diff options
Diffstat (limited to 'app/assets/javascripts/notes/components/comment_form.vue')
-rw-r--r-- | app/assets/javascripts/notes/components/comment_form.vue | 137 |
1 files changed, 31 insertions, 106 deletions
diff --git a/app/assets/javascripts/notes/components/comment_form.vue b/app/assets/javascripts/notes/components/comment_form.vue index 9cc53a320b8..0363173f912 100644 --- a/app/assets/javascripts/notes/components/comment_form.vue +++ b/app/assets/javascripts/notes/components/comment_form.vue @@ -3,23 +3,23 @@ import $ from 'jquery'; import { mapActions, mapGetters, mapState } from 'vuex'; import { isEmpty } from 'lodash'; import Autosize from 'autosize'; -import { GlAlert, GlIntersperse, GlLink, GlSprintf, GlButton, GlIcon } from '@gitlab/ui'; +import { GlButton, GlIcon } from '@gitlab/ui'; import { __, sprintf } from '~/locale'; import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue'; -import { deprecatedCreateFlash as Flash } from '../../flash'; -import Autosave from '../../autosave'; +import { deprecatedCreateFlash as Flash } from '~/flash'; +import Autosave from '~/autosave'; import { capitalizeFirstCharacter, convertToCamelCase, splitCamelCase, slugifyWithUnderscore, -} from '../../lib/utils/text_utility'; +} from '~/lib/utils/text_utility'; import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests'; import * as constants from '../constants'; import eventHub from '../event_hub'; -import NoteableWarning from '../../vue_shared/components/notes/noteable_warning.vue'; -import markdownField from '../../vue_shared/components/markdown/field.vue'; -import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue'; +import NoteableWarning from '~/vue_shared/components/notes/noteable_warning.vue'; +import markdownField from '~/vue_shared/components/markdown/field.vue'; +import userAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue'; import noteSignedOutWidget from './note_signed_out_widget.vue'; import discussionLockedWidget from './discussion_locked_widget.vue'; import issuableStateMixin from '../mixins/issuable_state'; @@ -34,10 +34,6 @@ export default { userAvatarLink, GlButton, TimelineEntryItem, - GlAlert, - GlIntersperse, - GlLink, - GlSprintf, GlIcon, }, mixins: [issuableStateMixin], @@ -63,9 +59,8 @@ export default { 'getNoteableDataByProp', 'getNotesData', 'openState', - 'getBlockedByIssues', ]), - ...mapState(['isToggleStateButtonLoading', 'isToggleBlockedIssueWarning']), + ...mapState(['isToggleStateButtonLoading']), noteableDisplayName() { return splitCamelCase(this.noteableType).toLowerCase(); }, @@ -143,7 +138,7 @@ export default { ? __('merge request') : __('issue'); }, - isIssueType() { + isIssue() { return this.noteableDisplayName === constants.ISSUE_NOTEABLE_TYPE; }, trackingLabel() { @@ -172,11 +167,9 @@ export default { 'stopPolling', 'restartPolling', 'removePlaceholderNotes', - 'closeIssue', - 'reopenIssue', + 'closeIssuable', + 'reopenIssuable', 'toggleIssueLocalState', - 'toggleStateButtonLoading', - 'toggleBlockedIssueWarning', ]), setIsSubmitButtonDisabled(note, isSubmitting) { if (!isEmpty(note) && !isSubmitting) { @@ -186,8 +179,6 @@ export default { } }, handleSave(withIssueAction) { - this.isSubmitting = true; - if (this.note.length) { const noteData = { endpoint: this.endpoint, @@ -210,9 +201,10 @@ export default { this.resizeTextarea(); this.stopPolling(); + this.isSubmitting = true; + this.saveNote(noteData) .then(() => { - this.enableButton(); this.restartPolling(); this.discard(); @@ -221,7 +213,6 @@ export default { } }) .catch(() => { - this.enableButton(); this.discard(false); const msg = __( 'Your comment could not be submitted! Please check your network connection and try again.', @@ -229,64 +220,27 @@ export default { Flash(msg, 'alert', this.$el); this.note = noteData.data.note.note; // Restore textarea content. this.removePlaceholderNotes(); + }) + .finally(() => { + this.isSubmitting = false; }); } else { this.toggleIssueState(); } }, - enableButton() { - this.isSubmitting = false; - }, toggleIssueState() { - if ( - this.noteableType.toLowerCase() === constants.ISSUE_NOTEABLE_TYPE && - this.isOpen && - this.getBlockedByIssues && - this.getBlockedByIssues.length > 0 - ) { - this.toggleBlockedIssueWarning(true); + if (this.isIssue) { + // We want to invoke the close/reopen logic in the issue header + // since that is where the blocked-by issues modal logic is also defined + eventHub.$emit('toggle.issuable.state'); return; } - if (this.isOpen) { - this.forceCloseIssue(); - } else { - this.reopenIssue() - .then(() => { - this.enableButton(); - refreshUserMergeRequestCounts(); - }) - .catch(({ data }) => { - this.enableButton(); - this.toggleStateButtonLoading(false); - let errorMessage = sprintf( - __('Something went wrong while reopening the %{issuable}. Please try again later'), - { issuable: this.noteableDisplayName }, - ); - if (data) { - errorMessage = Object.values(data).join('\n'); - } + const toggleState = this.isOpen ? this.closeIssuable : this.reopenIssuable; - Flash(errorMessage); - }); - } - }, - forceCloseIssue() { - this.closeIssue() - .then(() => { - this.enableButton(); - refreshUserMergeRequestCounts(); - }) - .catch(() => { - this.enableButton(); - this.toggleStateButtonLoading(false); - Flash( - sprintf( - __('Something went wrong while closing the %{issuable}. Please try again later'), - { issuable: this.noteableDisplayName }, - ), - ); - }); + toggleState() + .then(refreshUserMergeRequestCounts) + .catch(() => Flash(constants.toggleStateErrorMessage[this.noteableType][this.openState])); }, discard(shouldClear = true) { // `blur` is needed to clear slash commands autocomplete cache if event fired. @@ -384,6 +338,7 @@ export default { name="note[note]" class="note-textarea js-vue-comment-form js-note-text js-gfm-input js-autosize markdown-area" data-qa-selector="comment_field" + data-testid="comment-field" data-supports-quick-actions="true" :aria-label="__('Description')" :placeholder="__('Write a comment or drag your files hereā¦')" @@ -392,36 +347,7 @@ export default { @keydown.ctrl.enter="handleSave()" ></textarea> </markdown-field> - <gl-alert - v-if="isToggleBlockedIssueWarning" - class="gl-mt-5" - :title="__('Are you sure you want to close this blocked issue?')" - :primary-button-text="__('Yes, close issue')" - :secondary-button-text="__('Cancel')" - variant="warning" - :dismissible="false" - @primaryAction="toggleBlockedIssueWarning(false) && forceCloseIssue()" - @secondaryAction="toggleBlockedIssueWarning(false) && enableButton()" - > - <p> - <gl-sprintf - :message=" - __('This issue is currently blocked by the following issues: %{issues}.') - " - > - <template #issues> - <gl-intersperse> - <gl-link - v-for="blockingIssue in getBlockedByIssues" - :key="blockingIssue.web_url" - :href="blockingIssue.web_url" - >#{{ blockingIssue.iid }}</gl-link - > - </gl-intersperse> - </template> - </gl-sprintf> - </p> - </gl-alert> + <div class="note-form-actions"> <div class="btn-group gl-mr-3 comment-type-dropdown js-comment-type-dropdown droplab-dropdown" @@ -430,6 +356,7 @@ export default { :disabled="isSubmitButtonDisabled" class="js-comment-button js-comment-submit-button" data-qa-selector="comment_button" + data-testid="comment-button" type="submit" category="primary" variant="success" @@ -488,15 +415,13 @@ export default { </div> <gl-button - v-if="canToggleIssueState && !isToggleBlockedIssueWarning" + v-if="canToggleIssueState" :loading="isToggleStateButtonLoading" category="secondary" :variant="buttonVariant" - :class="[ - actionButtonClassNames, - 'btn-comment btn-comment-and-close js-action-button', - ]" - :disabled="isToggleStateButtonLoading || isSubmitting" + :class="[actionButtonClassNames, 'btn-comment btn-comment-and-close']" + :disabled="isSubmitting" + data-testid="close-reopen-button" @click="handleSave(true)" >{{ issueActionButtonTitle }}</gl-button > |