diff options
author | Simon Knox <psimyn@gmail.com> | 2019-06-14 17:53:34 +0300 |
---|---|---|
committer | Simon Knox <psimyn@gmail.com> | 2019-06-14 17:53:34 +0300 |
commit | dfc2d02cc6f848b65849525b6213574714855040 (patch) | |
tree | f1ae76ce0fb487d60c1862588c0a3079e038f874 /app | |
parent | 14f27102b696672f02b5d1b2ab45688b711f4024 (diff) | |
parent | ae853dba6b9e5f45aea0d14965c9691840db78f7 (diff) |
Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into 62966-embed-zoom-call-in-issue-mvc
Diffstat (limited to 'app')
18 files changed, 212 insertions, 82 deletions
diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue index 11d6672cacf..81da0754752 100644 --- a/app/assets/javascripts/diffs/components/app.vue +++ b/app/assets/javascripts/diffs/components/app.vue @@ -69,6 +69,16 @@ export default { required: false, default: false, }, + dismissEndpoint: { + type: String, + required: false, + default: '', + }, + showSuggestPopover: { + type: Boolean, + required: false, + default: false, + }, }, data() { const treeWidth = @@ -141,7 +151,12 @@ export default { showTreeList: 'adjustView', }, mounted() { - this.setBaseConfig({ endpoint: this.endpoint, projectPath: this.projectPath }); + this.setBaseConfig({ + endpoint: this.endpoint, + projectPath: this.projectPath, + dismissEndpoint: this.dismissEndpoint, + showSuggestPopover: this.showSuggestPopover, + }); if (this.shouldShow) { this.fetchData(); diff --git a/app/assets/javascripts/diffs/components/diff_line_note_form.vue b/app/assets/javascripts/diffs/components/diff_line_note_form.vue index c209b857652..da0cdbe467b 100644 --- a/app/assets/javascripts/diffs/components/diff_line_note_form.vue +++ b/app/assets/javascripts/diffs/components/diff_line_note_form.vue @@ -42,6 +42,7 @@ export default { noteableData: state => state.notes.noteableData, diffViewType: state => state.diffs.diffViewType, }), + ...mapState('diffs', ['showSuggestPopover']), ...mapGetters('diffs', ['getDiffFileByHash']), ...mapGetters([ 'isLoggedIn', @@ -80,7 +81,12 @@ export default { } }, methods: { - ...mapActions('diffs', ['cancelCommentForm', 'assignDiscussionsToDiff', 'saveDiffDiscussion']), + ...mapActions('diffs', [ + 'cancelCommentForm', + 'assignDiscussionsToDiff', + 'saveDiffDiscussion', + 'setSuggestPopoverDismissed', + ]), handleCancelCommentForm(shouldConfirm, isDirty) { if (shouldConfirm && isDirty) { const msg = s__('Notes|Are you sure you want to cancel creating this comment?'); @@ -125,11 +131,13 @@ export default { :line="line" :help-page-path="helpPagePath" :diff-file="diffFile" + :show-suggest-popover="showSuggestPopover" save-button-title="Comment" class="diff-comment-form" @handleFormUpdateAddToReview="addToReview" @cancelForm="handleCancelCommentForm" @handleFormUpdate="handleSaveNote" + @handleSuggestDismissed="setSuggestPopoverDismissed" /> </div> </template> diff --git a/app/assets/javascripts/diffs/index.js b/app/assets/javascripts/diffs/index.js index 1d897bca1dd..1e57e9b8a30 100644 --- a/app/assets/javascripts/diffs/index.js +++ b/app/assets/javascripts/diffs/index.js @@ -72,6 +72,8 @@ export default function initDiffsApp(store) { currentUser: JSON.parse(dataset.currentUserData) || {}, changesEmptyStateIllustration: dataset.changesEmptyStateIllustration, isFluidLayout: parseBoolean(dataset.isFluidLayout), + dismissEndpoint: dataset.dismissEndpoint, + showSuggestPopover: parseBoolean(dataset.showSuggestPopover), }; }, computed: { @@ -99,6 +101,8 @@ export default function initDiffsApp(store) { shouldShow: this.activeTab === 'diffs', changesEmptyStateIllustration: this.changesEmptyStateIllustration, isFluidLayout: this.isFluidLayout, + dismissEndpoint: this.dismissEndpoint, + showSuggestPopover: this.showSuggestPopover, }, }); }, diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js index 479afc50113..88d7b4bba63 100644 --- a/app/assets/javascripts/diffs/store/actions.js +++ b/app/assets/javascripts/diffs/store/actions.js @@ -36,8 +36,8 @@ import { import { diffViewerModes } from '~/ide/constants'; export const setBaseConfig = ({ commit }, options) => { - const { endpoint, projectPath } = options; - commit(types.SET_BASE_CONFIG, { endpoint, projectPath }); + const { endpoint, projectPath, dismissEndpoint, showSuggestPopover } = options; + commit(types.SET_BASE_CONFIG, { endpoint, projectPath, dismissEndpoint, showSuggestPopover }); }; export const fetchDiffFiles = ({ state, commit }) => { @@ -455,5 +455,17 @@ export const toggleFullDiff = ({ dispatch, getters, state }, filePath) => { export const setFileCollapsed = ({ commit }, { filePath, collapsed }) => commit(types.SET_FILE_COLLAPSED, { filePath, collapsed }); +export const setSuggestPopoverDismissed = ({ commit, state }) => + axios + .post(state.dismissEndpoint, { + feature_name: 'suggest_popover_dismissed', + }) + .then(() => { + commit(types.SET_SHOW_SUGGEST_POPOVER); + }) + .catch(() => { + createFlash(s__('MergeRequest|Error dismissing suggestion popover. Please try again.')); + }); + // prevent babel-plugin-rewire from generating an invalid default during karma tests export default () => {}; diff --git a/app/assets/javascripts/diffs/store/modules/diff_state.js b/app/assets/javascripts/diffs/store/modules/diff_state.js index cf4dd93dbfb..6821c8445ea 100644 --- a/app/assets/javascripts/diffs/store/modules/diff_state.js +++ b/app/assets/javascripts/diffs/store/modules/diff_state.js @@ -28,4 +28,6 @@ export default () => ({ renderTreeList: true, showWhitespace: true, fileFinderVisible: false, + dismissEndpoint: '', + showSuggestPopover: true, }); diff --git a/app/assets/javascripts/diffs/store/mutation_types.js b/app/assets/javascripts/diffs/store/mutation_types.js index 6bb24c97139..8d6111da500 100644 --- a/app/assets/javascripts/diffs/store/mutation_types.js +++ b/app/assets/javascripts/diffs/store/mutation_types.js @@ -33,3 +33,5 @@ export const SET_HIDDEN_VIEW_DIFF_FILE_LINES = 'SET_HIDDEN_VIEW_DIFF_FILE_LINES' export const SET_CURRENT_VIEW_DIFF_FILE_LINES = 'SET_CURRENT_VIEW_DIFF_FILE_LINES'; export const ADD_CURRENT_VIEW_DIFF_FILE_LINES = 'ADD_CURRENT_VIEW_DIFF_FILE_LINES'; export const TOGGLE_DIFF_FILE_RENDERING_MORE = 'TOGGLE_DIFF_FILE_RENDERING_MORE'; + +export const SET_SHOW_SUGGEST_POPOVER = 'SET_SHOW_SUGGEST_POPOVER'; diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js index 67bc1724738..00181a63c43 100644 --- a/app/assets/javascripts/diffs/store/mutations.js +++ b/app/assets/javascripts/diffs/store/mutations.js @@ -11,8 +11,8 @@ import * as types from './mutation_types'; export default { [types.SET_BASE_CONFIG](state, options) { - const { endpoint, projectPath } = options; - Object.assign(state, { endpoint, projectPath }); + const { endpoint, projectPath, dismissEndpoint, showSuggestPopover } = options; + Object.assign(state, { endpoint, projectPath, dismissEndpoint, showSuggestPopover }); }, [types.SET_LOADING](state, isLoading) { @@ -302,4 +302,7 @@ export default { file.renderingLines = !file.renderingLines; }, + [types.SET_SHOW_SUGGEST_POPOVER](state) { + state.showSuggestPopover = false; + }, }; diff --git a/app/assets/javascripts/notes/components/note_form.vue b/app/assets/javascripts/notes/components/note_form.vue index 09ecb695214..042ed196933 100644 --- a/app/assets/javascripts/notes/components/note_form.vue +++ b/app/assets/javascripts/notes/components/note_form.vue @@ -77,6 +77,11 @@ export default { required: false, default: '', }, + showSuggestPopover: { + type: Boolean, + required: false, + default: false, + }, }, data() { let updatedNoteBody = this.noteBody; @@ -247,6 +252,8 @@ export default { :can-suggest="canSuggest" :add-spacing-classes="false" :help-page-path="helpPagePath" + :show-suggest-popover="showSuggestPopover" + @handleSuggestDismissed="() => $emit('handleSuggestDismissed')" > <textarea id="note_note" @@ -303,7 +310,7 @@ export default { {{ __('Add comment now') }} </button> <button - class="btn btn-cancel note-edit-cancel js-close-discussion-note-form" + class="btn note-edit-cancel js-close-discussion-note-form" type="button" @click="cancelHandler()" > diff --git a/app/assets/javascripts/vue_shared/components/markdown/field.vue b/app/assets/javascripts/vue_shared/components/markdown/field.vue index 0f3b3568414..3bdc0bb8ebd 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/field.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/field.vue @@ -67,6 +67,11 @@ export default { required: false, default: '', }, + showSuggestPopover: { + type: Boolean, + required: false, + default: false, + }, }, data() { return { @@ -194,8 +199,10 @@ export default { :preview-markdown="previewMarkdown" :line-content="lineContent" :can-suggest="canSuggest" + :show-suggest-popover="showSuggestPopover" @preview-markdown="showPreviewTab" @write-markdown="showWriteTab" + @handleSuggestDismissed="() => $emit('handleSuggestDismissed')" /> <div v-show="!previewMarkdown" class="md-write-holder"> <div class="zen-backdrop"> diff --git a/app/assets/javascripts/vue_shared/components/markdown/header.vue b/app/assets/javascripts/vue_shared/components/markdown/header.vue index a5a5b2ef415..56a16c9e4d6 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/header.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/header.vue @@ -1,6 +1,6 @@ <script> import $ from 'jquery'; -import { GlTooltipDirective } from '@gitlab/ui'; +import { GlPopover, GlButton, GlTooltipDirective } from '@gitlab/ui'; import ToolbarButton from './toolbar_button.vue'; import Icon from '../icon.vue'; @@ -8,6 +8,8 @@ export default { components: { ToolbarButton, Icon, + GlPopover, + GlButton, }, directives: { GlTooltip: GlTooltipDirective, @@ -27,6 +29,11 @@ export default { required: false, default: true, }, + showSuggestPopover: { + type: Boolean, + required: false, + default: false, + }, }, computed: { mdTable() { @@ -70,6 +77,9 @@ export default { this.$emit('write-markdown'); }, + handleSuggestDismissed() { + this.$emit('handleSuggestDismissed'); + }, }, }; </script> @@ -93,66 +103,92 @@ export default { </button> </li> <li :class="{ active: !previewMarkdown }" class="md-header-toolbar"> - <toolbar-button tag="**" :button-title="__('Add bold text')" icon="bold" /> - <toolbar-button tag="*" :button-title="__('Add italic text')" icon="italic" /> - <toolbar-button - :prepend="true" - tag="> " - :button-title="__('Insert a quote')" - icon="quote" - /> - <toolbar-button tag="`" tag-block="```" :button-title="__('Insert code')" icon="code" /> - <toolbar-button - tag="[{text}](url)" - tag-select="url" - :button-title="__('Add a link')" - icon="link" - /> - <toolbar-button - :prepend="true" - tag="* " - :button-title="__('Add a bullet list')" - icon="list-bulleted" - /> - <toolbar-button - :prepend="true" - tag="1. " - :button-title="__('Add a numbered list')" - icon="list-numbered" - /> - <toolbar-button - :prepend="true" - tag="* [ ] " - :button-title="__('Add a task list')" - icon="task-done" - /> - <toolbar-button - :tag="mdTable" - :prepend="true" - :button-title="__('Add a table')" - icon="table" - /> - <toolbar-button - v-if="canSuggest" - :tag="mdSuggestion" - :prepend="true" - :button-title="__('Insert suggestion')" - :cursor-offset="4" - :tag-content="lineContent" - icon="doc-code" - class="qa-suggestion-btn" - /> - <button - v-gl-tooltip - :aria-label="__('Go full screen')" - class="toolbar-btn toolbar-fullscreen-btn js-zen-enter" - data-container="body" - tabindex="-1" - :title="__('Go full screen')" - type="button" - > - <icon name="screen-full" /> - </button> + <div class="d-inline-block"> + <toolbar-button tag="**" :button-title="__('Add bold text')" icon="bold" /> + <toolbar-button tag="*" :button-title="__('Add italic text')" icon="italic" /> + <toolbar-button + :prepend="true" + tag="> " + :button-title="__('Insert a quote')" + icon="quote" + /> + </div> + <div class="d-inline-block ml-md-2 ml-0"> + <template v-if="canSuggest"> + <toolbar-button + ref="suggestButton" + :tag="mdSuggestion" + :prepend="true" + :button-title="__('Insert suggestion')" + :cursor-offset="4" + :tag-content="lineContent" + icon="doc-code" + class="qa-suggestion-btn" + @click="handleSuggestDismissed" + /> + <gl-popover + v-if="showSuggestPopover" + :target="() => $refs.suggestButton" + :css-classes="['diff-suggest-popover']" + placement="bottom" + :show="showSuggestPopover" + > + <strong>{{ __('New! Suggest changes directly') }}</strong> + <p class="mb-2"> + {{ __('Suggest code changes which are immediately applied. Try it out!') }} + </p> + <gl-button variant="primary" size="sm" @click="handleSuggestDismissed"> + {{ __('Got it') }} + </gl-button> + </gl-popover> + </template> + <toolbar-button tag="`" tag-block="```" :button-title="__('Insert code')" icon="code" /> + <toolbar-button + tag="[{text}](url)" + tag-select="url" + :button-title="__('Add a link')" + icon="link" + /> + </div> + <div class="d-inline-block ml-md-2 ml-0"> + <toolbar-button + :prepend="true" + tag="* " + :button-title="__('Add a bullet list')" + icon="list-bulleted" + /> + <toolbar-button + :prepend="true" + tag="1. " + :button-title="__('Add a numbered list')" + icon="list-numbered" + /> + <toolbar-button + :prepend="true" + tag="* [ ] " + :button-title="__('Add a task list')" + icon="task-done" + /> + <toolbar-button + :tag="mdTable" + :prepend="true" + :button-title="__('Add a table')" + icon="table" + /> + </div> + <div class="d-inline-block ml-md-2 ml-0"> + <button + v-gl-tooltip + :aria-label="__('Go full screen')" + class="toolbar-btn toolbar-fullscreen-btn js-zen-enter" + data-container="body" + tabindex="-1" + :title="__('Go full screen')" + type="button" + > + <icon name="screen-full" /> + </button> + </div> </li> </ul> </div> diff --git a/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue b/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue index 4572caa907b..94f78c0c085 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue @@ -66,6 +66,7 @@ export default { class="toolbar-btn js-md" tabindex="-1" data-container="body" + @click="() => $emit('click')" > <icon :name="icon" /> </button> diff --git a/app/assets/javascripts/vue_shared/components/pagination/constants.js b/app/assets/javascripts/vue_shared/components/pagination/constants.js index c24b142ac7e..748ad178c70 100644 --- a/app/assets/javascripts/vue_shared/components/pagination/constants.js +++ b/app/assets/javascripts/vue_shared/components/pagination/constants.js @@ -7,3 +7,7 @@ export const PREV = s__('Pagination|Prev'); export const NEXT = s__('Pagination|Next'); export const FIRST = s__('Pagination|« First'); export const LAST = s__('Pagination|Last »'); +export const LABEL_FIRST_PAGE = s__('Pagination|Go to first page'); +export const LABEL_PREV_PAGE = s__('Pagination|Go to previous page'); +export const LABEL_NEXT_PAGE = s__('Pagination|Go to next page'); +export const LABEL_LAST_PAGE = s__('Pagination|Go to last page'); diff --git a/app/assets/javascripts/vue_shared/components/pagination_links.vue b/app/assets/javascripts/vue_shared/components/pagination_links.vue index 0b44f8578cb..06097913e91 100644 --- a/app/assets/javascripts/vue_shared/components/pagination_links.vue +++ b/app/assets/javascripts/vue_shared/components/pagination_links.vue @@ -1,6 +1,13 @@ <script> import { GlPagination } from '@gitlab/ui'; -import { s__ } from '../../locale'; +import { + PREV, + NEXT, + LABEL_FIRST_PAGE, + LABEL_PREV_PAGE, + LABEL_NEXT_PAGE, + LABEL_LAST_PAGE, +} from '~/vue_shared/components/pagination/constants'; export default { components: { @@ -16,23 +23,27 @@ export default { required: true, }, }, - firstText: s__('Pagination|« First'), - prevText: s__('Pagination|Prev'), - nextText: s__('Pagination|Next'), - lastText: s__('Pagination|Last »'), + prevText: PREV, + nextText: NEXT, + labelFirstPage: LABEL_FIRST_PAGE, + labelPrevPage: LABEL_PREV_PAGE, + labelNextPage: LABEL_NEXT_PAGE, + labelLastPage: LABEL_LAST_PAGE, }; </script> <template> <gl-pagination v-bind="$attrs" - :change="change" - :page="pageInfo.page" + :value="pageInfo.page" :per-page="pageInfo.perPage" :total-items="pageInfo.total" - :first-text="$options.firstText" :prev-text="$options.prevText" :next-text="$options.nextText" - :last-text="$options.lastText" + :label-first-page="$options.labelFirstPage" + :label-prev-page="$options.labelPrevPage" + :label-next-page="$options.labelNextPage" + :label-last-page="$options.labelLastPage" + @input="change" /> </template> diff --git a/app/assets/stylesheets/framework/markdown_area.scss b/app/assets/stylesheets/framework/markdown_area.scss index bfd96a4bc05..0bf911eec0a 100644 --- a/app/assets/stylesheets/framework/markdown_area.scss +++ b/app/assets/stylesheets/framework/markdown_area.scss @@ -154,11 +154,9 @@ } .toolbar-fullscreen-btn { - margin-left: $gl-padding; margin-right: -5px; @include media-breakpoint-down(xs) { - margin-left: 0; margin-right: 0; } } diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index 4ebf1019456..d2d35d91e0b 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -14,7 +14,7 @@ position: -webkit-sticky; position: sticky; top: $mr-file-header-top; - z-index: 102; + z-index: 220; &::before { content: ''; @@ -1122,3 +1122,15 @@ table.code { outline: 0; } } + +.diff-suggest-popover { + &.popover { + width: 250px; + min-width: 250px; + z-index: 210; + } + + .popover-header { + display: none; + } +} diff --git a/app/helpers/user_callouts_helper.rb b/app/helpers/user_callouts_helper.rb index 5d658d35107..d5e459311f7 100644 --- a/app/helpers/user_callouts_helper.rb +++ b/app/helpers/user_callouts_helper.rb @@ -3,6 +3,7 @@ module UserCalloutsHelper GKE_CLUSTER_INTEGRATION = 'gke_cluster_integration'.freeze GCP_SIGNUP_OFFER = 'gcp_signup_offer'.freeze + SUGGEST_POPOVER_DISMISSED = 'suggest_popover_dismissed'.freeze def show_gke_cluster_integration_callout?(project) can?(current_user, :create_cluster, project) && @@ -20,6 +21,10 @@ module UserCalloutsHelper def render_dashboard_gold_trial(user) end + def show_suggest_popover? + !user_dismissed?(SUGGEST_POPOVER_DISMISSED) + end + private def user_dismissed?(feature_name) diff --git a/app/models/user_callout_enums.rb b/app/models/user_callout_enums.rb index b9373ae6166..54b0d2ce831 100644 --- a/app/models/user_callout_enums.rb +++ b/app/models/user_callout_enums.rb @@ -10,7 +10,8 @@ module UserCalloutEnums { gke_cluster_integration: 1, gcp_signup_offer: 2, - cluster_security_warning: 3 + cluster_security_warning: 3, + suggest_popover_dismissed: 4 } end end diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml index a201fafb949..f593f4e049e 100644 --- a/app/views/projects/merge_requests/show.html.haml +++ b/app/views/projects/merge_requests/show.html.haml @@ -80,7 +80,9 @@ current_user_data: UserSerializer.new(project: @project).represent(current_user, {}, MergeRequestUserEntity).to_json, project_path: project_path(@merge_request.project), changes_empty_state_illustration: image_path('illustrations/merge_request_changes_empty.svg'), - is_fluid_layout: fluid_layout.to_s } } + is_fluid_layout: fluid_layout.to_s, + dismiss_endpoint: user_callouts_path, + show_suggest_popover: show_suggest_popover?.to_s } } .mr-loading-status = spinner |