summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriel Santiago <adriel@gitlab.com>2019-01-23 19:06:02 -0500
committerAdriel Santiago <adriel@gitlab.com>2019-02-05 08:15:57 -0500
commitb3bd24053e502da61557e2100fb19ae20e0b6dec (patch)
tree6c6c48c0d2983f287e3d0093e40649264f4e31d0
parentfb296ab57128f2da25e69cd8453fed86bf44748d (diff)
downloadgitlab-ce-b3bd24053e502da61557e2100fb19ae20e0b6dec.tar.gz
Use svg icon for deployment series
Use the rocket GitLab SVG to show deployment data
-rw-r--r--app/assets/javascripts/lib/utils/icon_utils.js18
-rw-r--r--app/assets/javascripts/monitoring/components/charts/area.vue14
-rw-r--r--spec/javascripts/lib/utils/icon_utils_spec.js67
3 files changed, 99 insertions, 0 deletions
diff --git a/app/assets/javascripts/lib/utils/icon_utils.js b/app/assets/javascripts/lib/utils/icon_utils.js
new file mode 100644
index 00000000000..7b8dd9bbef7
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/icon_utils.js
@@ -0,0 +1,18 @@
+/* eslint-disable import/prefer-default-export */
+
+import axios from '~/lib/utils/axios_utils';
+
+/**
+ * Retrieve SVG icon path content from gitlab/svg sprite icons
+ * @param {String} name
+ */
+export const getSvgIconPathContent = name =>
+ axios
+ .get(gon.sprite_icons)
+ .then(({ data: svgs }) =>
+ new DOMParser()
+ .parseFromString(svgs, 'text/xml')
+ .querySelector(`#${name} path`)
+ .getAttribute('d'),
+ )
+ .catch(() => null);
diff --git a/app/assets/javascripts/monitoring/components/charts/area.vue b/app/assets/javascripts/monitoring/components/charts/area.vue
index 47018803043..a0d6b91ff02 100644
--- a/app/assets/javascripts/monitoring/components/charts/area.vue
+++ b/app/assets/javascripts/monitoring/components/charts/area.vue
@@ -2,6 +2,7 @@
import { GlAreaChart } from '@gitlab/ui/dist/charts';
import dateFormat from 'dateformat';
import { debounceByAnimationFrame } from '~/lib/utils/common_utils';
+import { getSvgIconPathContent } from '~/lib/utils/icon_utils';
let debouncedResize;
@@ -48,6 +49,7 @@ export default {
return {
width: 0,
height: 0,
+ scatterSymbol: undefined,
};
},
computed: {
@@ -121,6 +123,8 @@ export default {
return {
type: 'scatter',
data: this.recentDeployments.map(deployment => [deployment.createdAt, 0]),
+ symbol: this.scatterSymbol,
+ symbolSize: 14,
};
},
xAxisLabel() {
@@ -140,12 +144,22 @@ export default {
created() {
debouncedResize = debounceByAnimationFrame(this.onResize);
window.addEventListener('resize', debouncedResize);
+ this.getScatterSymbol();
},
methods: {
formatTooltipText(params) {
const [date, value] = params;
return [dateFormat(date, 'dd mmm yyyy, h:MMtt'), value.toFixed(3)];
},
+ getScatterSymbol() {
+ getSvgIconPathContent('rocket')
+ .then(path => {
+ if (path) {
+ this.scatterSymbol = `path://${path}`;
+ }
+ })
+ .catch(() => {});
+ },
onResize() {
const { width, height } = this.$refs.areaChart.$el.getBoundingClientRect();
this.width = width;
diff --git a/spec/javascripts/lib/utils/icon_utils_spec.js b/spec/javascripts/lib/utils/icon_utils_spec.js
new file mode 100644
index 00000000000..3fd3940efe8
--- /dev/null
+++ b/spec/javascripts/lib/utils/icon_utils_spec.js
@@ -0,0 +1,67 @@
+import MockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
+import * as iconUtils from '~/lib/utils/icon_utils';
+
+describe('Icon utils', () => {
+ describe('getSvgIconPathContent', () => {
+ let spriteIcons;
+
+ beforeAll(() => {
+ spriteIcons = gon.sprite_icons;
+ gon.sprite_icons = 'mockSpriteIconsEndpoint';
+ });
+
+ afterAll(() => {
+ gon.sprite_icons = spriteIcons;
+ });
+
+ let axiosMock;
+ let mockEndpoint;
+ let getIcon;
+ const mockName = 'mockIconName';
+ const mockPath = 'mockPath';
+
+ beforeEach(() => {
+ axiosMock = new MockAdapter(axios);
+ mockEndpoint = axiosMock.onGet(gon.sprite_icons);
+ getIcon = iconUtils.getSvgIconPathContent(mockName);
+ });
+
+ afterEach(() => {
+ axiosMock.restore();
+ });
+
+ it('extracts svg icon path content from sprite icons', done => {
+ mockEndpoint.replyOnce(
+ 200,
+ `<svg><symbol id="${mockName}"><path d="${mockPath}"/></symbol></svg>`,
+ );
+ getIcon
+ .then(path => {
+ expect(path).toBe(mockPath);
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('returns null if icon path content does not exist', done => {
+ mockEndpoint.replyOnce(200, ``);
+ getIcon
+ .then(path => {
+ expect(path).toBe(null);
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('returns null if an http error occurs', done => {
+ mockEndpoint.replyOnce(500);
+ getIcon
+ .then(path => {
+ expect(path).toBe(null);
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+});