diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-05 21:13:27 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-05 21:13:27 +0300 |
commit | ad41744a177d11ead3268b1ec706e9c26f593060 (patch) | |
tree | 3c06d26fa5577a484e6c096a2b6b28ee14461b23 /app/assets | |
parent | a84626f13d61d190b2db5e44caf71b22fc541276 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
5 files changed, 69 insertions, 96 deletions
diff --git a/app/assets/javascripts/access_tokens/index.js b/app/assets/javascripts/access_tokens/index.js index 7f5f0403de6..2cd3a8f12ee 100644 --- a/app/assets/javascripts/access_tokens/index.js +++ b/app/assets/javascripts/access_tokens/index.js @@ -49,7 +49,7 @@ export const initProjectsField = () => { { default: createDefaultClient }, ]) => { const apolloProvider = new VueApollo({ - defaultClient: createDefaultClient(), + defaultClient: createDefaultClient({}, { assumeImmutableResults: true }), }); Vue.use(VueApollo); diff --git a/app/assets/javascripts/comment_type_toggle.js b/app/assets/javascripts/comment_type_toggle.js deleted file mode 100644 index 2fcd40a901d..00000000000 --- a/app/assets/javascripts/comment_type_toggle.js +++ /dev/null @@ -1,71 +0,0 @@ -import DropLab from './droplab/drop_lab'; -import ISetter from './droplab/plugins/input_setter'; - -// Todo: Remove this when fixing issue in input_setter plugin -const InputSetter = { ...ISetter }; - -class CommentTypeToggle { - constructor(opts = {}) { - this.dropdownTrigger = opts.dropdownTrigger; - this.dropdownList = opts.dropdownList; - this.noteTypeInput = opts.noteTypeInput; - this.submitButton = opts.submitButton; - this.closeButton = opts.closeButton; - this.reopenButton = opts.reopenButton; - } - - initDroplab() { - this.droplab = new DropLab(); - - const config = this.setConfig(); - - this.droplab.init(this.dropdownTrigger, this.dropdownList, [InputSetter], config); - } - - setConfig() { - const config = { - InputSetter: [ - { - input: this.noteTypeInput, - valueAttribute: 'data-value', - }, - { - input: this.submitButton, - valueAttribute: 'data-submit-text', - }, - ], - }; - - if (this.closeButton) { - config.InputSetter.push( - { - input: this.closeButton, - valueAttribute: 'data-close-text', - }, - { - input: this.closeButton, - valueAttribute: 'data-close-text', - inputAttribute: 'data-alternative-text', - }, - ); - } - - if (this.reopenButton) { - config.InputSetter.push( - { - input: this.reopenButton, - valueAttribute: 'data-reopen-text', - }, - { - input: this.reopenButton, - valueAttribute: 'data-reopen-text', - inputAttribute: 'data-alternative-text', - }, - ); - } - - return config; - } -} - -export default CommentTypeToggle; diff --git a/app/assets/javascripts/deprecated_notes.js b/app/assets/javascripts/deprecated_notes.js index a42b50edb8a..4ab3f140b61 100644 --- a/app/assets/javascripts/deprecated_notes.js +++ b/app/assets/javascripts/deprecated_notes.js @@ -19,9 +19,10 @@ import Vue from 'vue'; import '~/lib/utils/jquery_at_who'; import AjaxCache from '~/lib/utils/ajax_cache'; import syntaxHighlight from '~/syntax_highlight'; +import CommentTypeDropdown from '~/notes/components/comment_type_dropdown.vue'; +import * as constants from '~/notes/constants'; import Autosave from './autosave'; import loadAwardsHandler from './awards_handler'; -import CommentTypeToggle from './comment_type_toggle'; import createFlash from './flash'; import { defaultAutocompleteConfig } from './gfm_auto_complete'; import GLForm from './gl_form'; @@ -128,7 +129,13 @@ export default class Notes { this.$wrapperEl.on('click', '.js-note-edit', this.showEditForm.bind(this)); this.$wrapperEl.on('click', '.note-edit-cancel', this.cancelEdit); // Reopen and close actions for Issue/MR combined with note form submit - this.$wrapperEl.on('click', '.js-comment-submit-button', this.postComment); + this.$wrapperEl.on( + 'click', + // this oddly written selector needs to match the old style (input with class) as + // well as the new DOM styling from the Vue-based note form + 'input.js-comment-submit-button, .js-comment-submit-button > button:first-child', + this.postComment, + ); this.$wrapperEl.on('click', '.js-comment-save-button', this.updateComment); this.$wrapperEl.on('keyup input', '.js-note-text', this.updateTargetButtons); // resolve a discussion @@ -201,23 +208,39 @@ export default class Notes { } static initCommentTypeToggle(form) { - const dropdownTrigger = form.querySelector('.js-comment-type-dropdown .dropdown-toggle'); - const dropdownList = form.querySelector('.js-comment-type-dropdown .dropdown-menu'); + const el = form.querySelector('.js-comment-type-dropdown'); + const { noteableName } = el.dataset; const noteTypeInput = form.querySelector('#note_type'); - const submitButton = form.querySelector('.js-comment-type-dropdown .js-comment-submit-button'); - const closeButton = form.querySelector('.js-note-target-close'); - const reopenButton = form.querySelector('.js-note-target-reopen'); - - const commentTypeToggle = new CommentTypeToggle({ - dropdownTrigger, - dropdownList, - noteTypeInput, - submitButton, - closeButton, - reopenButton, - }); + const formHasContent = form.querySelector('.js-note-text').value.trim().length > 0; - commentTypeToggle.initDroplab(); + form.commentTypeComponent = new Vue({ + el, + data() { + return { + noteType: constants.COMMENT, + disabled: !formHasContent, + }; + }, + render(createElement) { + return createElement(CommentTypeDropdown, { + props: { + noteType: this.noteType, + noteableDisplayName: noteableName, + disabled: this.disabled, + }, + on: { + change: (arg) => { + this.noteType = arg; + if (this.noteType === constants.DISCUSSION) { + noteTypeInput.value = constants.DISCUSSION_NOTE; + } else { + noteTypeInput.value = ''; + } + }, + }, + }); + }, + }); } keydownNoteText(e) { @@ -1107,6 +1130,7 @@ export default class Notes { const form = textarea.parents('form'); const reopenbtn = form.find('.js-note-target-reopen'); const closebtn = form.find('.js-note-target-close'); + const commentTypeComponent = form.get(0)?.commentTypeComponent; if (textarea.val().trim().length > 0) { reopentext = reopenbtn.attr('data-alternative-text'); @@ -1123,6 +1147,9 @@ export default class Notes { if (closebtn.is(':not(.btn-comment-and-close)')) { closebtn.addClass('btn-comment-and-close'); } + if (commentTypeComponent) { + commentTypeComponent.disabled = false; + } } else { reopentext = reopenbtn.data('originalText'); closetext = closebtn.data('originalText'); @@ -1138,6 +1165,9 @@ export default class Notes { if (closebtn.is('.btn-comment-and-close')) { closebtn.removeClass('btn-comment-and-close'); } + if (commentTypeComponent) { + commentTypeComponent.disabled = true; + } } } @@ -1308,9 +1338,6 @@ export default class Notes { } cleanForm($form) { - // Remove JS classes that are not needed here - $form.find('.js-comment-type-dropdown').removeClass('btn-group'); - // Remove dropdown $form.find('.dropdown-menu').remove(); @@ -1505,6 +1532,8 @@ export default class Notes { const $submitBtn = $(e.target); $submitBtn.prop('disabled', true); let $form = $submitBtn.parents('form'); + const commentTypeComponent = $form.get(0)?.commentTypeComponent; + if (commentTypeComponent) commentTypeComponent.disabled = true; const $closeBtn = $form.find('.js-note-target-close'); const isDiscussionNote = $submitBtn.parent().find('li.droplab-item-selected').attr('id') === 'discussion'; @@ -1584,6 +1613,8 @@ export default class Notes { const note = res.data; $submitBtn.prop('disabled', false); + if (commentTypeComponent) commentTypeComponent.disabled = false; + // Submission successful! remove placeholder $notesContainer.find(`#${noteUniqueId}`).remove(); @@ -1662,6 +1693,8 @@ export default class Notes { // Submission failed, remove placeholder note and show Flash error message $notesContainer.find(`#${noteUniqueId}`).remove(); $submitBtn.prop('disabled', false); + if (commentTypeComponent) commentTypeComponent.disabled = false; + const blurEvent = new CustomEvent('blur.imageDiff', { detail: e, }); diff --git a/app/assets/javascripts/notes/components/comment_type_dropdown.vue b/app/assets/javascripts/notes/components/comment_type_dropdown.vue index 663a912999d..30ea5d3532e 100644 --- a/app/assets/javascripts/notes/components/comment_type_dropdown.vue +++ b/app/assets/javascripts/notes/components/comment_type_dropdown.vue @@ -96,7 +96,11 @@ export default { data-track-action="click_button" @click="$emit('click')" > - <gl-dropdown-item is-check-item :is-checked="isNoteTypeComment" @click="setNoteTypeToComment"> + <gl-dropdown-item + is-check-item + :is-checked="isNoteTypeComment" + @click.stop.prevent="setNoteTypeToComment" + > <strong>{{ $options.i18n.submitButton.comment }}</strong> <p class="gl-m-0">{{ commentDescription }}</p> </gl-dropdown-item> @@ -105,7 +109,7 @@ export default { is-check-item :is-checked="isNoteTypeDiscussion" data-qa-selector="discussion_menu_item" - @click="setNoteTypeToDiscussion" + @click.stop.prevent="setNoteTypeToDiscussion" > <strong>{{ $options.i18n.submitButton.startThread }}</strong> <p class="gl-m-0">{{ startDiscussionDescription }}</p> diff --git a/app/assets/javascripts/notes/components/note_header.vue b/app/assets/javascripts/notes/components/note_header.vue index 4e686ce8719..0925195d4bb 100644 --- a/app/assets/javascripts/notes/components/note_header.vue +++ b/app/assets/javascripts/notes/components/note_header.vue @@ -1,10 +1,16 @@ <script> -import { GlIcon, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui'; +import { + GlIcon, + GlLoadingIcon, + GlTooltipDirective, + GlSafeHtmlDirective as SafeHtml, +} from '@gitlab/ui'; import { mapActions } from 'vuex'; import timeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import UserNameWithStatus from '../../sidebar/components/assignees/user_name_with_status.vue'; export default { + safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] }, components: { timeAgoTooltip, GitlabTeamMemberBadge: () => @@ -14,6 +20,7 @@ export default { UserNameWithStatus, }, directives: { + SafeHtml, GlTooltip: GlTooltipDirective, }, props: { @@ -165,10 +172,10 @@ export default { <span v-if="authorStatus" ref="authorStatus" + v-safe-html:[$options.safeHtmlConfig]="authorStatus" v-on=" authorStatusHasTooltip ? { mouseenter: removeEmojiTitle, mouseleave: addEmojiTitle } : {} " - v-html="authorStatus /* eslint-disable-line vue/no-v-html */" ></span> <span class="text-nowrap author-username"> <a |