diff options
Diffstat (limited to 'app/assets/javascripts/notes/components/notes_app.vue')
-rw-r--r-- | app/assets/javascripts/notes/components/notes_app.vue | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/app/assets/javascripts/notes/components/notes_app.vue b/app/assets/javascripts/notes/components/notes_app.vue new file mode 100644 index 00000000000..e526c2491f5 --- /dev/null +++ b/app/assets/javascripts/notes/components/notes_app.vue @@ -0,0 +1,151 @@ +<script> + import { mapGetters, mapActions } from 'vuex'; + import Flash from '../../flash'; + import store from '../stores/'; + import * as constants from '../constants'; + import noteableNote from './noteable_note.vue'; + import noteableDiscussion from './noteable_discussion.vue'; + import systemNote from '../../vue_shared/components/notes/system_note.vue'; + import commentForm from './comment_form.vue'; + import placeholderNote from '../../vue_shared/components/notes/placeholder_note.vue'; + import placeholderSystemNote from '../../vue_shared/components/notes/placeholder_system_note.vue'; + import loadingIcon from '../../vue_shared/components/loading_icon.vue'; + + export default { + name: 'notesApp', + props: { + noteableData: { + type: Object, + required: true, + }, + notesData: { + type: Object, + required: true, + }, + userData: { + type: Object, + required: false, + default: {}, + }, + }, + store, + data() { + return { + isLoading: true, + }; + }, + components: { + noteableNote, + noteableDiscussion, + systemNote, + commentForm, + loadingIcon, + placeholderNote, + placeholderSystemNote, + }, + computed: { + ...mapGetters([ + 'notes', + 'getNotesDataByProp', + ]), + }, + methods: { + ...mapActions({ + actionFetchNotes: 'fetchNotes', + poll: 'poll', + actionToggleAward: 'toggleAward', + scrollToNoteIfNeeded: 'scrollToNoteIfNeeded', + setNotesData: 'setNotesData', + setNoteableData: 'setNoteableData', + setUserData: 'setUserData', + setLastFetchedAt: 'setLastFetchedAt', + setTargetNoteHash: 'setTargetNoteHash', + }), + getComponentName(note) { + if (note.isPlaceholderNote) { + if (note.placeholderType === constants.SYSTEM_NOTE) { + return placeholderSystemNote; + } + return placeholderNote; + } else if (note.individual_note) { + return note.notes[0].system ? systemNote : noteableNote; + } + + return noteableDiscussion; + }, + getComponentData(note) { + return note.individual_note ? note.notes[0] : note; + }, + fetchNotes() { + return this.actionFetchNotes(this.getNotesDataByProp('discussionsPath')) + .then(() => this.initPolling()) + .then(() => { + this.isLoading = false; + }) + .then(() => this.$nextTick()) + .then(() => this.checkLocationHash()) + .catch(() => { + this.isLoading = false; + Flash('Something went wrong while fetching comments. Please try again.'); + }); + }, + initPolling() { + this.setLastFetchedAt(this.getNotesDataByProp('lastFetchedAt')); + + this.poll(); + }, + checkLocationHash() { + const hash = gl.utils.getLocationHash(); + const element = document.getElementById(hash); + + if (hash && element) { + this.setTargetNoteHash(hash); + this.scrollToNoteIfNeeded($(element)); + } + }, + }, + created() { + this.setNotesData(this.notesData); + this.setNoteableData(this.noteableData); + this.setUserData(this.userData); + }, + mounted() { + this.fetchNotes(); + + const parentElement = this.$el.parentElement; + + if (parentElement && + parentElement.classList.contains('js-vue-notes-event')) { + parentElement.addEventListener('toggleAward', (event) => { + const { awardName, noteId } = event.detail; + this.actionToggleAward({ awardName, noteId }); + }); + } + }, + }; +</script> + +<template> + <div id="notes"> + <div + v-if="isLoading" + class="js-loading loading"> + <loading-icon /> + </div> + + <ul + v-if="!isLoading" + id="notes-list" + class="notes main-notes-list timeline"> + + <component + v-for="note in notes" + :is="getComponentName(note)" + :note="getComponentData(note)" + :key="note.id" + /> + </ul> + + <comment-form /> + </div> +</template> |