Commit 08b64655 authored by Dhiraj Bodicherla's avatar Dhiraj Bodicherla Committed by Miguel Rincon

Track add metric action in dashboard

New metrics can be added via the monitoring
dashboard. This MR tracks such user actions
parent 5e913ddd
...@@ -22,7 +22,8 @@ import MonitorTimeSeriesChart from './charts/time_series.vue'; ...@@ -22,7 +22,8 @@ import MonitorTimeSeriesChart from './charts/time_series.vue';
import MonitorSingleStatChart from './charts/single_stat.vue'; import MonitorSingleStatChart from './charts/single_stat.vue';
import GraphGroup from './graph_group.vue'; import GraphGroup from './graph_group.vue';
import EmptyState from './empty_state.vue'; import EmptyState from './empty_state.vue';
import { getTimeDiff, isValidDate } from '../utils'; import TrackEventDirective from '~/vue_shared/directives/track_event';
import { getTimeDiff, isValidDate, getAddMetricTrackingOptions } from '../utils';
export default { export default {
components: { components: {
...@@ -43,6 +44,7 @@ export default { ...@@ -43,6 +44,7 @@ export default {
directives: { directives: {
GlModal: GlModalDirective, GlModal: GlModalDirective,
GlTooltip: GlTooltipDirective, GlTooltip: GlTooltipDirective,
TrackEvent: TrackEventDirective,
}, },
props: { props: {
externalDashboardUrl: { externalDashboardUrl: {
...@@ -298,6 +300,7 @@ export default { ...@@ -298,6 +300,7 @@ export default {
onDateTimePickerApply(timeWindowUrlParams) { onDateTimePickerApply(timeWindowUrlParams) {
return redirectTo(mergeUrlParams(timeWindowUrlParams, window.location.href)); return redirectTo(mergeUrlParams(timeWindowUrlParams, window.location.href));
}, },
getAddMetricTrackingOptions,
}, },
addMetric: { addMetric: {
title: s__('Metrics|Add metric'), title: s__('Metrics|Add metric'),
...@@ -411,7 +414,9 @@ export default { ...@@ -411,7 +414,9 @@ export default {
<div slot="modal-footer"> <div slot="modal-footer">
<gl-button @click="hideAddMetricModal">{{ __('Cancel') }}</gl-button> <gl-button @click="hideAddMetricModal">{{ __('Cancel') }}</gl-button>
<gl-button <gl-button
v-track-event="getAddMetricTrackingOptions()"
:disabled="!formIsValid" :disabled="!formIsValid"
class="js-submit-custom-metrics-form"
variant="success" variant="success"
@click="submitCustomMetricsForm" @click="submitCustomMetricsForm"
> >
......
...@@ -115,6 +115,7 @@ export const generateLinkToChartOptions = chartLink => { ...@@ -115,6 +115,7 @@ export const generateLinkToChartOptions = chartLink => {
/** /**
* Tracks snowplow event when user downloads CSV of cluster metric * Tracks snowplow event when user downloads CSV of cluster metric
* @param {String} chart title that will be sent as a property for the event * @param {String} chart title that will be sent as a property for the event
* @return {Object} config object for event tracking
*/ */
export const downloadCSVOptions = title => { export const downloadCSVOptions = title => {
const isCLusterHealthBoard = isClusterHealthBoard(); const isCLusterHealthBoard = isClusterHealthBoard();
...@@ -129,6 +130,18 @@ export const downloadCSVOptions = title => { ...@@ -129,6 +130,18 @@ export const downloadCSVOptions = title => {
return { category, action, label: 'Chart title', property: title }; return { category, action, label: 'Chart title', property: title };
}; };
/**
* Generate options for snowplow to track adding a new metric via the dashboard
* custom metric modal
* @return {Object} config object for event tracking
*/
export const getAddMetricTrackingOptions = () => ({
category: document.body.dataset.page,
action: 'click_button',
label: 'add_new_metric',
property: 'modal',
});
/** /**
* This function validates the graph data contains exactly 3 metrics plus * This function validates the graph data contains exactly 3 metrics plus
* value validations from graphDataValidatorForValues. * value validations from graphDataValidatorForValues.
......
---
title: Track adding metric via monitoring dashboard
merge_request: 20818
author:
type: added
import { shallowMount, createLocalVue } from '@vue/test-utils'; import { shallowMount, createLocalVue } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import { GlModal } from '@gitlab/ui'; import { GlModal, GlButton } from '@gitlab/ui';
import Tracking from '~/tracking';
import Dashboard from 'ee/monitoring/components/dashboard.vue'; import Dashboard from 'ee/monitoring/components/dashboard.vue';
import { createStore } from '~/monitoring/stores'; import { createStore } from '~/monitoring/stores';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
...@@ -20,14 +21,19 @@ describe('Dashboard', () => { ...@@ -20,14 +21,19 @@ describe('Dashboard', () => {
let Component; let Component;
let mock; let mock;
let store; let store;
let vm; let wrapper;
const findAddMetricButton = () => wrapper.find('.js-add-metric-button');
const createComponent = (props = {}) => { const createComponent = (props = {}) => {
vm = shallowMount(localVue.extend(Component), { wrapper = shallowMount(localVue.extend(Component), {
propsData: { propsData: {
...propsData, ...propsData,
...props, ...props,
}, },
stubs: {
GlButton,
},
store, store,
sync: false, sync: false,
localVue, localVue,
...@@ -83,12 +89,16 @@ describe('Dashboard', () => { ...@@ -83,12 +89,16 @@ describe('Dashboard', () => {
}); });
it('does not render add button on the dashboard', () => { it('does not render add button on the dashboard', () => {
expect(vm.element.querySelector('.js-add-metric-button')).toBe(null); expect(findAddMetricButton().exists()).toBe(false);
}); });
}); });
describe('when available', () => { describe('when available', () => {
let origPage;
beforeEach(done => { beforeEach(done => {
spyOn(Tracking, 'event');
createComponent({ createComponent({
customMetricsAvailable: true, customMetricsAvailable: true,
customMetricsPath: '/endpoint', customMetricsPath: '/endpoint',
...@@ -97,22 +107,49 @@ describe('Dashboard', () => { ...@@ -97,22 +107,49 @@ describe('Dashboard', () => {
alertsEndpoint: '/endpoint', alertsEndpoint: '/endpoint',
}); });
setupComponentStore(vm); setupComponentStore(wrapper);
origPage = document.body.dataset.page;
document.body.dataset.page = 'projects:environments:metrics';
vm.vm.$nextTick(done); wrapper.vm.$nextTick(done);
});
afterEach(() => {
document.body.dataset.page = origPage;
}); });
it('renders add button on the dashboard', () => { it('renders add button on the dashboard', () => {
expect(vm.element.querySelector('.js-add-metric-button').innerText).toContain('Add metric'); expect(findAddMetricButton().exists()).toBe(true);
}); });
it('uses modal for custom metrics form', () => { it('uses modal for custom metrics form', () => {
expect(vm.find(GlModal).exists()).toBe(true); expect(wrapper.find(GlModal).exists()).toBe(true);
expect(vm.find(GlModal).attributes().modalid).toBe('add-metric'); expect(wrapper.find(GlModal).attributes().modalid).toBe('add-metric');
});
it('adding new metric is tracked', done => {
const submitButton = wrapper.find('.js-submit-custom-metrics-form');
wrapper.setData({ formIsValid: true });
wrapper.vm.$nextTick(() => {
submitButton.trigger('click');
wrapper.vm.$nextTick(() => {
expect(Tracking.event).toHaveBeenCalledWith(
document.body.dataset.page,
'click_button',
{
label: 'add_new_metric',
property: 'modal',
value: undefined,
},
);
done();
});
});
}); });
it('renders custom metrics form fields', () => { it('renders custom metrics form fields', () => {
expect(vm.find(CustomMetricsFormFields).exists()).toBe(true); expect(wrapper.find(CustomMetricsFormFields).exists()).toBe(true);
}); });
}); });
}); });
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment