Commit ddbc9f56 authored by Nicolas Dular's avatar Nicolas Dular

Remove the learn-gitlab popover

When the onboarding_issues experiment is active, we showed a popover on
the learn-gitlab project. However, since we now directly link to the
issue board of the project, this popover is no longer necessary.
parent 4d377b4a
<script> <script>
/* eslint-disable vue/no-v-html */ /* eslint-disable vue/no-v-html */
import { GlLoadingIcon, GlBadge, GlTooltipDirective } from '@gitlab/ui'; import { GlLoadingIcon, GlBadge, GlTooltipDirective } from '@gitlab/ui';
import { showLearnGitLabGroupItemPopover } from '~/onboarding_issues';
import { visitUrl } from '../../lib/utils/url_utility'; import { visitUrl } from '../../lib/utils/url_utility';
import identicon from '../../vue_shared/components/identicon.vue'; import identicon from '../../vue_shared/components/identicon.vue';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
...@@ -77,11 +76,6 @@ export default { ...@@ -77,11 +76,6 @@ export default {
return this.group.microdata || {}; return this.group.microdata || {};
}, },
}, },
mounted() {
if (this.group.name === 'Learn GitLab') {
showLearnGitLabGroupItemPopover(this.group.id);
}
},
methods: { methods: {
onClickRowGroup(e) { onClickRowGroup(e) {
const NO_EXPAND_CLS = 'no-expand'; const NO_EXPAND_CLS = 'no-expand';
......
import $ from 'jquery';
import { parseBoolean, getCookie, setCookie, removeCookie } from '~/lib/utils/common_utils';
import { __, sprintf } from '~/locale';
import Tracking from '~/tracking';
const COOKIE_NAME = 'onboarding_issues_settings';
const POPOVER_LOCATIONS = {
GROUPS_SHOW: 'groups#show',
PROJECTS_SHOW: 'projects#show',
ISSUES_INDEX: 'issues#index',
};
const removeLearnGitLabCookie = () => {
removeCookie(COOKIE_NAME);
};
function disposePopover(event) {
event.preventDefault();
this.popover('dispose');
removeLearnGitLabCookie();
Tracking.event('Growth::Conversion::Experiment::OnboardingIssues', 'dismiss_popover');
}
const showPopover = (el, path, footer, options) => {
// Cookie value looks like `{ 'groups#show': true, 'projects#show': true, 'issues#index': true }`. When it doesn't exist, don't show the popover.
const cookie = getCookie(COOKIE_NAME);
if (!cookie) return;
// When the popover action has already been taken, don't show the popover.
const settings = JSON.parse(cookie);
if (!parseBoolean(settings[path])) return;
const defaultOptions = {
boundary: 'window',
html: true,
placement: 'top',
template: `<div class="gl-popover popover blue learn-gitlab d-none d-xl-block" role="tooltip">
<div class="arrow"></div>
<div class="js-close-learn-gitlab gl-font-weight-bold gl-line-height-normal float-right gl-cursor-pointer gl-font-base gl-text-white gl-opacity-10 gl-p-3">&#10005</div>
<div class="popover-body gl-font-base"></div>
<div class="gl-font-weight-bold gl-text-right gl-text-white gl-p-3 gl-pt-0">${footer}</div>
</div>`,
};
// When one of the popovers is dismissed, remove the cookie.
const closeButton = () => document.querySelector('.js-close-learn-gitlab');
// We still have to use jQuery, since Bootstrap's Popover is based on jQuery.
const jQueryEl = $(el);
const clickCloseButton = disposePopover.bind(jQueryEl);
jQueryEl
.popover({ ...defaultOptions, ...options })
.on('inserted.bs.popover', () => closeButton().addEventListener('click', clickCloseButton))
.on('hide.bs.dropdown', () => closeButton().removeEventListener('click', clickCloseButton))
.popover('show');
// The previous popover actions have been taken, don't show those popovers anymore.
Object.keys(settings).forEach((pathSetting) => {
if (path !== pathSetting) {
settings[pathSetting] = false;
} else {
setCookie(COOKIE_NAME, settings);
}
});
// The final popover action will be taken on click, we then no longer need the cookie.
if (path === POPOVER_LOCATIONS.ISSUES_INDEX) {
el.addEventListener('click', removeLearnGitLabCookie);
}
};
export const showLearnGitLabGroupItemPopover = (id) => {
const el = document.querySelector(`#group-${id} .group-text a`);
if (!el) return;
const options = {
content: __(
'Here are all your projects in your group, including the one you just created. To start, let’s take a look at your personalized learning project which will help you learn about GitLab at your own pace.',
),
};
showPopover(el, POPOVER_LOCATIONS.GROUPS_SHOW, '1 / 2', options);
};
export const showLearnGitLabProjectPopover = () => {
// Do not show a popover if we are not viewing the 'Learn GitLab' project.
if (!window.location.pathname.includes('learn-gitlab')) return;
const el = document.querySelector('a.shortcuts-issues');
if (!el) return;
const options = {
content: sprintf(
__(
'Go to %{strongStart}Issues%{strongEnd} &gt; %{strongStart}Boards%{strongEnd} to access your personalized learning issue board.',
),
{ strongStart: '<strong>', strongEnd: '</strong>' },
false,
),
};
showPopover(el, POPOVER_LOCATIONS.PROJECTS_SHOW, '2 / 2', options);
};
export const showLearnGitLabIssuesPopover = () => {
// Do not show a popover if we are not viewing the 'Learn GitLab' project.
if (!window.location.pathname.includes('learn-gitlab')) return;
const el = document.querySelector('a[data-qa-selector="issue_boards_link"]');
if (!el) return;
const options = {
content: sprintf(
__(
'Go to %{strongStart}Issues%{strongEnd} &gt; %{strongStart}Boards%{strongEnd} to access your personalized learning issue board.',
),
{ strongStart: '<strong>', strongEnd: '</strong>' },
false,
),
};
showPopover(el, POPOVER_LOCATIONS.ISSUES_INDEX, '2 / 2', options);
};
...@@ -9,7 +9,6 @@ import { FILTERED_SEARCH } from '~/pages/constants'; ...@@ -9,7 +9,6 @@ import { FILTERED_SEARCH } from '~/pages/constants';
import { ISSUABLE_INDEX } from '~/pages/projects/constants'; import { ISSUABLE_INDEX } from '~/pages/projects/constants';
import initIssuablesList from '~/issues_list'; import initIssuablesList from '~/issues_list';
import initManualOrdering from '~/manual_ordering'; import initManualOrdering from '~/manual_ordering';
import { showLearnGitLabIssuesPopover } from '~/onboarding_issues';
IssuableFilteredSearchTokenKeys.addExtraTokensForIssues(); IssuableFilteredSearchTokenKeys.addExtraTokensForIssues();
...@@ -25,4 +24,3 @@ new UsersSelect(); ...@@ -25,4 +24,3 @@ new UsersSelect();
initManualOrdering(); initManualOrdering();
initIssuablesList(); initIssuablesList();
showLearnGitLabIssuesPopover();
...@@ -7,7 +7,6 @@ import BlobViewer from '~/blob/viewer/index'; ...@@ -7,7 +7,6 @@ import BlobViewer from '~/blob/viewer/index';
import Activities from '~/activities'; import Activities from '~/activities';
import initReadMore from '~/read_more'; import initReadMore from '~/read_more';
import leaveByUrl from '~/namespaces/leave_by_url'; import leaveByUrl from '~/namespaces/leave_by_url';
import { showLearnGitLabProjectPopover } from '~/onboarding_issues';
import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger'; import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
import initInviteMembersModal from '~/invite_members/init_invite_members_modal'; import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
import initVueNotificationsDropdown from '~/notifications'; import initVueNotificationsDropdown from '~/notifications';
...@@ -41,8 +40,6 @@ if (document.querySelector('.project-show-activity')) { ...@@ -41,8 +40,6 @@ if (document.querySelector('.project-show-activity')) {
leaveByUrl('project'); leaveByUrl('project');
showLearnGitLabProjectPopover();
if (gon.features?.vueNotificationDropdown) { if (gon.features?.vueNotificationDropdown) {
initVueNotificationsDropdown(); initVueNotificationsDropdown();
} else { } else {
......
...@@ -56,8 +56,6 @@ module Registrations ...@@ -56,8 +56,6 @@ module Registrations
).execute ).execute
end end
cookies[:onboarding_issues_settings] = { 'groups#show' => true, 'projects#show' => true, 'issues#index' => true }.to_json if learn_gitlab_project.saved? && !helpers.in_trial_onboarding_flow?
learn_gitlab_project learn_gitlab_project
end end
......
...@@ -72,7 +72,6 @@ RSpec.describe Registrations::ProjectsController do ...@@ -72,7 +72,6 @@ RSpec.describe Registrations::ProjectsController do
expect(subject).to have_gitlab_http_status(:redirect) expect(subject).to have_gitlab_http_status(:redirect)
expect(subject).to redirect_to(users_sign_up_experience_level_path(namespace_path: namespace.to_param)) expect(subject).to redirect_to(users_sign_up_experience_level_path(namespace_path: namespace.to_param))
expect(namespace.projects.find_by_name(s_('Learn GitLab'))).to be_import_finished expect(namespace.projects.find_by_name(s_('Learn GitLab'))).to be_import_finished
expect(cookies[:onboarding_issues_settings]).not_to be_nil
end end
context 'when the trial onboarding is active' do context 'when the trial onboarding is active' do
...@@ -88,7 +87,6 @@ RSpec.describe Registrations::ProjectsController do ...@@ -88,7 +87,6 @@ RSpec.describe Registrations::ProjectsController do
expect { subject }.to change { namespace.projects.pluck(:name) }.from([]).to(['New project', s_('Learn GitLab - Ultimate trial')]) expect { subject }.to change { namespace.projects.pluck(:name) }.from([]).to(['New project', s_('Learn GitLab - Ultimate trial')])
expect(subject).to have_gitlab_http_status(:redirect) expect(subject).to have_gitlab_http_status(:redirect)
expect(namespace.projects.find_by_name(s_('Learn GitLab - Ultimate trial'))).to be_import_finished expect(namespace.projects.find_by_name(s_('Learn GitLab - Ultimate trial'))).to be_import_finished
expect(cookies[:onboarding_issues_settings]).to be_nil
end end
it 'records context and redirects to the trial getting started page' do it 'records context and redirects to the trial getting started page' do
......
...@@ -47,18 +47,5 @@ RSpec.describe 'User sees new onboarding flow', :js do ...@@ -47,18 +47,5 @@ RSpec.describe 'User sees new onboarding flow', :js do
expect(page).to have_content('Learn GitLab') expect(page).to have_content('Learn GitLab')
expect(page).to have_css('.selectable', text: 'Label = ~Novice') expect(page).to have_css('.selectable', text: 'Label = ~Novice')
visit group_path('test')
expect(page).to have_css('.popover', text: 'Here are all your projects in your group, including the one you just created. To start, let’s take a look at your personalized learning project which will help you learn about GitLab at your own pace. 1 / 2')
click_on 'Learn GitLab'
expect(page).to have_content('We prepared tutorials to help you set up GitLab in a way to support your complete software development life cycle.')
expect(page).to have_css('.popover', text: 'Go to Issues > Boards to access your personalized learning issue board. 2 / 2')
page.find('.nav-item-name', text: 'Issues').click
expect(page).to have_css('.popover', text: 'Go to Issues > Boards to access your personalized learning issue board. 2 / 2')
end end
end end
...@@ -13624,9 +13624,6 @@ msgstr "" ...@@ -13624,9 +13624,6 @@ msgstr ""
msgid "Go full screen" msgid "Go full screen"
msgstr "" msgstr ""
msgid "Go to %{strongStart}Issues%{strongEnd} &gt; %{strongStart}Boards%{strongEnd} to access your personalized learning issue board."
msgstr ""
msgid "Go to Integrations" msgid "Go to Integrations"
msgstr "" msgstr ""
...@@ -14515,9 +14512,6 @@ msgstr "" ...@@ -14515,9 +14512,6 @@ msgstr ""
msgid "Helps reduce request volume for protected paths" msgid "Helps reduce request volume for protected paths"
msgstr "" msgstr ""
msgid "Here are all your projects in your group, including the one you just created. To start, let’s take a look at your personalized learning project which will help you learn about GitLab at your own pace."
msgstr ""
msgid "Here you will find recent merge request activity" msgid "Here you will find recent merge request activity"
msgstr "" msgstr ""
......
import $ from 'jquery';
import setWindowLocation from 'helpers/set_window_location_helper';
import { showLearnGitLabIssuesPopover } from '~/onboarding_issues';
import { getCookie, setCookie, removeCookie } from '~/lib/utils/common_utils';
import Tracking from '~/tracking';
describe('Onboarding Issues Popovers', () => {
const COOKIE_NAME = 'onboarding_issues_settings';
const getCookieValue = () => JSON.parse(getCookie(COOKIE_NAME));
beforeEach(() => {
jest.spyOn($.fn, 'popover');
});
afterEach(() => {
$.fn.popover.mockRestore();
document.getElementsByTagName('html')[0].innerHTML = '';
removeCookie(COOKIE_NAME);
});
const setupShowLearnGitLabIssuesPopoverTest = ({
currentPath = 'group/learn-gitlab',
isIssuesBoardsLinkShown = true,
isCookieSet = true,
cookieValue = true,
} = {}) => {
setWindowLocation(`http://example.com/${currentPath}`);
if (isIssuesBoardsLinkShown) {
const elem = document.createElement('a');
elem.setAttribute('data-qa-selector', 'issue_boards_link');
document.body.appendChild(elem);
}
if (isCookieSet) {
setCookie(COOKIE_NAME, { previous: true, 'issues#index': cookieValue });
}
showLearnGitLabIssuesPopover();
};
describe('showLearnGitLabIssuesPopover', () => {
describe('when on another project', () => {
beforeEach(() => {
setupShowLearnGitLabIssuesPopoverTest({
currentPath: 'group/another-project',
});
});
it('does not show a popover', () => {
expect($.fn.popover).not.toHaveBeenCalled();
});
});
describe('when the issues boards link is not shown', () => {
beforeEach(() => {
setupShowLearnGitLabIssuesPopoverTest({
isIssuesBoardsLinkShown: false,
});
});
it('does not show a popover', () => {
expect($.fn.popover).not.toHaveBeenCalled();
});
});
describe('when the cookie is not set', () => {
beforeEach(() => {
setupShowLearnGitLabIssuesPopoverTest({
isCookieSet: false,
});
});
it('does not show a popover', () => {
expect($.fn.popover).not.toHaveBeenCalled();
});
});
describe('when the cookie value is false', () => {
beforeEach(() => {
setupShowLearnGitLabIssuesPopoverTest({
cookieValue: false,
});
});
it('does not show a popover', () => {
expect($.fn.popover).not.toHaveBeenCalled();
});
});
describe('with all the right conditions', () => {
beforeEach(() => {
setupShowLearnGitLabIssuesPopoverTest();
});
it('shows a popover', () => {
expect($.fn.popover).toHaveBeenCalled();
});
it('does not change the cookie value', () => {
expect(getCookieValue()['issues#index']).toBe(true);
});
it('disables the previous popover', () => {
expect(getCookieValue().previous).toBe(false);
});
describe('when clicking the issues boards link', () => {
beforeEach(() => {
document.querySelector('a[data-qa-selector="issue_boards_link"]').click();
});
it('deletes the cookie', () => {
expect(getCookie(COOKIE_NAME)).toBe(undefined);
});
});
describe('when dismissing the popover', () => {
beforeEach(() => {
jest.spyOn(Tracking, 'event');
document.querySelector('.learn-gitlab.popover .js-close-learn-gitlab').click();
});
it('deletes the cookie', () => {
expect(getCookie(COOKIE_NAME)).toBe(undefined);
});
it('sends a tracking event', () => {
expect(Tracking.event).toHaveBeenCalledWith(
'Growth::Conversion::Experiment::OnboardingIssues',
'dismiss_popover',
);
});
});
});
});
});
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