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

229 lines
6.8 KiB
Vue
Raw Normal View History

2019-07-31 22:56:46 +05:30
<script>
2019-09-30 21:07:59 +05:30
import { mapGetters, mapActions } from 'vuex';
2021-12-11 22:18:48 +05:30
import { GlIntersectionObserver } from '@gitlab/ui';
2019-07-31 22:56:46 +05:30
import { __ } from '~/locale';
2019-09-30 21:07:59 +05:30
import PlaceholderNote from '~/vue_shared/components/notes/placeholder_note.vue';
import PlaceholderSystemNote from '~/vue_shared/components/notes/placeholder_system_note.vue';
2019-07-31 22:56:46 +05:30
import SystemNote from '~/vue_shared/components/notes/system_note.vue';
2021-03-11 19:13:27 +05:30
import { SYSTEM_NOTE } from '../constants';
import DiscussionNotesRepliesWrapper from './discussion_notes_replies_wrapper.vue';
import NoteEditedText from './note_edited_text.vue';
2019-09-30 21:07:59 +05:30
import NoteableNote from './noteable_note.vue';
2019-07-31 22:56:46 +05:30
import ToggleRepliesWidget from './toggle_replies_widget.vue';
export default {
name: 'DiscussionNotes',
components: {
ToggleRepliesWidget,
NoteEditedText,
2019-09-30 21:07:59 +05:30
DiscussionNotesRepliesWrapper,
2021-12-11 22:18:48 +05:30
GlIntersectionObserver,
2019-07-31 22:56:46 +05:30
},
2021-12-11 22:18:48 +05:30
inject: ['discussionObserverHandler'],
2019-07-31 22:56:46 +05:30
props: {
discussion: {
type: Object,
required: true,
},
isExpanded: {
type: Boolean,
required: false,
default: false,
},
diffLine: {
type: Object,
required: false,
default: null,
},
line: {
type: Object,
required: false,
default: null,
},
shouldGroupReplies: {
type: Boolean,
required: false,
default: false,
},
helpPagePath: {
type: String,
required: false,
default: '',
},
2021-11-18 22:05:49 +05:30
isOverviewTab: {
type: Boolean,
required: false,
default: false,
},
2019-07-31 22:56:46 +05:30
},
computed: {
2021-12-11 22:18:48 +05:30
...mapGetters([
'userCanReply',
'previousUnresolvedDiscussionId',
'firstUnresolvedDiscussionId',
]),
2019-07-31 22:56:46 +05:30
hasReplies() {
2019-09-04 21:01:54 +05:30
return Boolean(this.replies.length);
2019-07-31 22:56:46 +05:30
},
replies() {
return this.discussion.notes.slice(1);
},
firstNote() {
return this.discussion.notes.slice(0, 1)[0];
},
resolvedText() {
return this.discussion.resolved_by_push ? __('Automatically resolved') : __('Resolved');
},
commit() {
if (!this.discussion.for_commit) {
return null;
}
return {
id: this.discussion.commit_id,
url: this.discussion.discussion_path,
};
},
2021-12-11 22:18:48 +05:30
isFirstUnresolved() {
return this.firstUnresolvedDiscussionId === this.discussion.id;
},
},
observerOptions: {
threshold: 0,
rootMargin: '0px 0px -50% 0px',
2019-07-31 22:56:46 +05:30
},
methods: {
2021-12-11 22:18:48 +05:30
...mapActions([
'toggleDiscussion',
'setSelectedCommentPositionHover',
'setCurrentDiscussionId',
]),
2019-07-31 22:56:46 +05:30
componentName(note) {
if (note.isPlaceholderNote) {
if (note.placeholderType === SYSTEM_NOTE) {
return PlaceholderSystemNote;
}
return PlaceholderNote;
}
if (note.system) {
return SystemNote;
}
return NoteableNote;
},
componentData(note) {
return note.isPlaceholderNote ? note.notes[0] : note;
},
2020-10-24 23:57:45 +05:30
handleMouseEnter(discussion) {
2021-03-11 19:13:27 +05:30
if (discussion.position) {
2020-10-24 23:57:45 +05:30
this.setSelectedCommentPositionHover(discussion.position.line_range);
}
},
handleMouseLeave(discussion) {
2021-03-11 19:13:27 +05:30
// Even though position isn't used here we still don't want to unnecessarily call a mutation
2020-10-24 23:57:45 +05:30
// The lack of position tells us that highlighting is irrelevant in this context
2021-03-11 19:13:27 +05:30
if (discussion.position) {
2020-10-24 23:57:45 +05:30
this.setSelectedCommentPositionHover();
}
},
2021-12-11 22:18:48 +05:30
observerTriggered(entry) {
this.discussionObserverHandler({
entry,
isFirstUnresolved: this.isFirstUnresolved,
currentDiscussion: { ...this.discussion },
isDiffsPage: !this.isOverviewTab,
functions: {
setCurrentDiscussionId: this.setCurrentDiscussionId,
getPreviousUnresolvedDiscussionId: this.previousUnresolvedDiscussionId,
},
});
},
2019-07-31 22:56:46 +05:30
},
};
</script>
<template>
<div class="discussion-notes">
2020-07-28 23:09:34 +05:30
<ul
class="notes"
2020-10-24 23:57:45 +05:30
@mouseenter="handleMouseEnter(discussion)"
@mouseleave="handleMouseLeave(discussion)"
2020-07-28 23:09:34 +05:30
>
2019-07-31 22:56:46 +05:30
<template v-if="shouldGroupReplies">
2021-12-11 22:18:48 +05:30
<gl-intersection-observer :options="$options.observerOptions" @update="observerTriggered">
<component
:is="componentName(firstNote)"
:note="componentData(firstNote)"
:line="line || diffLine"
:discussion-file="discussion.diff_file"
:commit="commit"
:help-page-path="helpPagePath"
:show-reply-button="userCanReply"
:discussion-root="true"
:discussion-resolve-path="discussion.resolve_path"
:is-overview-tab="isOverviewTab"
@handleDeleteNote="$emit('deleteNote')"
@startReplying="$emit('startReplying')"
>
<template #discussion-resolved-text>
<note-edited-text
v-if="discussion.resolved"
:edited-at="discussion.resolved_at"
:edited-by="discussion.resolved_by"
:action-text="resolvedText"
class-name="discussion-headline-light js-discussion-headline discussion-resolved-text"
/>
</template>
<template #avatar-badge>
<slot name="avatar-badge"></slot>
</template>
</component>
</gl-intersection-observer>
2019-09-30 21:07:59 +05:30
<discussion-notes-replies-wrapper :is-diff-discussion="discussion.diff_discussion">
<toggle-replies-widget
v-if="hasReplies"
:collapsed="!isExpanded"
:replies="replies"
:class="{ 'discussion-toggle-replies': discussion.diff_discussion }"
@toggle="toggleDiscussion({ discussionId: discussion.id })"
2019-07-31 22:56:46 +05:30
/>
2019-09-30 21:07:59 +05:30
<template v-if="isExpanded">
<component
:is="componentName(note)"
v-for="note in replies"
:key="note.id"
:note="componentData(note)"
:help-page-path="helpPagePath"
:line="line"
@handleDeleteNote="$emit('deleteNote')"
/>
</template>
<slot :show-replies="isExpanded || !hasReplies" name="footer"></slot>
</discussion-notes-replies-wrapper>
2019-07-31 22:56:46 +05:30
</template>
<template v-else>
<component
:is="componentName(note)"
v-for="(note, index) in discussion.notes"
:key="note.id"
:note="componentData(note)"
2021-04-29 21:17:54 +05:30
:discussion-file="discussion.diff_file"
2019-07-31 22:56:46 +05:30
:help-page-path="helpPagePath"
:line="diffLine"
2020-07-28 23:09:34 +05:30
:discussion-root="index === 0"
2021-01-29 00:20:46 +05:30
:discussion-resolve-path="discussion.resolve_path"
2021-11-18 22:05:49 +05:30
:is-overview-tab="isOverviewTab"
2019-09-30 21:07:59 +05:30
@handleDeleteNote="$emit('deleteNote')"
2019-07-31 22:56:46 +05:30
>
2021-09-30 23:02:18 +05:30
<template #avatar-badge>
<slot v-if="index === 0" name="avatar-badge"></slot>
</template>
2019-07-31 22:56:46 +05:30
</component>
2019-09-30 21:07:59 +05:30
<slot :show-replies="isExpanded || !hasReplies" name="footer"></slot>
2019-07-31 22:56:46 +05:30
</template>
</ul>
</div>
</template>