diff options
author | Clement Ho <408677-ClemMakesApps@users.noreply.gitlab.com> | 2019-08-21 19:12:12 +0000 |
---|---|---|
committer | Clement Ho <408677-ClemMakesApps@users.noreply.gitlab.com> | 2019-08-21 19:12:12 +0000 |
commit | 2ef59c7e4bf133b6d92277b081fb1eb76bc3d0d9 (patch) | |
tree | d2e480830dca412fd91812aecf4e0a1072a01107 | |
parent | b0af3979a4656adb4a2a422969f3197b3c85eafa (diff) | |
parent | 293ef17e7352fa33ce70cae8233b5a415f326596 (diff) | |
download | gitlab-ce-2ef59c7e4bf133b6d92277b081fb1eb76bc3d0d9.tar.gz |
Merge branch '9703-track-clicks-on-the-issue-sidebars' into 'master'
Backport: Resolve "Track clicks on the issue sidebars"
See merge request gitlab-org/gitlab-ce!31435
12 files changed, 82 insertions, 8 deletions
diff --git a/app/assets/javascripts/event_tracking/issue_sidebar.js b/app/assets/javascripts/event_tracking/issue_sidebar.js new file mode 100644 index 00000000000..6909f82c66f --- /dev/null +++ b/app/assets/javascripts/event_tracking/issue_sidebar.js @@ -0,0 +1,2 @@ +export const initSidebarTracking = () => {}; +export const trackEvent = () => {}; diff --git a/app/assets/javascripts/issue_show/index.js b/app/assets/javascripts/issue_show/index.js index 529b6386221..5a9dd91817e 100644 --- a/app/assets/javascripts/issue_show/index.js +++ b/app/assets/javascripts/issue_show/index.js @@ -1,4 +1,5 @@ import Vue from 'vue'; +import { initSidebarTracking } from 'ee_else_ce/event_tracking/issue_sidebar'; import issuableApp from './components/app.vue'; import { parseIssuableData } from './utils/parse_data'; import '../vue_shared/vue_resource_interceptor'; @@ -9,6 +10,9 @@ export default function initIssueableApp() { components: { issuableApp, }, + mounted() { + initSidebarTracking(); + }, render(createElement) { return createElement('issuable-app', { props: parseIssuableData(), diff --git a/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue b/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue index fa6b6bfaef1..63b93a80ead 100644 --- a/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue +++ b/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue @@ -1,5 +1,6 @@ <script> import { n__ } from '~/locale'; +import { trackEvent } from 'ee_else_ce/event_tracking/issue_sidebar'; export default { name: 'AssigneeTitle', @@ -29,13 +30,23 @@ export default { return n__('Assignee', `%d Assignees`, assignees); }, }, + methods: { + trackEdit() { + trackEvent('click_edit_button', 'assignee'); + }, + }, }; </script> <template> <div class="title hide-collapsed"> {{ assigneeTitle }} <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') }} </a> <a diff --git a/app/assets/javascripts/sidebar/components/confidential/confidential_issue_sidebar.vue b/app/assets/javascripts/sidebar/components/confidential/confidential_issue_sidebar.vue index 597b723a9d9..1c75b6148e8 100644 --- a/app/assets/javascripts/sidebar/components/confidential/confidential_issue_sidebar.vue +++ b/app/assets/javascripts/sidebar/components/confidential/confidential_issue_sidebar.vue @@ -5,6 +5,7 @@ import tooltip from '~/vue_shared/directives/tooltip'; import Icon from '~/vue_shared/components/icon.vue'; import eventHub from '~/sidebar/event_hub'; import editForm from './edit_form.vue'; +import { trackEvent } from 'ee_else_ce/event_tracking/issue_sidebar'; export default { components: { @@ -51,6 +52,11 @@ export default { toggleForm() { this.edit = !this.edit; }, + onEditClick() { + this.toggleForm(); + + trackEvent('click_edit_button', 'confidentiality'); + }, updateConfidentialAttribute(confidential) { this.service .update('issue', { confidential }) @@ -82,7 +88,7 @@ export default { v-if="isEditable" class="float-right confidential-edit" href="#" - @click.prevent="toggleForm" + @click.prevent="onEditClick" > {{ __('Edit') }} </a> diff --git a/app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue b/app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue index c5cfa92f3c8..ec2a7b93a98 100644 --- a/app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue +++ b/app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue @@ -6,6 +6,7 @@ import issuableMixin from '~/vue_shared/mixins/issuable'; import Icon from '~/vue_shared/components/icon.vue'; import eventHub from '~/sidebar/event_hub'; import editForm from './edit_form.vue'; +import { trackEvent } from 'ee_else_ce/event_tracking/issue_sidebar'; export default { components: { @@ -65,7 +66,11 @@ export default { toggleForm() { this.mediator.store.isLockDialogOpen = !this.mediator.store.isLockDialogOpen; }, + onEditClick() { + this.toggleForm(); + trackEvent('click_edit_button', 'lock_issue'); + }, updateLockedAttribute(locked) { this.mediator.service .update(this.issuableType, { @@ -109,7 +114,7 @@ export default { v-if="isEditable" class="float-right lock-edit" type="button" - @click.prevent="toggleForm" + @click.prevent="onEditClick" > {{ __('Edit') }} </button> diff --git a/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue b/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue index 0d1faceef11..1f5f19d1931 100644 --- a/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue +++ b/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue @@ -4,6 +4,7 @@ import icon from '~/vue_shared/components/icon.vue'; import toggleButton from '~/vue_shared/components/toggle_button.vue'; import tooltip from '~/vue_shared/directives/tooltip'; import eventHub from '../../event_hub'; +import { trackEvent } from 'ee_else_ce/event_tracking/issue_sidebar'; const ICON_ON = 'notifications'; const ICON_OFF = 'notifications-off'; @@ -63,6 +64,8 @@ export default { // Component event emission. this.$emit('toggleSubscription', this.id); + + trackEvent('toggle_button', 'notifications', this.subscribed ? 0 : 1); }, onClickCollapsedIcon() { this.$emit('toggleSidebar'); diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index e2e007eee50..b88b25eb845 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -405,7 +405,11 @@ module IssuablesHelper placement: is_collapsed ? 'left' : nil, container: is_collapsed ? 'body' : nil, 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 diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index 825088a58e7..aea09bf8d4d 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -38,7 +38,7 @@ = _('Milestone') = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true') - 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 - 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' } @@ -66,7 +66,7 @@ = _('Due date') = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true') - 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 %span.value-content - if issuable_sidebar[:due_date] @@ -102,7 +102,7 @@ = _('Labels') = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true') - 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?) } - if selected_labels.any? - selected_labels.each do |label_hash| @@ -160,7 +160,7 @@ = custom_icon('icon_arrow_right') .dropdown.sidebar-move-issue-dropdown.hide-collapsed %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') .dropdown-menu.dropdown-menu-selectable.dropdown-extended-height = dropdown_title(_('Move issue')) diff --git a/spec/javascripts/sidebar/assignee_title_spec.js b/spec/javascripts/sidebar/assignee_title_spec.js index 509edba2036..7fff7c075d9 100644 --- a/spec/javascripts/sidebar/assignee_title_spec.js +++ b/spec/javascripts/sidebar/assignee_title_spec.js @@ -4,8 +4,10 @@ import AssigneeTitle from '~/sidebar/components/assignees/assignee_title.vue'; describe('AssigneeTitle component', () => { let component; let AssigneeTitleComponent; + let statsSpy; beforeEach(() => { + statsSpy = spyOnDependency(AssigneeTitle, 'trackEvent'); AssigneeTitleComponent = Vue.extend(AssigneeTitle); }); @@ -102,4 +104,16 @@ describe('AssigneeTitle component', () => { 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(); + }); }); diff --git a/spec/javascripts/sidebar/confidential_issue_sidebar_spec.js b/spec/javascripts/sidebar/confidential_issue_sidebar_spec.js index 486a7241e33..ea9e5677bc5 100644 --- a/spec/javascripts/sidebar/confidential_issue_sidebar_spec.js +++ b/spec/javascripts/sidebar/confidential_issue_sidebar_spec.js @@ -4,8 +4,10 @@ import confidentialIssueSidebar from '~/sidebar/components/confidential/confiden describe('Confidential Issue Sidebar Block', () => { let vm1; let vm2; + let statsSpy; beforeEach(() => { + statsSpy = spyOnDependency(confidentialIssueSidebar, 'trackEvent'); const Component = Vue.extend(confidentialIssueSidebar); const service = { update: () => Promise.resolve(true), @@ -67,4 +69,10 @@ describe('Confidential Issue Sidebar Block', () => { done(); }); }); + + it('calls trackEvent when "Edit" is clicked', () => { + vm1.$el.querySelector('.confidential-edit').click(); + + expect(statsSpy).toHaveBeenCalled(); + }); }); diff --git a/spec/javascripts/sidebar/lock/lock_issue_sidebar_spec.js b/spec/javascripts/sidebar/lock/lock_issue_sidebar_spec.js index ca882032bdf..2d930428230 100644 --- a/spec/javascripts/sidebar/lock/lock_issue_sidebar_spec.js +++ b/spec/javascripts/sidebar/lock/lock_issue_sidebar_spec.js @@ -4,8 +4,10 @@ import lockIssueSidebar from '~/sidebar/components/lock/lock_issue_sidebar.vue'; describe('LockIssueSidebar', () => { let vm1; let vm2; + let statsSpy; beforeEach(() => { + statsSpy = spyOnDependency(lockIssueSidebar, 'trackEvent'); const Component = Vue.extend(lockIssueSidebar); const mediator = { @@ -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 => { expect(vm1.isLockDialogOpen).toBe(false); diff --git a/spec/javascripts/sidebar/subscriptions_spec.js b/spec/javascripts/sidebar/subscriptions_spec.js index 32728e58b06..2efa13f3fe8 100644 --- a/spec/javascripts/sidebar/subscriptions_spec.js +++ b/spec/javascripts/sidebar/subscriptions_spec.js @@ -6,8 +6,10 @@ import mountComponent from 'spec/helpers/vue_mount_component_helper'; describe('Subscriptions', function() { let vm; let Subscriptions; + let statsSpy; beforeEach(() => { + statsSpy = spyOnDependency(subscriptions, 'trackEvent'); Subscriptions = Vue.extend(subscriptions); }); @@ -58,6 +60,13 @@ describe('Subscriptions', function() { 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', () => { vm = mountComponent(Subscriptions, { subscribed: true }); spyOn(vm, '$emit'); |