diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-19 17:16:28 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-19 17:16:28 +0300 |
commit | e4384360a16dd9a19d4d2d25d0ef1f2b862ed2a6 (patch) | |
tree | 2fcdfa7dcdb9db8f5208b2562f4b4e803d671243 /app/assets/javascripts/notes/components | |
parent | ffda4e7bcac36987f936b4ba515995a6698698f0 (diff) |
Add latest changes from gitlab-org/gitlab@16-2-stable-eev16.2.0-rc42
Diffstat (limited to 'app/assets/javascripts/notes/components')
14 files changed, 209 insertions, 153 deletions
diff --git a/app/assets/javascripts/notes/components/comment_field_layout.vue b/app/assets/javascripts/notes/components/comment_field_layout.vue index bde7d219e9f..cefcc1b0c98 100644 --- a/app/assets/javascripts/notes/components/comment_field_layout.vue +++ b/app/assets/javascripts/notes/components/comment_field_layout.vue @@ -66,9 +66,7 @@ export default { }; </script> <template> - <div - class="comment-warning-wrapper gl-border-solid gl-border-1 gl-rounded-lg gl-border-gray-100 gl-bg-white gl-overflow-hidden" - > + <div class="comment-warning-wrapper"> <div v-if="withAlertContainer" class="error-alert" @@ -76,7 +74,7 @@ export default { ></div> <noteable-warning v-if="hasWarning" - class="gl-py-4 gl-border-b-1 gl-border-b-solid gl-border-b-gray-100 gl-rounded-base gl-rounded-bottom-left-none gl-rounded-bottom-right-none" + class="gl-pt-4 gl-pb-5 gl-mb-n3 gl-rounded-lg gl-rounded-bottom-left-none gl-rounded-bottom-right-none" :is-locked="isLocked" :is-confidential="isConfidential" :noteable-type="noteableType" @@ -84,10 +82,20 @@ export default { :confidential-noteable-docs-path="noteableData.confidential_issues_docs_path" /> <slot></slot> - <attachments-warning v-if="showAttachmentWarning" /> + <attachments-warning + v-if="showAttachmentWarning" + :class="{ + 'gl-py-3': !showEmailParticipantsWarning, + 'gl-pt-4 gl-pb-3 gl-mt-n3': showEmailParticipantsWarning, + }" + /> <email-participants-warning v-if="showEmailParticipantsWarning" - class="gl-border-t-1 gl-border-t-solid gl-border-t-gray-100 gl-rounded-base gl-rounded-top-left-none! gl-rounded-top-right-none!" + class="gl-border-t-1 gl-rounded-lg gl-rounded-top-left-none! gl-rounded-top-right-none!" + :class="{ + 'gl-pt-4 gl-pb-3 gl-mt-n3': !showAttachmentWarning, + 'gl-py-3 gl-mt-1': showAttachmentWarning, + }" :emails="emailParticipants" /> </div> diff --git a/app/assets/javascripts/notes/components/comment_form.vue b/app/assets/javascripts/notes/components/comment_form.vue index cba0f960c00..c6d94a3b7b7 100644 --- a/app/assets/javascripts/notes/components/comment_form.vue +++ b/app/assets/javascripts/notes/components/comment_form.vue @@ -16,11 +16,12 @@ import { sprintf } from '~/locale'; import MarkdownEditor from '~/vue_shared/components/markdown/markdown_editor.vue'; import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; +import { trackSavedUsingEditor } from '~/vue_shared/components/markdown/tracking'; import * as constants from '../constants'; import eventHub from '../event_hub'; import { COMMENT_FORM } from '../i18n'; -import { getErrorMessages } from '../utils'; +import { createNoteErrorMessages } from '../utils'; import issuableStateMixin from '../mixins/issuable_state'; import CommentFieldLayout from './comment_field_layout.vue'; @@ -146,9 +147,6 @@ export default { markdownDocsPath() { return this.getNotesData.markdownDocsPath; }, - quickActionsDocsPath() { - return this.getNotesData.quickActionsDocsPath; - }, markdownPreviewPath() { return this.getNoteableData.preview_note_path; }, @@ -219,7 +217,7 @@ export default { 'toggleIssueLocalState', ]), handleSaveError({ data, status }) { - this.errors = getErrorMessages(data, status); + this.errors = createNoteErrorMessages(data, status); }, handleSaveDraft() { this.handleSave({ isDraft: true }); @@ -258,6 +256,11 @@ export default { this.isSubmitting = true; + trackSavedUsingEditor( + this.$refs.markdownEditor.isContentEditorActive, + `${this.noteableType}_${this.noteType}`, + ); + this.saveNote(noteData) .then(() => { this.restartPolling(); @@ -366,7 +369,6 @@ export default { :render-markdown-path="markdownPreviewPath" :markdown-docs-path="markdownDocsPath" :add-spacing-classes="false" - :quick-actions-docs-path="quickActionsDocsPath" :form-field-props="formFieldProps" :autosave-key="autosaveKey" :disabled="isSubmitting" diff --git a/app/assets/javascripts/notes/components/comment_type_dropdown.vue b/app/assets/javascripts/notes/components/comment_type_dropdown.vue index 543be838920..2e4f925194f 100644 --- a/app/assets/javascripts/notes/components/comment_type_dropdown.vue +++ b/app/assets/javascripts/notes/components/comment_type_dropdown.vue @@ -1,16 +1,20 @@ <script> -import { GlDropdown, GlDropdownItem, GlDropdownDivider } from '@gitlab/ui'; +import { GlButtonGroup, GlButton, GlCollapsibleListbox } from '@gitlab/ui'; -import { sprintf } from '~/locale'; +import { sprintf, __ } from '~/locale'; import { COMMENT_FORM } from '~/notes/i18n'; import * as constants from '../constants'; export default { - i18n: COMMENT_FORM, + name: 'CommentTypeDropdown', + i18n: { + ...COMMENT_FORM, + toggleSrText: __('Comment type'), + }, components: { - GlDropdown, - GlDropdownItem, - GlDropdownDivider, + GlButtonGroup, + GlButton, + GlCollapsibleListbox, }, model: { prop: 'noteType', @@ -93,56 +97,63 @@ export default { noteableDisplayName: this.noteableDisplayName, }); }, + dropdownItems() { + return [ + { + text: this.dropdownCommentButtonTitle, + description: this.commentDescription, + value: constants.COMMENT, + }, + { + text: this.dropdownStartThreadButtonTitle, + description: this.startDiscussionDescription, + value: constants.DISCUSSION, + qaSelector: 'discussion_menu_item', + }, + ]; + }, }, methods: { handleClick() { this.$emit('click'); }, - setNoteTypeToComment() { - if (this.noteType !== constants.COMMENT) { - this.$emit('change', constants.COMMENT); - } - }, - setNoteTypeToDiscussion() { - if (this.noteType !== constants.DISCUSSION) { - this.$emit('change', constants.DISCUSSION); - } + setNoteType(value) { + this.$emit('change', value); }, }, }; </script> <template> - <gl-dropdown - split - :text="commentButtonTitle" - class="gl-mr-3 js-comment-button js-comment-submit-button comment-type-dropdown" - category="primary" - variant="confirm" - :disabled="disabled" - data-testid="comment-button" - data-qa-selector="comment_button" + <!--TODO: Replace button-group workaround once `split` option for new dropdowns is implemented.--> + <!-- See issue at https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2263--> + <gl-button-group + class="js-comment-button js-comment-submit-button comment-type-dropdown gl-w-full gl-mb-3 gl-md-w-auto gl-md-mb-0" :data-track-label="trackingLabel" data-track-action="click_button" - @click="$emit('click')" + data-testid="comment-button" + data-qa-selector="comment_button" > - <gl-dropdown-item - is-check-item - :is-checked="isNoteTypeComment" - @click.stop.prevent="setNoteTypeToComment" - > - <strong>{{ dropdownCommentButtonTitle }}</strong> - <p class="gl-m-0">{{ commentDescription }}</p> - </gl-dropdown-item> - <gl-dropdown-divider /> - <gl-dropdown-item - is-check-item - :is-checked="isNoteTypeDiscussion" - data-qa-selector="discussion_menu_item" - @click.stop.prevent="setNoteTypeToDiscussion" + <gl-button variant="confirm" :disabled="disabled" @click="handleClick"> + {{ commentButtonTitle }} + </gl-button> + <gl-collapsible-listbox + class="split" + toggle-class="gl-rounded-top-left-none! gl-rounded-bottom-left-none! gl-pl-1!" + variant="confirm" + text-sr-only + :toggle-text="$options.i18n.toggleSrText" + :disabled="disabled" + :items="dropdownItems" + :selected="noteType" + @select="setNoteType" > - <strong>{{ dropdownStartThreadButtonTitle }}</strong> - <p class="gl-m-0">{{ startDiscussionDescription }}</p> - </gl-dropdown-item> - </gl-dropdown> + <template #list-item="{ item }"> + <div :data-qa-selector="item.qaSelector"> + <strong>{{ item.text }}</strong> + <p class="gl-m-0">{{ item.description }}</p> + </div> + </template> + </gl-collapsible-listbox> + </gl-button-group> </template> diff --git a/app/assets/javascripts/notes/components/diff_discussion_header.vue b/app/assets/javascripts/notes/components/diff_discussion_header.vue index c53d3203327..e7b7ba7743e 100644 --- a/app/assets/javascripts/notes/components/diff_discussion_header.vue +++ b/app/assets/javascripts/notes/components/diff_discussion_header.vue @@ -107,7 +107,13 @@ export default { <template> <div class="discussion-header gl-display-flex gl-align-items-center"> <div v-once class="timeline-avatar gl-align-self-start gl-flex-shrink-0 gl-flex-shrink"> - <gl-avatar-link v-if="author" :href="author.path"> + <gl-avatar-link + v-if="author" + :href="author.path" + :data-user-id="author.id" + :data-username="author.username" + class="js-user-link" + > <gl-avatar :src="author.avatar_url" :alt="author.name" :size="32" /> </gl-avatar-link> </div> diff --git a/app/assets/javascripts/notes/components/discussion_counter.vue b/app/assets/javascripts/notes/components/discussion_counter.vue index ba5ffc60917..cff1043c258 100644 --- a/app/assets/javascripts/notes/components/discussion_counter.vue +++ b/app/assets/javascripts/notes/components/discussion_counter.vue @@ -1,13 +1,6 @@ <script> -import { - GlTooltipDirective, - GlButton, - GlButtonGroup, - GlDropdown, - GlDropdownItem, - GlIcon, -} from '@gitlab/ui'; -import { mapGetters, mapActions } from 'vuex'; +import { GlButton, GlButtonGroup, GlDisclosureDropdown, GlTooltipDirective } from '@gitlab/ui'; +import { mapActions, mapGetters } from 'vuex'; import { throttle } from 'lodash'; import { __ } from '~/locale'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; @@ -18,11 +11,9 @@ export default { GlTooltip: GlTooltipDirective, }, components: { + GlDisclosureDropdown, GlButton, GlButtonGroup, - GlDropdown, - GlDropdownItem, - GlIcon, }, mixins: [glFeatureFlagsMixin(), discussionNavigation], props: { @@ -56,6 +47,29 @@ export default { resolveAllDiscussionsIssuePath() { return this.getNoteableData.create_issue_to_resolve_discussions_path; }, + threadOptions() { + const options = [ + { + text: this.toggleThreadsLabel, + action: this.handleExpandDiscussions, + extraAttrs: { + 'data-testid': 'toggle-all-discussions-btn', + }, + }, + ]; + + if (this.resolveAllDiscussionsIssuePath && !this.allResolved) { + options.push({ + text: __('Resolve all with new issue'), + href: this.resolveAllDiscussionsIssuePath, + extraAttrs: { + 'data-testid': 'resolve-all-with-issue-link', + }, + }); + } + + return options; + }, }, methods: { ...mapActions(['setExpandDiscussions']), @@ -86,32 +100,25 @@ export default { > <template v-if="allResolved"> {{ __('All threads resolved!') }} - <gl-dropdown - v-gl-tooltip:discussionCounter.hover.bottom + <gl-disclosure-dropdown + v-gl-tooltip:discussionCounter.hover.top + icon="ellipsis_v" size="small" category="tertiary" - right + placement="right" + no-caret :title="__('Thread options')" :aria-label="__('Thread options')" toggle-class="btn-icon" class="gl-pt-0! gl-px-2 gl-h-full gl-ml-2" - > - <template #button-content> - <gl-icon name="ellipsis_v" class="mr-0" /> - </template> - <gl-dropdown-item - data-testid="toggle-all-discussions-btn" - @click="handleExpandDiscussions" - > - {{ toggleThreadsLabel }} - </gl-dropdown-item> - </gl-dropdown> + :items="threadOptions" + /> </template> <template v-else> {{ n__('%d unresolved thread', '%d unresolved threads', unresolvedDiscussionsCount) }} <gl-button-group class="gl-ml-3"> <gl-button - v-gl-tooltip:discussionCounter.hover.bottom + v-gl-tooltip:discussionCounter.hover.top :title="__('Go to previous unresolved thread')" :aria-label="__('Go to previous unresolved thread')" class="discussion-previous-btn gl-rounded-base! gl-px-2!" @@ -123,7 +130,7 @@ export default { @click="jumpPrevious" /> <gl-button - v-gl-tooltip:discussionCounter.hover.bottom + v-gl-tooltip:discussionCounter.hover.top :title="__('Go to next unresolved thread')" :aria-label="__('Go to next unresolved thread')" class="discussion-next-btn gl-rounded-base! gl-px-2!" @@ -134,32 +141,19 @@ export default { category="tertiary" @click="jumpNext" /> - <gl-dropdown - v-gl-tooltip:discussionCounter.hover.bottom + <gl-disclosure-dropdown + v-gl-tooltip:discussionCounter.hover.top + icon="ellipsis_v" size="small" category="tertiary" - right + placement="right" + no-caret :title="__('Thread options')" :aria-label="__('Thread options')" toggle-class="btn-icon" class="gl-pt-0! gl-px-2" - > - <template #button-content> - <gl-icon name="ellipsis_v" class="mr-0" /> - </template> - <gl-dropdown-item - data-testid="toggle-all-discussions-btn" - @click="handleExpandDiscussions" - > - {{ toggleThreadsLabel }} - </gl-dropdown-item> - <gl-dropdown-item - v-if="resolveAllDiscussionsIssuePath && !allResolved" - :href="resolveAllDiscussionsIssuePath" - > - {{ __('Resolve all with new issue') }} - </gl-dropdown-item> - </gl-dropdown> + :items="threadOptions" + /> </gl-button-group> </template> </div> diff --git a/app/assets/javascripts/notes/components/discussion_notes.vue b/app/assets/javascripts/notes/components/discussion_notes.vue index 9fb027fb955..080787884c8 100644 --- a/app/assets/javascripts/notes/components/discussion_notes.vue +++ b/app/assets/javascripts/notes/components/discussion_notes.vue @@ -169,7 +169,6 @@ export default { v-if="hasReplies" :collapsed="!isExpanded" :replies="replies" - :class="{ 'discussion-toggle-replies': discussion.diff_discussion }" @toggle="toggleDiscussion({ discussionId: discussion.id })" /> <template v-if="isExpanded"> diff --git a/app/assets/javascripts/notes/components/discussion_notes_replies_wrapper.vue b/app/assets/javascripts/notes/components/discussion_notes_replies_wrapper.vue index 1dd07fe90d2..571928b972b 100644 --- a/app/assets/javascripts/notes/components/discussion_notes_replies_wrapper.vue +++ b/app/assets/javascripts/notes/components/discussion_notes_replies_wrapper.vue @@ -21,7 +21,7 @@ export default { 'li', { class: - 'discussion-collapsible gl-border-solid gl-border-gray-100 gl-border-1 gl-rounded-base clearfix', + 'discussion-collapsible gl-border-solid gl-border-gray-100 gl-border-1 gl-rounded-base gl-border-top-0', }, [h('ul', { class: 'notes' }, children)], ); diff --git a/app/assets/javascripts/notes/components/mr_discussion_filter.vue b/app/assets/javascripts/notes/components/mr_discussion_filter.vue index 2338c9eef67..7ca0c4730a9 100644 --- a/app/assets/javascripts/notes/components/mr_discussion_filter.vue +++ b/app/assets/javascripts/notes/components/mr_discussion_filter.vue @@ -62,6 +62,12 @@ export default { this.updateMergeRequestFilters(filters); this.selectedFilters = filters; }, + deselectAll() { + this.selectedFilters = []; + }, + selectAll() { + this.selectedFilters = MR_FILTER_OPTIONS.map((f) => f.value); + }, }, MR_FILTER_OPTIONS, }; @@ -84,9 +90,14 @@ export default { <gl-collapsible-listbox v-model="selectedFilters" :items="$options.MR_FILTER_OPTIONS" + :header-text="__('Filter activity')" + :show-select-all-button-label="__('Select all')" + :reset-button-label="__('Deselect all')" multiple placement="right" @hidden="applyFilters" + @reset="deselectAll" + @select-all="selectAll" > <template #toggle> <gl-button class="gl-rounded-top-right-none! gl-rounded-bottom-right-none!"> diff --git a/app/assets/javascripts/notes/components/note_actions.vue b/app/assets/javascripts/notes/components/note_actions.vue index 47e0ace1ea7..8d2d8095a44 100644 --- a/app/assets/javascripts/notes/components/note_actions.vue +++ b/app/assets/javascripts/notes/components/note_actions.vue @@ -1,7 +1,6 @@ <script> import { GlTooltipDirective, - GlIcon, GlButton, GlDisclosureDropdown, GlDisclosureDropdownItem, @@ -30,15 +29,14 @@ export default { }, name: 'NoteActions', components: { - GlIcon, - ReplyButton, - TimelineEventButton, + AbuseCategorySelector, + EmojiPicker: () => import('~/emoji/components/picker.vue'), GlButton, GlDisclosureDropdown, GlDisclosureDropdownItem, + ReplyButton, + TimelineEventButton, UserAccessRoleBadge, - EmojiPicker: () => import('~/emoji/components/picker.vue'), - AbuseCategorySelector, }, directives: { GlTooltip: GlTooltipDirective, @@ -318,22 +316,12 @@ export default { /> <emoji-picker v-if="canAwardEmoji" + v-gl-tooltip + :title="$options.i18n.addReactionLabel" toggle-class="note-action-button note-emoji-button btn-icon btn-default-tertiary" data-testid="note-emoji-button" @click="setAwardEmoji" - > - <template #button-content> - <gl-icon class="award-control-icon-neutral gl-button-icon gl-icon" name="slight-smile" /> - <gl-icon - class="award-control-icon-positive gl-button-icon gl-icon gl-left-3!" - name="smiley" - /> - <gl-icon - class="award-control-icon-super-positive gl-button-icon gl-icon gl-left-3!" - name="smile" - /> - </template> - </emoji-picker> + /> <reply-button v-if="showReply" ref="replyButton" @@ -365,7 +353,8 @@ export default { <gl-disclosure-dropdown v-gl-tooltip :title="$options.i18n.moreActionsLabel" - :aria-label="$options.i18n.moreActionsLabel" + :toggle-text="$options.i18n.moreActionsLabel" + text-sr-only icon="ellipsis_v" category="tertiary" placement="right" diff --git a/app/assets/javascripts/notes/components/note_body.vue b/app/assets/javascripts/notes/components/note_body.vue index b4e5129ca0e..1c6be0cfd77 100644 --- a/app/assets/javascripts/notes/components/note_body.vue +++ b/app/assets/javascripts/notes/components/note_body.vue @@ -174,6 +174,7 @@ export default { :note-id="note.id" :line="line" :note="note" + :diff-file="file" :save-button-title="saveButtonTitle" :help-page-path="helpPagePath" :discussion="discussion" diff --git a/app/assets/javascripts/notes/components/note_form.vue b/app/assets/javascripts/notes/components/note_form.vue index fe7967f1ed0..4e816038539 100644 --- a/app/assets/javascripts/notes/components/note_form.vue +++ b/app/assets/javascripts/notes/components/note_form.vue @@ -5,6 +5,7 @@ import { mergeUrlParams } from '~/lib/utils/url_utility'; import { __ } from '~/locale'; import MarkdownEditor from '~/vue_shared/components/markdown/markdown_editor.vue'; import glFeaturesFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; +import { trackSavedUsingEditor } from '~/vue_shared/components/markdown/tracking'; import eventHub from '../event_hub'; import issuableStateMixin from '../mixins/issuable_state'; import resolvable from '../mixins/resolvable'; @@ -192,9 +193,6 @@ export default { markdownDocsPath() { return this.getNotesDataByProp('markdownDocsPath'); }, - quickActionsDocsPath() { - return this.getNotesDataByProp('quickActionsDocsPath'); - }, currentUserId() { return this.getUserDataByProp('id'); }, @@ -223,6 +221,15 @@ export default { enableContentEditor() { return Boolean(this.glFeatures.contentEditorOnIssues); }, + codeSuggestionsConfig() { + return { + canSuggest: this.canSuggest, + line: this.line, + lines: this.lines, + showPopover: this.showSuggestPopover, + diffFile: this.diffFile, + }; + }, }, watch: { noteBody() { @@ -290,6 +297,11 @@ export default { const beforeSubmitDiscussionState = this.discussionResolved; this.isSubmitting = true; + trackSavedUsingEditor( + this.$refs.markdownEditor.isContentEditorActive, + `${this.getNoteableData.noteableType}_note`, + ); + this.$emit( 'handleFormUpdate', this.updatedNoteBody, @@ -321,7 +333,15 @@ export default { (!this.discussionResolved && this.isResolving); this.isSubmitting = true; - this.$emit('handleFormUpdateAddToReview', this.updatedNoteBody, shouldResolve); + this.$emit( + 'handleFormUpdateAddToReview', + this.updatedNoteBody, + shouldResolve, + this.$refs.editNoteForm, + () => { + this.isSubmitting = false; + }, + ); }, hasEmailParticipants() { return this.getNoteableData.issue_email_participants?.length; @@ -351,15 +371,11 @@ export default { :value="updatedNoteBody" :render-markdown-path="markdownPreviewPath" :markdown-docs-path="markdownDocsPath" - :line="line" - :lines="lines" - :can-suggest="canSuggest" + :code-suggestions-config="codeSuggestionsConfig" :add-spacing-classes="false" :help-page-path="helpPagePath" :note="discussionNote" :form-field-props="formFieldProps" - :show-suggest-popover="showSuggestPopover" - :quick-actions-docs-path="quickActionsDocsPath" :autosave-key="autosaveKey" :autocomplete-data-sources="autocompleteDataSources" :disabled="isSubmitting" diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue index 499581653ba..a5939e1023c 100644 --- a/app/assets/javascripts/notes/components/noteable_discussion.vue +++ b/app/assets/javascripts/notes/components/noteable_discussion.vue @@ -15,7 +15,7 @@ import { containsSensitiveToken, confirmSensitiveAction } from '~/lib/utils/secr import eventHub from '../event_hub'; import noteable from '../mixins/noteable'; import resolvable from '../mixins/resolvable'; -import { getErrorMessages } from '../utils'; +import { createNoteErrorMessages } from '../utils'; import DiffDiscussionHeader from './diff_discussion_header.vue'; import DiffWithNote from './diff_with_note.vue'; import DiscussionActions from './discussion_actions.vue'; @@ -96,6 +96,18 @@ export default { 'showJumpToNextDiscussion', 'getUserData', ]), + diffFile() { + const diffFile = this.discussion.diff_file; + if (!diffFile) return null; + + return { + ...diffFile, + view_path: window.location.href.replace( + /\/-\/merge_requests.*/, + `/-/blob/${diffFile.content_sha}/${diffFile.new_path}`, + ), + }; + }, currentUser() { return this.getUserData; }, @@ -270,7 +282,7 @@ export default { }); }, handleSaveError({ response }) { - const errorMessage = getErrorMessages(response.data, response.status)[0]; + const errorMessage = createNoteErrorMessages(response.data, response.status)[0]; createAlert({ message: errorMessage, @@ -331,7 +343,7 @@ export default { <li v-else-if="canShowReplyActions && showReplies" data-testid="reply-wrapper" - class="discussion-reply-holder gl-border-t-0! clearfix" + class="discussion-reply-holder gl-border-t-0! gl-pb-5! clearfix" :class="discussionHolderClass" > <discussion-actions @@ -348,6 +360,7 @@ export default { v-if="isReplying" ref="noteForm" :discussion="discussion" + :diff-file="diffFile" :line="diffLine" :save-button-title="saveButtonTitle" :autosave-key="autosaveKey" diff --git a/app/assets/javascripts/notes/components/noteable_note.vue b/app/assets/javascripts/notes/components/noteable_note.vue index dd135eaee3b..69c41af97ab 100644 --- a/app/assets/javascripts/notes/components/noteable_note.vue +++ b/app/assets/javascripts/notes/components/noteable_note.vue @@ -17,8 +17,7 @@ import { containsSensitiveToken, confirmSensitiveAction } from '~/lib/utils/secr import eventHub from '../event_hub'; import noteable from '../mixins/noteable'; import resolvable from '../mixins/resolvable'; -import { renderMarkdown } from '../utils'; -import { UPDATE_COMMENT_FORM } from '../i18n'; +import { renderMarkdown, updateNoteErrorMessage } from '../utils'; import { getStartLineNumber, getEndLineNumber, @@ -114,7 +113,6 @@ export default { isResolving: false, commentLineStart: {}, resolveAsThread: true, - oldContent: this.note.note_html, }; }, computed: { @@ -212,7 +210,8 @@ export default { return fileResolvedFromAvailableSource || null; }, isMRDiffView() { - return this.line && !this.isOverviewTab; + const isFileComment = this.note.position?.position_type === 'file'; + return !this.isOverviewTab && (this.line || isFileComment); }, }, created() { @@ -295,7 +294,7 @@ export default { updateSuccess() { this.isEditing = false; this.isRequesting = false; - this.oldContent = this.note.note_html; + this.oldContent = null; renderGFM(this.$refs.noteBody.$el); this.$emit('updateSuccess'); }, @@ -317,7 +316,9 @@ export default { noteText, resolveDiscussion, position, + flashContainer: this.$el, callback: () => this.updateSuccess(), + errorCallback: () => callback(), }); if (this.isDraft) return; @@ -343,6 +344,7 @@ export default { // https://gitlab.com/gitlab-org/gitlab/-/issues/298827 if (!isEmpty(position)) data.note.note.position = JSON.stringify(position); this.isRequesting = true; + this.oldContent = this.note.note_html; // eslint-disable-next-line vue/no-mutating-props this.note.note_html = renderMarkdown(noteText); @@ -369,14 +371,8 @@ export default { }); }, handleUpdateError(e) { - const serverErrorMessage = e?.response?.data?.errors; - - const alertMessage = serverErrorMessage - ? sprintf(UPDATE_COMMENT_FORM.error, { reason: serverErrorMessage.toLowerCase() }, false) - : UPDATE_COMMENT_FORM.defaultError; - createAlert({ - message: alertMessage, + message: updateNoteErrorMessage(e), parent: this.$el, }); }, @@ -442,7 +438,12 @@ export default { </div> <div v-if="isMRDiffView" class="timeline-avatar gl-float-left gl-pt-2"> - <gl-avatar-link :href="author.path"> + <gl-avatar-link + :href="author.path" + :data-user-id="author.id" + :data-username="author.username" + class="js-user-link" + > <gl-avatar :src="author.avatar_url" :entity-name="author.username" @@ -455,7 +456,12 @@ export default { </div> <div v-else class="timeline-avatar gl-float-left"> - <gl-avatar-link :href="author.path"> + <gl-avatar-link + :href="author.path" + :data-user-id="author.id" + :data-username="author.username" + class="js-user-link" + > <gl-avatar :src="author.avatar_url" :entity-name="author.username" diff --git a/app/assets/javascripts/notes/components/toggle_replies_widget.vue b/app/assets/javascripts/notes/components/toggle_replies_widget.vue index b0f7a4a4732..a012b4411bc 100644 --- a/app/assets/javascripts/notes/components/toggle_replies_widget.vue +++ b/app/assets/javascripts/notes/components/toggle_replies_widget.vue @@ -39,7 +39,7 @@ export default { }, liClasses() { return this.collapsed - ? 'gl-text-gray-500 gl-rounded-bottom-left-base! gl-rounded-bottom-right-base! replies-widget-collapsed' + ? 'gl-text-gray-500 gl-rounded-bottom-left-base! gl-rounded-bottom-right-base!' : 'gl-border-b'; }, buttonIcon() { |