Commit 4cf42c26 authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch '334808-add-work-item-title-update-tracking' into 'master'

Add snowplow tracking to Work Item Title updates

See merge request gitlab-org/gitlab!78179
parents 4844ca81 8ae71e79
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
import { escape } from 'lodash'; import { escape } from 'lodash';
import { __ } from '~/locale'; import { __ } from '~/locale';
import { WI_TITLE_TRACK_LABEL } from '../constants';
export default { export default {
WI_TITLE_TRACK_LABEL,
props: { props: {
initialTitle: { initialTitle: {
type: String, type: String,
...@@ -56,6 +59,7 @@ export default { ...@@ -56,6 +59,7 @@ export default {
role="textbox" role="textbox"
:aria-label="__('Title')" :aria-label="__('Title')"
:data-placeholder="placeholder" :data-placeholder="placeholder"
:data-track-label="$options.WI_TITLE_TRACK_LABEL"
:contenteditable="!disabled" :contenteditable="!disabled"
class="gl-pseudo-placeholder" class="gl-pseudo-placeholder"
@blur="handleBlur" @blur="handleBlur"
......
export const widgetTypes = { export const widgetTypes = {
title: 'TITLE', title: 'TITLE',
}; };
export const WI_TITLE_TRACK_LABEL = 'item_title';
<script> <script>
import { GlAlert } from '@gitlab/ui'; import { GlAlert } from '@gitlab/ui';
import Tracking from '~/tracking';
import workItemQuery from '../graphql/work_item.query.graphql'; import workItemQuery from '../graphql/work_item.query.graphql';
import updateWorkItemMutation from '../graphql/update_work_item.mutation.graphql'; import updateWorkItemMutation from '../graphql/update_work_item.mutation.graphql';
import { widgetTypes } from '../constants'; import { widgetTypes, WI_TITLE_TRACK_LABEL } from '../constants';
import ItemTitle from '../components/item_title.vue'; import ItemTitle from '../components/item_title.vue';
const trackingMixin = Tracking.mixin();
export default { export default {
titleUpdatedEvent: 'updated_title',
components: { components: {
ItemTitle, ItemTitle,
GlAlert, GlAlert,
}, },
mixins: [trackingMixin],
props: { props: {
id: { id: {
type: String, type: String,
...@@ -34,6 +39,14 @@ export default { ...@@ -34,6 +39,14 @@ export default {
}, },
}, },
computed: { computed: {
tracking() {
return {
category: 'workItems:show',
action: 'updated_title',
label: WI_TITLE_TRACK_LABEL,
property: '[type_work_item]',
};
},
titleWidgetData() { titleWidgetData() {
return this.workItem?.widgets?.nodes?.find((widget) => widget.type === widgetTypes.title); return this.workItem?.widgets?.nodes?.find((widget) => widget.type === widgetTypes.title);
}, },
...@@ -50,6 +63,7 @@ export default { ...@@ -50,6 +63,7 @@ export default {
}, },
}, },
}); });
this.track();
} catch { } catch {
this.error = true; this.error = true;
} }
......
...@@ -3,6 +3,7 @@ import { shallowMount } from '@vue/test-utils'; ...@@ -3,6 +3,7 @@ import { shallowMount } from '@vue/test-utils';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper'; import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import workItemQuery from '~/work_items/graphql/work_item.query.graphql'; import workItemQuery from '~/work_items/graphql/work_item.query.graphql';
import updateWorkItemMutation from '~/work_items/graphql/update_work_item.mutation.graphql'; import updateWorkItemMutation from '~/work_items/graphql/update_work_item.mutation.graphql';
import WorkItemsRoot from '~/work_items/pages/work_item_root.vue'; import WorkItemsRoot from '~/work_items/pages/work_item_root.vue';
...@@ -15,6 +16,7 @@ Vue.use(VueApollo); ...@@ -15,6 +16,7 @@ Vue.use(VueApollo);
const WORK_ITEM_ID = '1'; const WORK_ITEM_ID = '1';
describe('Work items root component', () => { describe('Work items root component', () => {
const mockUpdatedTitle = 'Updated title';
let wrapper; let wrapper;
let fakeApollo; let fakeApollo;
...@@ -53,7 +55,6 @@ describe('Work items root component', () => { ...@@ -53,7 +55,6 @@ describe('Work items root component', () => {
it('updates the title when it is edited', async () => { it('updates the title when it is edited', async () => {
createComponent(); createComponent();
jest.spyOn(wrapper.vm.$apollo, 'mutate'); jest.spyOn(wrapper.vm.$apollo, 'mutate');
const mockUpdatedTitle = 'Updated title';
await findTitle().vm.$emit('title-changed', mockUpdatedTitle); await findTitle().vm.$emit('title-changed', mockUpdatedTitle);
...@@ -91,4 +92,32 @@ describe('Work items root component', () => { ...@@ -91,4 +92,32 @@ describe('Work items root component', () => {
expect(findTitle().exists()).toBe(false); expect(findTitle().exists()).toBe(false);
}); });
describe('tracking', () => {
let trackingSpy;
beforeEach(() => {
trackingSpy = mockTracking('_category_', undefined, jest.spyOn);
createComponent();
});
afterEach(() => {
unmockTracking();
});
it('tracks item title updates', async () => {
await findTitle().vm.$emit('title-changed', mockUpdatedTitle);
await waitForPromises();
expect(trackingSpy).toHaveBeenCalledTimes(1);
expect(trackingSpy).toHaveBeenCalledWith('workItems:show', undefined, {
action: 'updated_title',
category: 'workItems:show',
label: 'item_title',
property: '[type_work_item]',
});
});
});
}); });
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