Commit 3528c71b authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch '36955-snowplow-custom-events-for-monitor-apm-alerts' into 'master'

Custom snowplow events for alerts

Closes #36955

See merge request gitlab-org/gitlab!21963
parents 71ccf41f 6f6e8d43
---
title: Custom snowplow events for monitoring alerts
merge_request: 21963
author:
type: added
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
import _ from 'underscore'; import _ from 'underscore';
import Vue from 'vue'; import Vue from 'vue';
import { import {
GlLink,
GlButton, GlButton,
GlButtonGroup, GlButtonGroup,
GlFormGroup, GlFormGroup,
...@@ -13,8 +14,9 @@ import { ...@@ -13,8 +14,9 @@ import {
} from '@gitlab/ui'; } from '@gitlab/ui';
import { __, s__ } from '~/locale'; import { __, s__ } from '~/locale';
import Translate from '~/vue_shared/translate'; import Translate from '~/vue_shared/translate';
import { alertsValidator, queriesValidator } from '../validators'; import TrackEventDirective from '~/vue_shared/directives/track_event';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import { alertsValidator, queriesValidator } from '../validators';
Vue.use(Translate); Vue.use(Translate);
...@@ -45,10 +47,12 @@ export default { ...@@ -45,10 +47,12 @@ export default {
GlDropdown, GlDropdown,
GlDropdownItem, GlDropdownItem,
GlModal, GlModal,
GlLink,
Icon, Icon,
}, },
directives: { directives: {
GlTooltipDirective, GlTooltip: GlTooltipDirective,
TrackEvent: TrackEventDirective,
}, },
props: { props: {
disabled: { disabled: {
...@@ -177,6 +181,14 @@ export default { ...@@ -177,6 +181,14 @@ export default {
this.prometheusMetricId = null; this.prometheusMetricId = null;
this.selectedAlert = {}; this.selectedAlert = {};
}, },
getAlertFormActionTrackingOption() {
const label = `${this.submitAction}_alert`;
return {
category: document.body.dataset.page,
action: 'click_button',
label,
};
},
}, },
alertQueryText: { alertQueryText: {
label: __('Query'), label: __('Query'),
...@@ -195,7 +207,6 @@ export default { ...@@ -195,7 +207,6 @@ export default {
:title="dropdownTitle" :title="dropdownTitle"
:modal-id="modalId" :modal-id="modalId"
:ok-variant="submitAction === 'delete' ? 'danger' : 'success'" :ok-variant="submitAction === 'delete' ? 'danger' : 'success'"
:ok-title="submitActionText"
:ok-disabled="formDisabled" :ok-disabled="formDisabled"
@ok="handleSubmit" @ok="handleSubmit"
@hidden="handleHidden" @hidden="handleHidden"
...@@ -215,7 +226,7 @@ export default { ...@@ -215,7 +226,7 @@ export default {
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
{{ __('Single or combined queries') }} {{ __('Single or combined queries') }}
<icon <icon
v-gl-tooltip-directive="$options.alertQueryText.descriptionTooltip" v-gl-tooltip="$options.alertQueryText.descriptionTooltip"
name="question" name="question"
class="prepend-left-4" class="prepend-left-4"
/> />
...@@ -272,5 +283,13 @@ export default { ...@@ -272,5 +283,13 @@ export default {
/> />
</gl-form-group> </gl-form-group>
</div> </div>
<template #modal-ok>
<gl-link
v-track-event="getAlertFormActionTrackingOption()"
class="text-reset text-decoration-none"
>
{{ submitActionText }}
</gl-link>
</template>
</gl-modal> </gl-modal>
</template> </template>
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlLink } from '@gitlab/ui';
import AlertWidgetForm from 'ee/monitoring/components/alert_widget_form.vue'; import AlertWidgetForm from 'ee/monitoring/components/alert_widget_form.vue';
import { GlModal } from '@gitlab/ui'; import ModalStub from '../stubs/modal_stub';
describe('AlertWidgetForm', () => { describe('AlertWidgetForm', () => {
let wrapper; let wrapper;
...@@ -8,6 +9,11 @@ describe('AlertWidgetForm', () => { ...@@ -8,6 +9,11 @@ describe('AlertWidgetForm', () => {
const metricId = '8'; const metricId = '8';
const alertPath = 'alert'; const alertPath = 'alert';
const relevantQueries = [{ metricId, alert_path: alertPath, label: 'alert-label' }]; const relevantQueries = [{ metricId, alert_path: alertPath, label: 'alert-label' }];
const dataTrackingOptions = {
create: { action: 'click_button', label: 'create_alert' },
delete: { action: 'click_button', label: 'delete_alert' },
update: { action: 'click_button', label: 'update_alert' },
};
const defaultProps = { const defaultProps = {
disabled: false, disabled: false,
...@@ -30,12 +36,17 @@ describe('AlertWidgetForm', () => { ...@@ -30,12 +36,17 @@ describe('AlertWidgetForm', () => {
wrapper = shallowMount(AlertWidgetForm, { wrapper = shallowMount(AlertWidgetForm, {
propsData, propsData,
stubs: {
GlModal: ModalStub,
},
}); });
} }
const modal = () => wrapper.find(GlModal); const modal = () => wrapper.find(ModalStub);
const modalTitle = () => modal().attributes('title'); const modalTitle = () => modal().attributes('title');
const submitText = () => modal().attributes('ok-title'); const submitButton = () => modal().find(GlLink);
const submitButtonTrackingOpts = () =>
JSON.parse(submitButton().attributes('data-tracking-options'));
const e = { const e = {
preventDefault: jest.fn(), preventDefault: jest.fn(),
}; };
...@@ -62,14 +73,20 @@ describe('AlertWidgetForm', () => { ...@@ -62,14 +73,20 @@ describe('AlertWidgetForm', () => {
it('shows correct title and button text', () => { it('shows correct title and button text', () => {
expect(modalTitle()).toBe('Add alert'); expect(modalTitle()).toBe('Add alert');
expect(submitText()).toBe('Add'); expect(submitButton().text()).toBe('Add');
});
it('sets tracking options for create alert', () => {
expect(submitButtonTrackingOpts()).toEqual(dataTrackingOptions.create);
}); });
it('emits a "create" event when form submitted without existing alert', () => { it('emits a "create" event when form submitted without existing alert', () => {
createComponent(); createComponent();
wrapper.vm.selectQuery('9'); wrapper.vm.selectQuery('9');
wrapper.vm.threshold = 900; wrapper.setData({
threshold: 900,
});
wrapper.vm.handleSubmit(e); wrapper.vm.handleSubmit(e);
...@@ -89,9 +106,11 @@ describe('AlertWidgetForm', () => { ...@@ -89,9 +106,11 @@ describe('AlertWidgetForm', () => {
wrapper.vm.selectQuery('9'); wrapper.vm.selectQuery('9');
wrapper.vm.selectQuery('>'); wrapper.vm.selectQuery('>');
wrapper.vm.threshold = 800; wrapper.setData({
threshold: 800,
});
wrapper.find(GlModal).vm.$emit('hidden'); modal().vm.$emit('hidden');
expect(wrapper.vm.selectedAlert).toEqual({}); expect(wrapper.vm.selectedAlert).toEqual({});
expect(wrapper.vm.operator).toBe(null); expect(wrapper.vm.operator).toBe(null);
...@@ -106,9 +125,13 @@ describe('AlertWidgetForm', () => { ...@@ -106,9 +125,13 @@ describe('AlertWidgetForm', () => {
wrapper.vm.selectQuery(metricId); wrapper.vm.selectQuery(metricId);
}); });
it('sets tracking options for delete alert', () => {
expect(submitButtonTrackingOpts()).toEqual(dataTrackingOptions.delete);
});
it('updates button text', () => { it('updates button text', () => {
expect(modalTitle()).toBe('Edit alert'); expect(modalTitle()).toBe('Edit alert');
expect(submitText()).toBe('Delete'); expect(submitButton().text()).toBe('Delete');
}); });
it('emits "delete" event when form values unchanged', () => { it('emits "delete" event when form values unchanged', () => {
...@@ -126,7 +149,9 @@ describe('AlertWidgetForm', () => { ...@@ -126,7 +149,9 @@ describe('AlertWidgetForm', () => {
}); });
it('emits "update" event when form changed', () => { it('emits "update" event when form changed', () => {
wrapper.vm.threshold = 11; wrapper.setData({
threshold: 11,
});
wrapper.vm.handleSubmit(e); wrapper.vm.handleSubmit(e);
...@@ -140,5 +165,15 @@ describe('AlertWidgetForm', () => { ...@@ -140,5 +165,15 @@ describe('AlertWidgetForm', () => {
]); ]);
expect(e.preventDefault).toHaveBeenCalledTimes(1); expect(e.preventDefault).toHaveBeenCalledTimes(1);
}); });
it('sets tracking options for update alert', () => {
wrapper.setData({
threshold: 11,
});
return wrapper.vm.$nextTick(() => {
expect(submitButtonTrackingOpts()).toEqual(dataTrackingOptions.update);
});
});
}); });
}); });
const ModalStub = {
name: 'glmodal-stub',
template: `
<div>
<slot></slot>
<slot name="modal-ok"></slot>
</div>
`,
};
export default ModalStub;
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