Commit 631fc8c9 authored by Jackie Fraser's avatar Jackie Fraser

Nudge users to commit their changes

Once the user selected a template on the previous step,
show the next popover.
parent 2665e40c
......@@ -9,6 +9,7 @@ import GitignoreSelector from './template_selectors/gitignore_selector';
import LicenseSelector from './template_selectors/license_selector';
import toast from '~/vue_shared/plugins/global_toast';
import { __ } from '~/locale';
import initPopover from '~/blob/suggest_gitlab_ci_yml';
export default class FileTemplateMediator {
constructor({ editor, currentAction, projectId }) {
......@@ -128,6 +129,7 @@ export default class FileTemplateMediator {
selectTemplateFile(selector, query, data) {
const self = this;
const { name } = selector.config;
const suggestCommitChanges = document.querySelector('.js-suggest-gitlab-ci-yml-commit-changes');
selector.renderLoading();
......@@ -146,6 +148,10 @@ export default class FileTemplateMediator {
},
},
});
if (suggestCommitChanges) {
initPopover(suggestCommitChanges);
}
})
.catch(err => new Flash(`An error occurred while fetching the template: ${err}`));
}
......
<script>
import { GlPopover, GlSprintf, GlButton, GlIcon } from '@gitlab/ui';
import Cookies from 'js-cookie';
import { parseBoolean } from '~/lib/utils/common_utils';
import { parseBoolean, scrollToElement } from '~/lib/utils/common_utils';
import { s__ } from '~/locale';
import { glEmojiTag } from '~/emoji';
const popoverStates = {
suggest_gitlab_ci_yml: {
title: s__(`suggestPipeline|1/2: Choose a template`),
content: s__(
`suggestPipeline|We recommend the %{boldStart}Code Quality%{boldEnd} template, which will add a report widget to your Merge Requests. This way you’ll learn about code quality degradations much sooner. %{footerStart} Goodbye technical debt! %{footerEnd}`,
),
emoji: glEmojiTag('wave'),
},
suggest_commit_first_project_gitlab_ci_yml: {
title: s__(`suggestPipeline|2/2: Commit your changes`),
content: s__(
`suggestPipeline|Commit the changes and your pipeline will automatically run for the first time.`,
),
},
};
export default {
components: {
GlPopover,
......@@ -17,7 +32,7 @@ export default {
type: String,
required: true,
},
cssClass: {
trackLabel: {
type: String,
required: true,
},
......@@ -33,17 +48,19 @@ export default {
},
computed: {
suggestTitle() {
return s__(`suggestPipeline|1/2: Choose a template`);
return popoverStates[this.trackLabel].title || '';
},
suggestContent() {
return s__(
`suggestPipeline|We recommend the %{boldStart}Code Quality%{boldEnd} template, which will add a report widget to your Merge Requests. This way you’ll learn about code quality degradations much sooner. %{footerStart} Goodbye technical debt! %{footerEnd}`,
);
return popoverStates[this.trackLabel].content || '';
},
emoji() {
return glEmojiTag('wave');
return popoverStates[this.trackLabel].emoji || '';
},
},
mounted() {
if (this.trackLabel === 'suggest_commit_first_project_gitlab_ci_yml' && !this.popoverDismissed)
scrollToElement(document.querySelector(this.target));
},
methods: {
onDismiss() {
this.popoverDismissed = true;
......@@ -61,13 +78,15 @@ export default {
placement="rightbottom"
trigger="manual"
container="viewport"
:css-classes="[cssClass]"
:css-classes="['suggest-gitlab-ci-yml', 'ml-4']"
>
<template #title>
<gl-button :aria-label="__('Close')" class="btn-blank float-right" @click="onDismiss">
<gl-icon name="close" aria-hidden="true" />
</gl-button>
{{ suggestTitle }}
<span v-html="suggestTitle"></span>
<span class="ml-auto">
<gl-button :aria-label="__('Close')" class="btn-blank" @click="onDismiss">
<gl-icon name="close" aria-hidden="true" />
</gl-button>
</span>
</template>
<gl-sprintf :message="suggestContent">
......
......@@ -8,7 +8,7 @@ export default el =>
return createElement(Popover, {
props: {
target: el.dataset.target,
cssClass: el.dataset.cssClass,
trackLabel: el.dataset.trackLabel,
dismissKey: el.dataset.dismissKey,
},
});
......
......@@ -4,11 +4,13 @@ import $ from 'jquery';
import NewCommitForm from '../new_commit_form';
import EditBlob from './edit_blob';
import BlobFileDropzone from '../blob/blob_file_dropzone';
import initPopover from '~/blob/suggest_gitlab_ci_yml';
export default () => {
const editBlobForm = $('.js-edit-blob-form');
const uploadBlobForm = $('.js-upload-blob-form');
const deleteBlobForm = $('.js-delete-blob-form');
const suggestEl = document.querySelector('.js-suggest-gitlab-ci-yml');
if (editBlobForm.length) {
const urlRoot = editBlobForm.data('relativeUrlRoot');
......@@ -56,4 +58,8 @@ export default () => {
if (deleteBlobForm.length) {
new NewCommitForm(deleteBlobForm);
}
if (suggestEl) {
initPopover(suggestEl);
}
};
......@@ -144,9 +144,7 @@
.popover-header {
padding: $gl-padding;
.ic-close {
margin-top: -1em;
}
display: flex;
align-items: center;
}
}
.form-actions
= button_tag 'Commit changes', class: 'btn commit-btn js-commit-button btn-success qa-commit-button'
= button_tag 'Commit changes', id: 'commit-changes', class: 'btn commit-btn js-commit-button btn-success qa-commit-button'
= link_to 'Cancel', cancel_path,
class: 'btn btn-cancel', data: {confirm: leave_edit_message}
......
......@@ -20,7 +20,10 @@
required: true, class: 'form-control new-file-name js-file-path-name-input', value: params[:file_name] || (should_suggest_gitlab_ci_yml? ? '.gitlab-ci.yml' : '')
= render 'template_selectors'
- if should_suggest_gitlab_ci_yml?
= render partial: 'suggest_gitlab_ci_yml', locals: { target: '#gitlab-ci-yml-selector', dismiss_key: "suggest_gitlab_ci_yml_#{@project.id}" }
.js-suggest-gitlab-ci-yml{ data: { toggle: 'popover',
target: '#gitlab-ci-yml-selector',
track_label: 'suggest_gitlab_ci_yml',
dismiss_key: "suggest_gitlab_ci_yml_#{@project.id}" } }
.file-buttons
- if is_markdown
......
.js-suggest-gitlab-ci-yml{ data: { toggle: 'popover',
target: target,
css_class: 'suggest-gitlab-ci-yml ml-4',
dismiss_key: dismiss_key } }
......@@ -13,3 +13,8 @@
= hidden_field_tag 'content', '', id: 'file-content'
= render 'projects/commit_button', ref: @ref,
cancel_path: project_tree_path(@project, @id)
- if should_suggest_gitlab_ci_yml?
.js-suggest-gitlab-ci-yml-commit-changes{ data: { toggle: 'popover',
target: '#commit-changes',
track_label: 'suggest_commit_first_project_gitlab_ci_yml',
dismiss_key: "suggest_commit_first_project_gitlab_ci_yml_#{@project.id}" } }
......@@ -24211,6 +24211,12 @@ msgstr ""
msgid "suggestPipeline|1/2: Choose a template"
msgstr ""
msgid "suggestPipeline|2/2: Commit your changes"
msgstr ""
msgid "suggestPipeline|Commit the changes and your pipeline will automatically run for the first time."
msgstr ""
msgid "suggestPipeline|We recommend the %{boldStart}Code Quality%{boldEnd} template, which will add a report widget to your Merge Requests. This way you’ll learn about code quality degradations much sooner. %{footerStart} Goodbye technical debt! %{footerEnd}"
msgstr ""
......
import { shallowMount } from '@vue/test-utils';
import Popover from '~/blob/suggest_gitlab_ci_yml/components/popover.vue';
import Cookies from 'js-cookie';
import * as utils from '~/lib/utils/common_utils';
const popoverTarget = 'gitlab-ci-yml-selector';
jest.mock('~/lib/utils/common_utils', () => ({
...jest.requireActual('~/lib/utils/common_utils'),
scrollToElement: jest.fn(),
}));
const target = 'gitlab-ci-yml-selector';
const dismissKey = 'suggest_gitlab_ci_yml_99';
const defaultTrackLabel = 'suggest_gitlab_ci_yml';
describe('Suggest gitlab-ci.yml Popover', () => {
let wrapper;
function createWrapper() {
function createWrapper(trackLabel) {
wrapper = shallowMount(Popover, {
propsData: {
target: popoverTarget,
cssClass: 'js-class',
target,
trackLabel,
dismissKey,
},
});
......@@ -25,7 +32,7 @@ describe('Suggest gitlab-ci.yml Popover', () => {
describe('when no dismiss cookie is set', () => {
beforeEach(() => {
createWrapper();
createWrapper(defaultTrackLabel);
});
it('sets popoverDismissed to false', () => {
......@@ -36,11 +43,26 @@ describe('Suggest gitlab-ci.yml Popover', () => {
describe('when the dismiss cookie is set', () => {
beforeEach(() => {
Cookies.set(dismissKey, true);
createWrapper();
createWrapper(defaultTrackLabel);
});
it('sets popoverDismissed to true', () => {
expect(wrapper.vm.popoverDismissed).toEqual(true);
});
beforeEach(() => {
Cookies.remove(dismissKey);
});
});
describe('when the popover is mounted with the trackLabel of the Confirm button popover at the bottom of the page', () => {
it('calls scrollToElement so that the Confirm button and popover will be in sight', () => {
const scrollToElementSpy = jest.spyOn(utils, 'scrollToElement');
const commitTrackLabel = 'suggest_commit_first_project_gitlab_ci_yml';
createWrapper(commitTrackLabel);
expect(scrollToElementSpy).toHaveBeenCalled();
});
});
});
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