<script> /* global Flash */ import { mapGetters, mapActions } from 'vuex'; import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue'; import issueNoteHeader from './issue_note_header.vue'; import issueNoteActions from './issue_note_actions.vue'; import issueNoteBody from './issue_note_body.vue'; import eventHub from '../event_hub'; export default { props: { note: { type: Object, required: true, }, }, data() { return { isEditing: false, isDeleting: false, currentUserId: window.gon.current_user_id, }; }, components: { userAvatarLink, issueNoteHeader, issueNoteActions, issueNoteBody, }, computed: { ...mapGetters([ 'targetNoteHash', ]), author() { return this.note.author; }, classNameBindings() { return { 'is-editing': this.isEditing, 'disabled-content': this.isDeleting, target: this.targetNoteHash === this.noteAnchorId, }; }, canReportAsAbuse() { return this.note.report_abuse_path && this.author.id !== this.currentUserId; }, noteAnchorId() { return `note_${this.note.id}`; }, }, methods: { ...mapActions([ 'deleteNote', 'updateNote', 'scrollToNoteIfNeeded', ]), editHandler() { this.isEditing = true; }, deleteHandler() { // eslint-disable-next-line no-alert const isConfirmed = confirm('Are you sure you want to delete this list?'); if (isConfirmed) { this.isDeleting = true; this.deleteNote(this.note) .then(() => { this.isDeleting = false; }) .catch(() => { Flash('Something went wrong while deleting your note. Please try again.'); this.isDeleting = false; }); } }, formUpdateHandler(noteText, parentElement) { const data = { endpoint: this.note.path, note: { full_data: true, target_type: 'issue', target_id: this.note.noteable_id, note: { note: noteText }, }, }; this.updateNote(data) .then(() => { this.isEditing = false; // TODO: this could be moved down, by setting a prop $(this.$refs.noteBody.$el).renderGFM(); }) .catch(() => Flash( 'Something went wrong while editing your comment. Please try again.', 'alert', $(parentElement), )); }, formCancelHandler(shouldConfirm, isDirty) { if (shouldConfirm && isDirty) { // eslint-disable-next-line no-alert if (!confirm('Are you sure you want to cancel editing this comment?')) return; } this.isEditing = false; }, }, created() { eventHub.$on('enterEditMode', ({ noteId }) => { if (noteId === this.note.id) { this.isEditing = true; this.scrollToNoteIfNeeded($(this.$el)); } }); }, }; </script> <template> <li class="note timeline-entry" :id="noteAnchorId" :class="classNameBindings" :data-award-url="note.toggle_award_path"> <div class="timeline-entry-inner"> <div class="timeline-icon"> <user-avatar-link :link-href="author.path" :img-src="author.avatar_url" :img-alt="author.name" :img-size="40" /> </div> <div class="timeline-content"> <div class="note-header"> <issue-note-header :author="author" :created-at="note.created_at" :note-id="note.id" action-text="commented" /> <issue-note-actions :author-id="author.id" :note-id="note.id" :access-level="note.human_access" :can-edit="note.current_user.can_edit" :can-delete="note.current_user.can_edit" :can-report-as-abuse="canReportAsAbuse" :report-abuse-path="note.report_abuse_path" :edit-handler="editHandler" :delete-handler="deleteHandler" /> </div> <issue-note-body :note="note" :can-edit="note.current_user.can_edit" :is-editing="isEditing" @handleFormUpdate="formUpdateHandler" @cancelFormEdition="formCancelHandler" ref="noteBody" /> </div> </div> </li> </template>