Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2019-06-14 16:01:24 +0300
committerPhil Hughes <me@iamphill.com>2019-06-14 16:01:24 +0300
commitd2fd6bd51036be836c2c793e2bd7a503c7ad9030 (patch)
treefe86f4b3dca7f33ec37be2c75ea061afafcdb4fe /app/assets/javascripts
parent577832598f1b35187efafc426068ef7ac36ae09f (diff)
Added diff suggestion popover
Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/56523
Diffstat (limited to 'app/assets/javascripts')
-rw-r--r--app/assets/javascripts/diffs/components/app.vue17
-rw-r--r--app/assets/javascripts/diffs/components/diff_line_note_form.vue10
-rw-r--r--app/assets/javascripts/diffs/index.js4
-rw-r--r--app/assets/javascripts/diffs/store/actions.js16
-rw-r--r--app/assets/javascripts/diffs/store/modules/diff_state.js2
-rw-r--r--app/assets/javascripts/diffs/store/mutation_types.js2
-rw-r--r--app/assets/javascripts/diffs/store/mutations.js7
-rw-r--r--app/assets/javascripts/notes/components/note_form.vue9
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/field.vue7
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/header.vue158
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue1
11 files changed, 165 insertions, 68 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>