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:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-10-05 21:13:27 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-10-05 21:13:27 +0300
commitad41744a177d11ead3268b1ec706e9c26f593060 (patch)
tree3c06d26fa5577a484e6c096a2b6b28ee14461b23 /app/assets
parenta84626f13d61d190b2db5e44caf71b22fc541276 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/access_tokens/index.js2
-rw-r--r--app/assets/javascripts/comment_type_toggle.js71
-rw-r--r--app/assets/javascripts/deprecated_notes.js73
-rw-r--r--app/assets/javascripts/notes/components/comment_type_dropdown.vue8
-rw-r--r--app/assets/javascripts/notes/components/note_header.vue11
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