2017-06-13 13:01:59 -04:00
|
|
|
<script>
|
2017-08-03 14:27:33 -04:00
|
|
|
/* global Flash, Autosave */
|
2017-08-02 12:19:06 -04:00
|
|
|
import { mapActions, mapGetters } from 'vuex';
|
2017-07-26 07:02:01 -04:00
|
|
|
import { SYSTEM_NOTE } from '../constants';
|
|
|
|
import issueNote from './issue_note.vue';
|
|
|
|
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 issueNoteSignedOutWidget from './issue_note_signed_out_widget.vue';
|
|
|
|
import issueNoteEditedText from './issue_note_edited_text.vue';
|
|
|
|
import issueNoteForm from './issue_note_form.vue';
|
|
|
|
import placeholderNote from './issue_placeholder_note.vue';
|
|
|
|
import placeholderSystemNote from './issue_placeholder_system_note.vue';
|
2017-08-04 06:46:55 -04:00
|
|
|
import autosave from '../mixins/autosave';
|
2017-06-20 20:50:44 -04:00
|
|
|
|
2017-07-26 07:02:01 -04:00
|
|
|
export default {
|
|
|
|
props: {
|
|
|
|
note: {
|
|
|
|
type: Object,
|
|
|
|
required: true,
|
|
|
|
},
|
2017-06-13 13:01:59 -04:00
|
|
|
},
|
2017-07-26 07:02:01 -04:00
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
isReplying: false,
|
|
|
|
};
|
2017-07-20 17:56:14 -04:00
|
|
|
},
|
2017-07-26 07:02:01 -04:00
|
|
|
components: {
|
|
|
|
issueNote,
|
|
|
|
userAvatarLink,
|
|
|
|
issueNoteHeader,
|
|
|
|
issueNoteActions,
|
|
|
|
issueNoteSignedOutWidget,
|
|
|
|
issueNoteEditedText,
|
|
|
|
issueNoteForm,
|
|
|
|
placeholderNote,
|
|
|
|
placeholderSystemNote,
|
2017-07-20 17:56:14 -04:00
|
|
|
},
|
2017-08-04 05:53:58 -04:00
|
|
|
mixins: [
|
|
|
|
autosave,
|
|
|
|
],
|
2017-07-26 07:02:01 -04:00
|
|
|
computed: {
|
2017-08-02 12:19:06 -04:00
|
|
|
...mapGetters([
|
|
|
|
'getIssueData',
|
|
|
|
]),
|
2017-07-26 07:02:01 -04:00
|
|
|
discussion() {
|
|
|
|
return this.note.notes[0];
|
|
|
|
},
|
|
|
|
author() {
|
|
|
|
return this.discussion.author;
|
|
|
|
},
|
|
|
|
canReply() {
|
2017-08-02 12:19:06 -04:00
|
|
|
return this.getIssueData.current_user.can_create_note;
|
2017-07-26 07:02:01 -04:00
|
|
|
},
|
2017-08-02 12:19:06 -04:00
|
|
|
newNotePath() {
|
|
|
|
return this.getIssueData.create_note_path;
|
2017-08-03 07:15:54 -04:00
|
|
|
},
|
2017-07-20 17:56:14 -04:00
|
|
|
},
|
2017-07-26 07:02:01 -04:00
|
|
|
methods: {
|
|
|
|
...mapActions([
|
|
|
|
'saveNote',
|
2017-08-02 11:22:38 -04:00
|
|
|
'toggleDiscussion',
|
2017-07-26 07:02:01 -04:00
|
|
|
]),
|
|
|
|
componentName(note) {
|
|
|
|
if (note.isPlaceholderNote) {
|
|
|
|
if (note.placeholderType === SYSTEM_NOTE) {
|
|
|
|
return placeholderSystemNote;
|
|
|
|
}
|
|
|
|
return placeholderNote;
|
2017-07-14 11:11:12 -04:00
|
|
|
}
|
|
|
|
|
2017-07-26 07:02:01 -04:00
|
|
|
return issueNote;
|
|
|
|
},
|
|
|
|
componentData(note) {
|
|
|
|
return note.isPlaceholderNote ? note.notes[0] : note;
|
|
|
|
},
|
2017-08-02 07:25:14 -04:00
|
|
|
toggleDiscussionHandler() {
|
2017-07-26 07:02:01 -04:00
|
|
|
this.toggleDiscussion({ discussionId: this.note.id });
|
|
|
|
},
|
|
|
|
showReplyForm() {
|
|
|
|
this.isReplying = true;
|
|
|
|
},
|
|
|
|
cancelReplyForm(shouldConfirm) {
|
|
|
|
if (shouldConfirm && this.$refs.noteForm.isDirty) {
|
|
|
|
// eslint-disable-next-line no-alert
|
2017-08-04 05:29:01 -04:00
|
|
|
if (!confirm('Are you sure you want to cancel creating this comment?')) {
|
2017-07-26 07:02:01 -04:00
|
|
|
return;
|
|
|
|
}
|
2017-07-03 18:31:11 -04:00
|
|
|
}
|
|
|
|
|
2017-08-04 05:53:58 -04:00
|
|
|
this.resetAutoSave();
|
2017-07-26 07:02:01 -04:00
|
|
|
this.isReplying = false;
|
|
|
|
},
|
2017-08-02 11:22:38 -04:00
|
|
|
saveReply(noteText) {
|
2017-07-26 07:02:01 -04:00
|
|
|
const replyData = {
|
|
|
|
endpoint: this.newNotePath,
|
|
|
|
flashContainer: this.$el,
|
|
|
|
data: {
|
|
|
|
in_reply_to_discussion_id: this.note.reply_id,
|
|
|
|
target_type: 'issue',
|
|
|
|
target_id: this.discussion.noteable_id,
|
2017-08-02 11:22:38 -04:00
|
|
|
note: { note: noteText },
|
2017-08-07 07:59:34 -04:00
|
|
|
view: 'full_data',
|
2017-07-26 07:02:01 -04:00
|
|
|
},
|
|
|
|
};
|
2017-06-20 20:40:36 -04:00
|
|
|
|
2017-07-26 07:02:01 -04:00
|
|
|
this.saveNote(replyData)
|
|
|
|
.then(() => {
|
|
|
|
this.isReplying = false;
|
2017-08-04 05:53:58 -04:00
|
|
|
this.resetAutoSave();
|
2017-07-26 07:02:01 -04:00
|
|
|
})
|
|
|
|
.catch(() => Flash('Something went wrong while adding your reply. Please try again.'));
|
|
|
|
},
|
2017-08-03 14:27:33 -04:00
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
if (this.isReplying) {
|
|
|
|
this.initAutoSave();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
updated() {
|
|
|
|
if (this.isReplying) {
|
2017-08-04 05:53:58 -04:00
|
|
|
if (!this.autosave) {
|
|
|
|
this.initAutoSave();
|
|
|
|
} else {
|
|
|
|
this.setAutoSave();
|
|
|
|
}
|
2017-08-03 14:27:33 -04:00
|
|
|
}
|
2017-06-20 17:45:59 -04:00
|
|
|
},
|
2017-07-26 07:02:01 -04:00
|
|
|
};
|
2017-06-13 13:01:59 -04:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
|
|
<li class="note note-discussion timeline-entry">
|
|
|
|
<div class="timeline-entry-inner">
|
|
|
|
<div class="timeline-icon">
|
|
|
|
<user-avatar-link
|
2017-07-20 18:12:44 -04:00
|
|
|
:link-href="author.path"
|
|
|
|
:img-src="author.avatar_url"
|
|
|
|
:img-alt="author.name"
|
2017-07-25 15:01:53 -04:00
|
|
|
:img-size="40"
|
|
|
|
/>
|
2017-06-13 13:01:59 -04:00
|
|
|
</div>
|
|
|
|
<div class="timeline-content">
|
|
|
|
<div class="discussion">
|
|
|
|
<div class="discussion-header">
|
|
|
|
<issue-note-header
|
|
|
|
:author="author"
|
2017-07-20 18:12:44 -04:00
|
|
|
:created-at="discussion.created_at"
|
|
|
|
:note-id="discussion.id"
|
|
|
|
:include-toggle="true"
|
2017-08-02 07:25:14 -04:00
|
|
|
:toggle-handler="toggleDiscussionHandler"
|
2017-07-26 11:26:03 -04:00
|
|
|
action-text="started a discussion"
|
2017-07-25 15:01:53 -04:00
|
|
|
/>
|
2017-06-13 13:01:59 -04:00
|
|
|
<issue-note-edited-text
|
|
|
|
v-if="note.last_updated_by"
|
2017-07-20 18:12:44 -04:00
|
|
|
:edited-at="note.last_updated_at"
|
|
|
|
:edited-by="note.last_updated_by"
|
2017-07-26 11:26:03 -04:00
|
|
|
action-text="Last updated"
|
2017-07-26 12:26:07 -04:00
|
|
|
class-name="discussion-headline-light js-discussion-headline"
|
|
|
|
/>
|
2017-06-13 13:01:59 -04:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div
|
|
|
|
v-if="note.expanded"
|
|
|
|
class="discussion-body">
|
|
|
|
<div class="panel panel-default">
|
|
|
|
<div class="discussion-notes">
|
|
|
|
<ul class="notes">
|
2017-07-14 11:11:12 -04:00
|
|
|
<component
|
2017-06-13 13:01:59 -04:00
|
|
|
v-for="note in note.notes"
|
2017-07-17 13:12:43 -04:00
|
|
|
:is="componentName(note)"
|
2017-07-14 11:11:12 -04:00
|
|
|
:note="componentData(note)"
|
2017-07-26 12:26:07 -04:00
|
|
|
:key="note.id"
|
2017-07-25 15:01:53 -04:00
|
|
|
/>
|
2017-06-13 13:01:59 -04:00
|
|
|
</ul>
|
|
|
|
<div class="flash-container"></div>
|
|
|
|
<div class="discussion-reply-holder">
|
|
|
|
<button
|
2017-06-28 16:53:46 -04:00
|
|
|
v-if="canReply && !isReplying"
|
2017-06-20 17:45:59 -04:00
|
|
|
@click="showReplyForm"
|
2017-06-13 13:01:59 -04:00
|
|
|
type="button"
|
2017-06-20 17:45:59 -04:00
|
|
|
class="btn btn-text-field"
|
2017-06-13 22:13:14 -04:00
|
|
|
title="Add a reply">Reply...</button>
|
2017-07-17 13:12:43 -04:00
|
|
|
<issue-note-form
|
|
|
|
v-if="isReplying"
|
|
|
|
saveButtonTitle="Comment"
|
2017-07-28 13:43:19 -04:00
|
|
|
:discussion="note"
|
2017-08-02 11:22:38 -04:00
|
|
|
:is-editing="false"
|
2017-07-28 13:43:19 -04:00
|
|
|
@handleFormUpdate="saveReply"
|
|
|
|
@cancelFormEdition="cancelReplyForm"
|
2017-07-26 07:02:01 -04:00
|
|
|
ref="noteForm"
|
|
|
|
/>
|
2017-07-04 17:56:25 -04:00
|
|
|
<issue-note-signed-out-widget v-if="!canReply" />
|
2017-06-13 13:01:59 -04:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</li>
|
|
|
|
</template>
|