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

222 lines
5.9 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 { getLocationHash } from '../../lib/utils/url_utility';
import Flash from '../../flash';
import * as constants from '../constants';
2018-11-08 19:23:39 +05:30
import eventHub from '../event_hub';
2018-05-09 12:01:36 +05:30
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 skeletonLoadingContainer from '../../vue_shared/components/notes/skeleton_note.vue';
2018-12-05 23:21:45 +05:30
import highlightCurrentUser from '~/behaviors/markdown/highlight_current_user';
2018-03-17 18:26:18 +05:30
2018-05-09 12:01:36 +05:30
export default {
name: 'NotesApp',
components: {
noteableNote,
noteableDiscussion,
systemNote,
commentForm,
placeholderNote,
placeholderSystemNote,
},
props: {
noteableData: {
type: Object,
required: true,
2018-03-17 18:26:18 +05:30
},
2018-05-09 12:01:36 +05:30
notesData: {
type: Object,
required: true,
2018-03-17 18:26:18 +05:30
},
2018-05-09 12:01:36 +05:30
userData: {
type: Object,
required: false,
default: () => ({}),
2018-03-17 18:26:18 +05:30
},
2018-11-08 19:23:39 +05:30
shouldShow: {
type: Boolean,
required: false,
default: true,
},
markdownVersion: {
type: Number,
required: false,
default: 0,
},
2018-05-09 12:01:36 +05:30
},
data() {
return {
2018-12-13 13:39:08 +05:30
isFetching: false,
currentFilter: null,
2018-05-09 12:01:36 +05:30
};
},
computed: {
2018-12-13 13:39:08 +05:30
...mapGetters([
'isNotesFetched',
'discussions',
'getNotesDataByProp',
2019-01-03 12:48:30 +05:30
'discussionCount',
2018-12-13 13:39:08 +05:30
'isLoading',
'commentsDisabled',
]),
2018-05-09 12:01:36 +05:30
noteableType() {
return this.noteableData.noteableType;
2018-03-17 18:26:18 +05:30
},
2018-11-08 19:23:39 +05:30
allDiscussions() {
2018-05-09 12:01:36 +05:30
if (this.isLoading) {
const totalNotes = parseInt(this.notesData.totalNotes, 10) || 0;
2018-03-17 18:26:18 +05:30
2018-05-09 12:01:36 +05:30
return new Array(totalNotes).fill({
isSkeletonNote: true,
2018-03-17 18:26:18 +05:30
});
}
2018-11-08 19:23:39 +05:30
return this.discussions;
},
},
watch: {
shouldShow() {
if (!this.isNotesFetched) {
this.fetchNotes();
}
2018-03-27 19:54:05 +05:30
},
2018-05-09 12:01:36 +05:30
},
created() {
this.setNotesData(this.notesData);
this.setNoteableData(this.noteableData);
this.setUserData(this.userData);
2018-11-08 19:23:39 +05:30
this.setTargetNoteHash(getLocationHash());
eventHub.$once('fetchNotesData', this.fetchNotes);
2018-05-09 12:01:36 +05:30
},
mounted() {
2018-11-08 19:23:39 +05:30
if (this.shouldShow) {
this.fetchNotes();
}
2018-05-09 12:01:36 +05:30
2018-11-08 19:23:39 +05:30
const { parentElement } = this.$el;
if (parentElement && parentElement.classList.contains('js-vue-notes-event')) {
2018-05-09 12:01:36 +05:30
parentElement.addEventListener('toggleAward', event => {
const { awardName, noteId } = event.detail;
2019-01-03 12:48:30 +05:30
this.actionToggleAward({ awardName, noteId });
2018-05-09 12:01:36 +05:30
});
}
},
2018-12-05 23:21:45 +05:30
updated() {
2019-01-03 12:48:30 +05:30
this.$nextTick(() => highlightCurrentUser(this.$el.querySelectorAll('.gfm-project_member')));
2018-12-05 23:21:45 +05:30
},
2018-05-09 12:01:36 +05:30
methods: {
2019-01-03 12:48:30 +05:30
...mapActions({
setLoadingState: 'setLoadingState',
fetchDiscussions: 'fetchDiscussions',
poll: 'poll',
actionToggleAward: 'toggleAward',
scrollToNoteIfNeeded: 'scrollToNoteIfNeeded',
setNotesData: 'setNotesData',
setNoteableData: 'setNoteableData',
setUserData: 'setUserData',
setLastFetchedAt: 'setLastFetchedAt',
setTargetNoteHash: 'setTargetNoteHash',
toggleDiscussion: 'toggleDiscussion',
setNotesFetchedState: 'setNotesFetchedState',
}),
getComponentName(discussion) {
if (discussion.isSkeletonNote) {
return skeletonLoadingContainer;
}
if (discussion.isPlaceholderNote) {
if (discussion.placeholderType === constants.SYSTEM_NOTE) {
return placeholderSystemNote;
}
return placeholderNote;
} else if (discussion.individual_note) {
return discussion.notes[0].system ? systemNote : noteableNote;
}
return noteableDiscussion;
},
getComponentData(discussion) {
return discussion.individual_note ? { note: discussion.notes[0] } : { discussion };
},
2018-05-09 12:01:36 +05:30
fetchNotes() {
2018-12-13 13:39:08 +05:30
if (this.isFetching) return null;
this.isFetching = true;
return this.fetchDiscussions({ path: this.getNotesDataByProp('discussionsPath') })
2018-11-08 19:23:39 +05:30
.then(() => {
this.initPolling();
})
2018-05-09 12:01:36 +05:30
.then(() => {
2018-12-13 13:39:08 +05:30
this.setLoadingState(false);
2018-11-08 19:23:39 +05:30
this.setNotesFetchedState(true);
2018-11-20 20:47:30 +05:30
eventHub.$emit('fetchedNotesData');
2018-12-13 13:39:08 +05:30
this.isFetching = false;
2018-05-09 12:01:36 +05:30
})
.then(() => this.$nextTick())
.then(() => this.checkLocationHash())
.catch(() => {
2018-12-13 13:39:08 +05:30
this.setLoadingState(false);
2018-11-08 19:23:39 +05:30
this.setNotesFetchedState(true);
Flash('Something went wrong while fetching comments. Please try again.');
2018-05-09 12:01:36 +05:30
});
},
initPolling() {
if (this.isPollingInitialized) {
return;
}
2018-03-27 19:54:05 +05:30
2018-05-09 12:01:36 +05:30
this.setLastFetchedAt(this.getNotesDataByProp('lastFetchedAt'));
2018-03-17 18:26:18 +05:30
2018-05-09 12:01:36 +05:30
this.poll();
this.isPollingInitialized = true;
},
checkLocationHash() {
const hash = getLocationHash();
2018-11-08 19:23:39 +05:30
const noteId = hash && hash.replace(/^note_/, '');
2018-03-17 18:26:18 +05:30
2018-11-08 19:23:39 +05:30
if (noteId) {
2019-01-03 12:48:30 +05:30
this.discussions.forEach(discussion => {
if (discussion.notes) {
discussion.notes.forEach(note => {
if (`${note.id}` === `${noteId}`) {
// FIXME: this modifies the store state without using a mutation/action
Object.assign(discussion, { expanded: true });
}
});
}
});
2018-05-09 12:01:36 +05:30
}
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
v-show="shouldShow"
id="notes"
>
<ul
id="notes-list"
class="notes main-notes-list timeline"
>
<component
:is="getComponentName(discussion)"
v-for="discussion in allDiscussions"
:key="discussion.id"
v-bind="getComponentData(discussion)"
/>
2018-03-17 18:26:18 +05:30
</ul>
2018-03-27 19:54:05 +05:30
<comment-form
2018-12-13 13:39:08 +05:30
v-if="!commentsDisabled"
2018-03-27 19:54:05 +05:30
:noteable-type="noteableType"
2018-11-08 19:23:39 +05:30
:markdown-version="markdownVersion"
2018-03-27 19:54:05 +05:30
/>
2018-03-17 18:26:18 +05:30
</div>
</template>