debian-mirror-gitlab/app/assets/javascripts/notes/components/note_form.vue

224 lines
6.3 KiB
Vue
Raw Normal View History

2018-03-17 18:26:18 +05:30
<script>
2018-05-09 12:01:36 +05:30
import { mapGetters, mapActions } from 'vuex';
import eventHub from '../event_hub';
import issueWarning from '../../vue_shared/components/issue/issue_warning.vue';
import markdownField from '../../vue_shared/components/markdown/field.vue';
import issuableStateMixin from '../mixins/issuable_state';
import resolvable from '../mixins/resolvable';
2018-03-17 18:26:18 +05:30
2018-05-09 12:01:36 +05:30
export default {
2018-11-18 11:00:15 +05:30
name: 'NoteForm',
2018-05-09 12:01:36 +05:30
components: {
issueWarning,
markdownField,
},
mixins: [issuableStateMixin, resolvable],
props: {
noteBody: {
type: String,
required: false,
default: '',
2018-03-17 18:26:18 +05:30
},
2018-05-09 12:01:36 +05:30
noteId: {
2018-12-05 23:21:45 +05:30
type: [String, Number],
2018-05-09 12:01:36 +05:30
required: false,
2018-11-20 20:47:30 +05:30
default: '',
2018-03-17 18:26:18 +05:30
},
2018-11-08 19:23:39 +05:30
markdownVersion: {
type: Number,
required: false,
default: 0,
},
2018-05-09 12:01:36 +05:30
saveButtonTitle: {
type: String,
required: false,
default: 'Save comment',
2018-03-17 18:26:18 +05:30
},
2018-11-08 19:23:39 +05:30
discussion: {
2018-05-09 12:01:36 +05:30
type: Object,
required: false,
default: () => ({}),
2018-03-17 18:26:18 +05:30
},
2018-05-09 12:01:36 +05:30
isEditing: {
type: Boolean,
required: true,
},
2018-11-08 19:23:39 +05:30
lineCode: {
type: String,
required: false,
default: '',
},
2018-05-09 12:01:36 +05:30
},
data() {
return {
updatedNoteBody: this.noteBody,
conflictWhileEditing: false,
isSubmitting: false,
2019-01-03 12:48:30 +05:30
isResolving: false,
2018-05-09 12:01:36 +05:30
resolveAsThread: true,
};
},
computed: {
...mapGetters([
'getDiscussionLastNote',
'getNoteableData',
'getNoteableDataByProp',
'getNotesDataByProp',
'getUserDataByProp',
]),
noteHash() {
2018-11-20 20:47:30 +05:30
if (this.noteId) {
return `#note_${this.noteId}`;
}
return '#';
2018-05-09 12:01:36 +05:30
},
markdownPreviewPath() {
2019-01-03 12:48:30 +05:30
return this.getNoteableDataByProp('preview_note_path');
2018-05-09 12:01:36 +05:30
},
markdownDocsPath() {
return this.getNotesDataByProp('markdownDocsPath');
},
quickActionsDocsPath() {
2018-11-08 19:23:39 +05:30
return !this.isEditing ? this.getNotesDataByProp('quickActionsDocsPath') : undefined;
2018-03-17 18:26:18 +05:30
},
2018-05-09 12:01:36 +05:30
currentUserId() {
return this.getUserDataByProp('id');
2018-03-17 18:26:18 +05:30
},
2018-05-09 12:01:36 +05:30
isDisabled() {
return !this.updatedNoteBody.length || this.isSubmitting;
},
},
watch: {
noteBody() {
if (this.updatedNoteBody === this.noteBody) {
this.updatedNoteBody = this.noteBody;
} else {
this.conflictWhileEditing = true;
}
},
},
mounted() {
this.$refs.textarea.focus();
},
methods: {
...mapActions(['toggleResolveNote']),
2018-12-05 23:21:45 +05:30
shouldToggleResolved(shouldResolve, beforeSubmitDiscussionState) {
// shouldBeResolved() checks the actual resolution state,
// considering batchComments (EEP), if applicable/enabled.
const newResolvedStateAfterUpdate =
this.shouldBeResolved && this.shouldBeResolved(shouldResolve);
const shouldToggleState =
newResolvedStateAfterUpdate !== undefined &&
beforeSubmitDiscussionState !== newResolvedStateAfterUpdate;
return shouldResolve || shouldToggleState;
},
2018-05-09 12:01:36 +05:30
handleUpdate(shouldResolve) {
const beforeSubmitDiscussionState = this.discussionResolved;
this.isSubmitting = true;
2018-03-17 18:26:18 +05:30
2018-11-08 19:23:39 +05:30
this.$emit('handleFormUpdate', this.updatedNoteBody, this.$refs.editNoteForm, () => {
this.isSubmitting = false;
2018-03-27 19:54:05 +05:30
2018-12-05 23:21:45 +05:30
if (this.shouldToggleResolved(shouldResolve, beforeSubmitDiscussionState)) {
2018-11-08 19:23:39 +05:30
this.resolveHandler(beforeSubmitDiscussionState);
}
});
2018-05-09 12:01:36 +05:30
},
editMyLastNote() {
if (this.updatedNoteBody === '') {
2018-11-08 19:23:39 +05:30
const lastNoteInDiscussion = this.getDiscussionLastNote(this.discussion);
2018-03-17 18:26:18 +05:30
2018-05-09 12:01:36 +05:30
if (lastNoteInDiscussion) {
eventHub.$emit('enterEditMode', {
noteId: lastNoteInDiscussion.id,
});
2018-03-17 18:26:18 +05:30
}
2018-05-09 12:01:36 +05:30
}
},
cancelHandler(shouldConfirm = false) {
// Sends information about confirm message and if the textarea has changed
2018-11-08 19:23:39 +05:30
this.$emit('cancelForm', shouldConfirm, this.noteBody !== this.updatedNoteBody);
2018-03-17 18:26:18 +05:30
},
2018-05-09 12:01:36 +05:30
},
};
2018-03-17 18:26:18 +05:30
</script>
<template>
2019-01-03 12:48:30 +05:30
<div
ref="editNoteForm"
class="note-edit-form current-note-edit-form js-discussion-note-form">
<div
v-if="conflictWhileEditing"
class="js-conflict-edit-warning alert alert-danger">
2018-03-17 18:26:18 +05:30
This comment has changed since you started editing, please review the
2019-01-03 12:48:30 +05:30
<a
:href="noteHash"
target="_blank"
rel="noopener noreferrer">
updated comment
</a>
to ensure information is not lost.
2018-03-17 18:26:18 +05:30
</div>
<div class="flash-container timeline-content"></div>
2019-01-03 12:48:30 +05:30
<form
:data-line-code="lineCode"
class="edit-note common-note-form js-quick-submit gfm-form"
>
2018-03-17 18:26:18 +05:30
<issue-warning
v-if="hasWarning(getNoteableData)"
:is-locked="isLocked(getNoteableData)"
:is-confidential="isConfidential(getNoteableData)"
/>
<markdown-field
:markdown-preview-path="markdownPreviewPath"
:markdown-docs-path="markdownDocsPath"
2018-11-08 19:23:39 +05:30
:markdown-version="markdownVersion"
2018-03-17 18:26:18 +05:30
:quick-actions-docs-path="quickActionsDocsPath"
2019-01-03 12:48:30 +05:30
:add-spacing-classes="false">
2018-03-17 18:26:18 +05:30
<textarea
id="note_note"
2018-11-08 19:23:39 +05:30
ref="textarea"
slot="textarea"
v-model="updatedNoteBody"
2018-12-05 23:21:45 +05:30
:data-supports-quick-actions="!isEditing"
2018-03-17 18:26:18 +05:30
name="note[note]"
2019-01-03 12:48:30 +05:30
class="note-textarea js-gfm-input js-note-text
js-autosize markdown-area js-vue-issue-note-form js-vue-textarea qa-reply-input"
2018-03-17 18:26:18 +05:30
aria-label="Description"
2018-11-08 19:23:39 +05:30
placeholder="Write a comment or drag your files here…"
2019-01-03 12:48:30 +05:30
@keydown.meta.enter="handleUpdate()"
@keydown.ctrl.enter="handleUpdate()"
@keydown.up="editMyLastNote()"
@keydown.esc="cancelHandler(true)">
</textarea>
2018-03-17 18:26:18 +05:30
</markdown-field>
<div class="note-form-actions clearfix">
<button
:disabled="isDisabled"
2018-11-08 19:23:39 +05:30
type="button"
2019-01-03 12:48:30 +05:30
class="js-vue-issue-save btn btn-success js-comment-button "
@click="handleUpdate()">
2018-03-17 18:26:18 +05:30
{{ saveButtonTitle }}
</button>
2018-03-27 19:54:05 +05:30
<button
2018-11-08 19:23:39 +05:30
v-if="discussion.resolvable"
2018-03-27 19:54:05 +05:30
class="btn btn-nr btn-default append-right-10 js-comment-resolve-button"
2019-01-03 12:48:30 +05:30
@click.prevent="handleUpdate(true)"
2018-03-27 19:54:05 +05:30
>
{{ resolveButtonTitle }}
</button>
2018-03-17 18:26:18 +05:30
<button
2018-11-08 19:23:39 +05:30
class="btn btn-cancel note-edit-cancel js-close-discussion-note-form"
type="button"
2019-01-03 12:48:30 +05:30
@click="cancelHandler()">
2018-03-17 18:26:18 +05:30
Cancel
</button>
</div>
</form>
</div>
</template>