issue_note_form.vue 4.5 KB
Newer Older
1
<script>
2
  import { mapGetters } from 'vuex';
3
  import eventHub from '../event_hub';
4 5
  import confidentialIssue from '../../vue_shared/components/issue/confidential_issue_warning.vue';
  import markdownField from '../../vue_shared/components/markdown/field.vue';
6

7
  export default {
8
    name: 'issueNoteForm',
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
    props: {
      noteBody: {
        type: String,
        required: false,
        default: '',
      },
      noteId: {
        type: Number,
        required: false,
      },
      saveButtonTitle: {
        type: String,
        required: false,
        default: 'Save comment',
      },
24
      discussion: {
25
        type: Object,
26
        required: false,
27
        default: () => ({}),
28 29 30 31 32
      },
      isEditing: {
        type: Boolean,
        required: true,
      },
33
    },
34 35 36 37
    data() {
      return {
        note: this.noteBody,
        conflictWhileEditing: false,
38
        isSubmitting: false,
39
      };
40
    },
41
    components: {
42
      confidentialIssue,
43
      markdownField,
44
    },
45
    computed: {
46 47
      ...mapGetters([
        'getDiscussionLastNote',
48 49 50
        'getIssueDataByProp',
        'getNotesDataByProp',
        'getUserDataByProp',
51
      ]),
52 53 54
      noteHash() {
        return `#note_${this.noteId}`;
      },
55 56 57 58 59 60 61
      markdownPreviewUrl() {
        return this.getIssueDataByProp('preview_note_path');
      },
      markdownDocsUrl() {
        return this.getNotesDataByProp('markdownDocs');
      },
      quickActionsDocsUrl() {
62
        return !this.isEditing ? this.getNotesDataByProp('quickActionsDocs') : undefined;
63 64 65
      },
      currentUserId() {
        return this.getUserDataByProp('id');
66 67 68 69
      },
      isDisabled() {
        return !this.note.length || this.isSubmitting;
      },
70 71 72
      isConfidentialIssue() {
        return this.getIssueDataByProp('confidential');
      },
73
    },
74 75
    methods: {
      handleUpdate() {
76
        this.isSubmitting = true;
77
        this.$emit('handleFormUpdate', this.note, this.$refs.editNoteForm);
78 79 80
      },
      editMyLastNote() {
        if (this.note === '') {
81
          const lastNoteInDiscussion = this.getDiscussionLastNote(this.discussion);
82

83
          if (lastNoteInDiscussion) {
84
            eventHub.$emit('enterEditMode', {
85
              noteId: lastNoteInDiscussion.id,
86 87
            });
          }
88
        }
89
      },
90 91
      cancelHandler(shouldConfirm = false) {
        // Sends information about confirm message and if the textarea has changed
92
        this.$emit('cancelFormEdition', shouldConfirm, this.noteBody !== this.note);
93
      },
94
    },
95 96 97 98 99
    mounted() {
      this.$refs.textarea.focus();
    },
    watch: {
      noteBody() {
100
        if (this.note === this.noteBody) {
101 102 103 104 105
          this.note = this.noteBody;
        } else {
          this.conflictWhileEditing = true;
        }
      },
106
    },
107
  };
108 109 110
</script>

<template>
111
  <div ref="editNoteForm" class="note-edit-form current-note-edit-form">
112 113 114 115 116 117 118 119 120 121
    <div
      v-if="conflictWhileEditing"
      class="js-conflict-edit-warning alert alert-danger">
      This comment has changed since you started editing, please review the
      <a
        :href="noteHash"
        target="_blank"
        rel="noopener noreferrer">updated comment</a>
        to ensure information is not lost.
    </div>
122
    <div class="flash-container timeline-content"></div>
123
    <form
124
      class="edit-note common-note-form">
125
      <confidentialIssue v-if="isConfidentialIssue" />
126 127 128
      <markdown-field
        :markdown-preview-url="markdownPreviewUrl"
        :markdown-docs="markdownDocsUrl"
129 130
        :quick-actions-docs="quickActionsDocsUrl"
        :add-spacing-classes="false">
131
        <textarea
F
Filipa Lacerda 已提交
132
          id="note_note"
F
Fatih Acet 已提交
133
          name="note[note]"
F
Filipa Lacerda 已提交
134
          class="note-textarea js-gfm-input js-autosize markdown-area js-vue-issue-note-form js-vue-textarea"
135
          :data-supports-quick-actions="!isEditing"
136 137 138 139 140
          aria-label="Description"
          v-model="note"
          ref="textarea"
          slot="textarea"
          placeholder="Write a comment or drag your files here..."
141 142
          @keydown.meta.enter="handleUpdate()"
          @keydown.up="editMyLastNote()"
143
          @keydown.esc="cancelHandler(true)">
144 145 146 147
        </textarea>
      </markdown-field>
      <div class="note-form-actions clearfix">
        <button
F
Filipa Lacerda 已提交
148
          type="submit"
149
          @click="handleUpdate()"
150
          :disabled="isDisabled"
151
          class="js-vue-issue-save btn btn-save">
152
          {{saveButtonTitle}}
153 154
        </button>
        <button
155
          @click="cancelHandler()"
156
          class="btn btn-cancel note-edit-cancel"
157 158 159 160 161 162 163
          type="button">
          Cancel
        </button>
      </div>
    </form>
  </div>
</template>