Commit 0ae4d32b authored by Donald Cook's avatar Donald Cook Committed by Clement Ho

Tracking for edit button in sidebar

Added snowplow event tracking to assignee edit
parent 4b7da284
export const initSidebarTracking = () => {};
export const trackEvent = () => {};
import Vue from 'vue'; import Vue from 'vue';
import { initSidebarTracking } from 'ee_else_ce/event_tracking/issue_sidebar';
import issuableApp from './components/app.vue'; import issuableApp from './components/app.vue';
import { parseIssuableData } from './utils/parse_data'; import { parseIssuableData } from './utils/parse_data';
import '../vue_shared/vue_resource_interceptor'; import '../vue_shared/vue_resource_interceptor';
...@@ -9,6 +10,9 @@ export default function initIssueableApp() { ...@@ -9,6 +10,9 @@ export default function initIssueableApp() {
components: { components: {
issuableApp, issuableApp,
}, },
mounted() {
initSidebarTracking();
},
render(createElement) { render(createElement) {
return createElement('issuable-app', { return createElement('issuable-app', {
props: parseIssuableData(), props: parseIssuableData(),
......
<script> <script>
import { n__ } from '~/locale'; import { n__ } from '~/locale';
import { trackEvent } from 'ee_else_ce/event_tracking/issue_sidebar';
export default { export default {
name: 'AssigneeTitle', name: 'AssigneeTitle',
...@@ -29,13 +30,23 @@ export default { ...@@ -29,13 +30,23 @@ export default {
return n__('Assignee', `%d Assignees`, assignees); return n__('Assignee', `%d Assignees`, assignees);
}, },
}, },
methods: {
trackEdit() {
trackEvent('click_edit_button', 'assignee');
},
},
}; };
</script> </script>
<template> <template>
<div class="title hide-collapsed"> <div class="title hide-collapsed">
{{ assigneeTitle }} {{ assigneeTitle }}
<i v-if="loading" aria-hidden="true" class="fa fa-spinner fa-spin block-loading"></i> <i v-if="loading" aria-hidden="true" class="fa fa-spinner fa-spin block-loading"></i>
<a v-if="editable" class="js-sidebar-dropdown-toggle edit-link float-right" href="#"> <a
v-if="editable"
class="js-sidebar-dropdown-toggle edit-link float-right"
href="#"
@click.prevent="trackEdit"
>
{{ __('Edit') }} {{ __('Edit') }}
</a> </a>
<a <a
......
...@@ -5,6 +5,7 @@ import tooltip from '~/vue_shared/directives/tooltip'; ...@@ -5,6 +5,7 @@ import tooltip from '~/vue_shared/directives/tooltip';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import eventHub from '~/sidebar/event_hub'; import eventHub from '~/sidebar/event_hub';
import editForm from './edit_form.vue'; import editForm from './edit_form.vue';
import { trackEvent } from 'ee_else_ce/event_tracking/issue_sidebar';
export default { export default {
components: { components: {
...@@ -51,6 +52,11 @@ export default { ...@@ -51,6 +52,11 @@ export default {
toggleForm() { toggleForm() {
this.edit = !this.edit; this.edit = !this.edit;
}, },
onEditClick() {
this.toggleForm();
trackEvent('click_edit_button', 'confidentiality');
},
updateConfidentialAttribute(confidential) { updateConfidentialAttribute(confidential) {
this.service this.service
.update('issue', { confidential }) .update('issue', { confidential })
...@@ -82,7 +88,7 @@ export default { ...@@ -82,7 +88,7 @@ export default {
v-if="isEditable" v-if="isEditable"
class="float-right confidential-edit" class="float-right confidential-edit"
href="#" href="#"
@click.prevent="toggleForm" @click.prevent="onEditClick"
> >
{{ __('Edit') }} {{ __('Edit') }}
</a> </a>
......
...@@ -6,6 +6,7 @@ import issuableMixin from '~/vue_shared/mixins/issuable'; ...@@ -6,6 +6,7 @@ import issuableMixin from '~/vue_shared/mixins/issuable';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import eventHub from '~/sidebar/event_hub'; import eventHub from '~/sidebar/event_hub';
import editForm from './edit_form.vue'; import editForm from './edit_form.vue';
import { trackEvent } from 'ee_else_ce/event_tracking/issue_sidebar';
export default { export default {
components: { components: {
...@@ -65,7 +66,11 @@ export default { ...@@ -65,7 +66,11 @@ export default {
toggleForm() { toggleForm() {
this.mediator.store.isLockDialogOpen = !this.mediator.store.isLockDialogOpen; this.mediator.store.isLockDialogOpen = !this.mediator.store.isLockDialogOpen;
}, },
onEditClick() {
this.toggleForm();
trackEvent('click_edit_button', 'lock_issue');
},
updateLockedAttribute(locked) { updateLockedAttribute(locked) {
this.mediator.service this.mediator.service
.update(this.issuableType, { .update(this.issuableType, {
...@@ -109,7 +114,7 @@ export default { ...@@ -109,7 +114,7 @@ export default {
v-if="isEditable" v-if="isEditable"
class="float-right lock-edit" class="float-right lock-edit"
type="button" type="button"
@click.prevent="toggleForm" @click.prevent="onEditClick"
> >
{{ __('Edit') }} {{ __('Edit') }}
</button> </button>
......
...@@ -4,6 +4,7 @@ import icon from '~/vue_shared/components/icon.vue'; ...@@ -4,6 +4,7 @@ import icon from '~/vue_shared/components/icon.vue';
import toggleButton from '~/vue_shared/components/toggle_button.vue'; import toggleButton from '~/vue_shared/components/toggle_button.vue';
import tooltip from '~/vue_shared/directives/tooltip'; import tooltip from '~/vue_shared/directives/tooltip';
import eventHub from '../../event_hub'; import eventHub from '../../event_hub';
import { trackEvent } from 'ee_else_ce/event_tracking/issue_sidebar';
const ICON_ON = 'notifications'; const ICON_ON = 'notifications';
const ICON_OFF = 'notifications-off'; const ICON_OFF = 'notifications-off';
...@@ -63,6 +64,8 @@ export default { ...@@ -63,6 +64,8 @@ export default {
// Component event emission. // Component event emission.
this.$emit('toggleSubscription', this.id); this.$emit('toggleSubscription', this.id);
trackEvent('toggle_button', 'notifications', this.subscribed ? 0 : 1);
}, },
onClickCollapsedIcon() { onClickCollapsedIcon() {
this.$emit('toggleSidebar'); this.$emit('toggleSidebar');
......
...@@ -405,7 +405,11 @@ module IssuablesHelper ...@@ -405,7 +405,11 @@ module IssuablesHelper
placement: is_collapsed ? 'left' : nil, placement: is_collapsed ? 'left' : nil,
container: is_collapsed ? 'body' : nil, container: is_collapsed ? 'body' : nil,
boundary: 'viewport', boundary: 'viewport',
is_collapsed: is_collapsed is_collapsed: is_collapsed,
track_label: "right_sidebar",
track_property: "update_todo",
track_event: "click_button",
track_value: ""
} }
end end
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
= _('Milestone') = _('Milestone')
= icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true') = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true')
- if can_edit_issuable - if can_edit_issuable
= link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right' = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right', data: { track_label: "right_sidebar", track_property: "milestone", track_event: "click_edit_button", track_value: "" }
.value.hide-collapsed .value.hide-collapsed
- if milestone.present? - if milestone.present?
= link_to milestone[:title], milestone[:web_url], class: "bold has-tooltip", title: sidebar_milestone_remaining_days(milestone), data: { container: "body", html: 'true', boundary: 'viewport' } = link_to milestone[:title], milestone[:web_url], class: "bold has-tooltip", title: sidebar_milestone_remaining_days(milestone), data: { container: "body", html: 'true', boundary: 'viewport' }
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
= _('Due date') = _('Due date')
= icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true') = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true')
- if can_edit_issuable - if can_edit_issuable
= link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right' = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right', data: { track_label: "right_sidebar", track_property: "due_date", track_event: "click_edit_button", track_value: "" }
.value.hide-collapsed .value.hide-collapsed
%span.value-content %span.value-content
- if issuable_sidebar[:due_date] - if issuable_sidebar[:due_date]
...@@ -102,7 +102,7 @@ ...@@ -102,7 +102,7 @@
= _('Labels') = _('Labels')
= icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true') = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true')
- if can_edit_issuable - if can_edit_issuable
= link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link qa-edit-link-labels float-right' = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link qa-edit-link-labels float-right', data: { track_label: "right_sidebar", track_property: "labels", track_event: "click_edit_button", track_value: "" }
.value.issuable-show-labels.dont-hide.hide-collapsed.qa-labels-block{ class: ("has-labels" if selected_labels.any?) } .value.issuable-show-labels.dont-hide.hide-collapsed.qa-labels-block{ class: ("has-labels" if selected_labels.any?) }
- if selected_labels.any? - if selected_labels.any?
- selected_labels.each do |label_hash| - selected_labels.each do |label_hash|
...@@ -160,7 +160,7 @@ ...@@ -160,7 +160,7 @@
= custom_icon('icon_arrow_right') = custom_icon('icon_arrow_right')
.dropdown.sidebar-move-issue-dropdown.hide-collapsed .dropdown.sidebar-move-issue-dropdown.hide-collapsed
%button.btn.btn-default.btn-block.js-sidebar-dropdown-toggle.js-move-issue{ type: 'button', %button.btn.btn-default.btn-block.js-sidebar-dropdown-toggle.js-move-issue{ type: 'button',
data: { toggle: 'dropdown', display: 'static' } } data: { toggle: 'dropdown', display: 'static', track_label: "right_sidebar", track_property: "move_issue", track_event: "click_button", track_value: "" } }
= _('Move issue') = _('Move issue')
.dropdown-menu.dropdown-menu-selectable.dropdown-extended-height .dropdown-menu.dropdown-menu-selectable.dropdown-extended-height
= dropdown_title(_('Move issue')) = dropdown_title(_('Move issue'))
......
import Tracking from '~/tracking';
export const initSidebarTracking = () => {
new Tracking().bind('.js-issuable-sidebar');
};
export const trackEvent = (eventType, property, value = '') => {
Tracking.event(document.body.dataset.page, eventType, {
label: 'right_sidebar',
property,
value,
});
};
...@@ -5,6 +5,7 @@ import eventHub from '~/sidebar/event_hub'; ...@@ -5,6 +5,7 @@ import eventHub from '~/sidebar/event_hub';
import tooltip from '~/vue_shared/directives/tooltip'; import tooltip from '~/vue_shared/directives/tooltip';
import icon from '~/vue_shared/components/icon.vue'; import icon from '~/vue_shared/components/icon.vue';
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } from '@gitlab/ui';
import { trackEvent } from 'ee/event_tracking/issue_sidebar';
export default { export default {
components: { components: {
...@@ -101,6 +102,11 @@ export default { ...@@ -101,6 +102,11 @@ export default {
checkIfNoValue(weight) { checkIfNoValue(weight) {
return weight === undefined || weight === null || weight === this.weightNoneValue; return weight === undefined || weight === null || weight === this.weightNoneValue;
}, },
onEditClick(shouldShowEditField = true) {
this.showEditField(shouldShowEditField);
trackEvent('click_edit_button', 'weight');
},
showEditField(bool = true) { showEditField(bool = true) {
this.shouldShowEditField = bool; this.shouldShowEditField = bool;
...@@ -160,7 +166,7 @@ export default { ...@@ -160,7 +166,7 @@ export default {
v-if="editable" v-if="editable"
class="float-right js-weight-edit-link" class="float-right js-weight-edit-link"
href="#" href="#"
@click="showEditField(!shouldShowEditField)" @click="onEditClick(!shouldShowEditField)"
> >
{{ __('Edit') }} {{ __('Edit') }}
</a> </a>
......
...@@ -11,8 +11,10 @@ const DEFAULT_PROPS = { ...@@ -11,8 +11,10 @@ const DEFAULT_PROPS = {
describe('Weight', function() { describe('Weight', function() {
let vm; let vm;
let Weight; let Weight;
let statsSpy;
beforeEach(() => { beforeEach(() => {
statsSpy = spyOnDependency(weight, 'trackEvent');
Weight = Vue.extend(weight); Weight = Vue.extend(weight);
}); });
...@@ -109,6 +111,22 @@ describe('Weight', function() { ...@@ -109,6 +111,22 @@ describe('Weight', function() {
.catch(done.fail); .catch(done.fail);
}); });
it('calls trackEvent when "Edit" is clicked', done => {
vm = mountComponent(Weight, {
...DEFAULT_PROPS,
editable: true,
});
vm.$el.querySelector('.js-weight-edit-link').click();
vm.$nextTick()
.then(() => {
expect(statsSpy).toHaveBeenCalled();
})
.then(done)
.catch(done.fail);
});
it('emits event on input submission', done => { it('emits event on input submission', done => {
const ID = 123; const ID = 123;
const expectedWeightValue = '3'; const expectedWeightValue = '3';
......
...@@ -4,8 +4,10 @@ import AssigneeTitle from '~/sidebar/components/assignees/assignee_title.vue'; ...@@ -4,8 +4,10 @@ import AssigneeTitle from '~/sidebar/components/assignees/assignee_title.vue';
describe('AssigneeTitle component', () => { describe('AssigneeTitle component', () => {
let component; let component;
let AssigneeTitleComponent; let AssigneeTitleComponent;
let statsSpy;
beforeEach(() => { beforeEach(() => {
statsSpy = spyOnDependency(AssigneeTitle, 'trackEvent');
AssigneeTitleComponent = Vue.extend(AssigneeTitle); AssigneeTitleComponent = Vue.extend(AssigneeTitle);
}); });
...@@ -102,4 +104,16 @@ describe('AssigneeTitle component', () => { ...@@ -102,4 +104,16 @@ describe('AssigneeTitle component', () => {
expect(component.$el.querySelector('.edit-link')).not.toBeNull(); expect(component.$el.querySelector('.edit-link')).not.toBeNull();
}); });
it('calls trackEvent when edit is clicked', () => {
component = new AssigneeTitleComponent({
propsData: {
numberOfAssignees: 0,
editable: true,
},
}).$mount();
component.$el.querySelector('.js-sidebar-dropdown-toggle').click();
expect(statsSpy).toHaveBeenCalled();
});
}); });
...@@ -4,8 +4,10 @@ import confidentialIssueSidebar from '~/sidebar/components/confidential/confiden ...@@ -4,8 +4,10 @@ import confidentialIssueSidebar from '~/sidebar/components/confidential/confiden
describe('Confidential Issue Sidebar Block', () => { describe('Confidential Issue Sidebar Block', () => {
let vm1; let vm1;
let vm2; let vm2;
let statsSpy;
beforeEach(() => { beforeEach(() => {
statsSpy = spyOnDependency(confidentialIssueSidebar, 'trackEvent');
const Component = Vue.extend(confidentialIssueSidebar); const Component = Vue.extend(confidentialIssueSidebar);
const service = { const service = {
update: () => Promise.resolve(true), update: () => Promise.resolve(true),
...@@ -67,4 +69,10 @@ describe('Confidential Issue Sidebar Block', () => { ...@@ -67,4 +69,10 @@ describe('Confidential Issue Sidebar Block', () => {
done(); done();
}); });
}); });
it('calls trackEvent when "Edit" is clicked', () => {
vm1.$el.querySelector('.confidential-edit').click();
expect(statsSpy).toHaveBeenCalled();
});
}); });
...@@ -4,8 +4,10 @@ import lockIssueSidebar from '~/sidebar/components/lock/lock_issue_sidebar.vue'; ...@@ -4,8 +4,10 @@ import lockIssueSidebar from '~/sidebar/components/lock/lock_issue_sidebar.vue';
describe('LockIssueSidebar', () => { describe('LockIssueSidebar', () => {
let vm1; let vm1;
let vm2; let vm2;
let statsSpy;
beforeEach(() => { beforeEach(() => {
statsSpy = spyOnDependency(lockIssueSidebar, 'trackEvent');
const Component = Vue.extend(lockIssueSidebar); const Component = Vue.extend(lockIssueSidebar);
const mediator = { const mediator = {
...@@ -59,6 +61,12 @@ describe('LockIssueSidebar', () => { ...@@ -59,6 +61,12 @@ describe('LockIssueSidebar', () => {
}); });
}); });
it('calls trackEvent when "Edit" is clicked', () => {
vm1.$el.querySelector('.lock-edit').click();
expect(statsSpy).toHaveBeenCalled();
});
it('displays the edit form when opened from collapsed state', done => { it('displays the edit form when opened from collapsed state', done => {
expect(vm1.isLockDialogOpen).toBe(false); expect(vm1.isLockDialogOpen).toBe(false);
......
...@@ -6,8 +6,10 @@ import mountComponent from 'spec/helpers/vue_mount_component_helper'; ...@@ -6,8 +6,10 @@ import mountComponent from 'spec/helpers/vue_mount_component_helper';
describe('Subscriptions', function() { describe('Subscriptions', function() {
let vm; let vm;
let Subscriptions; let Subscriptions;
let statsSpy;
beforeEach(() => { beforeEach(() => {
statsSpy = spyOnDependency(subscriptions, 'trackEvent');
Subscriptions = Vue.extend(subscriptions); Subscriptions = Vue.extend(subscriptions);
}); });
...@@ -58,6 +60,13 @@ describe('Subscriptions', function() { ...@@ -58,6 +60,13 @@ describe('Subscriptions', function() {
expect(vm.$emit).toHaveBeenCalledWith('toggleSubscription', jasmine.any(Object)); expect(vm.$emit).toHaveBeenCalledWith('toggleSubscription', jasmine.any(Object));
}); });
it('calls trackEvent when toggled', () => {
vm = mountComponent(Subscriptions, { subscribed: true });
vm.toggleSubscription();
expect(statsSpy).toHaveBeenCalled();
});
it('onClickCollapsedIcon method emits `toggleSidebar` event on component', () => { it('onClickCollapsedIcon method emits `toggleSidebar` event on component', () => {
vm = mountComponent(Subscriptions, { subscribed: true }); vm = mountComponent(Subscriptions, { subscribed: true });
spyOn(vm, '$emit'); spyOn(vm, '$emit');
......
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