143 lines
4.1 KiB
Vue
143 lines
4.1 KiB
Vue
<script>
|
|
import { mapActions, mapGetters } from 'vuex';
|
|
import { GlSprintf, GlIcon } from '@gitlab/ui';
|
|
import { IMAGE_DIFF_POSITION_TYPE } from '~/diffs/constants';
|
|
import { sprintf, __ } from '~/locale';
|
|
import resolvedStatusMixin from '../mixins/resolved_status';
|
|
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
|
import {
|
|
getStartLineNumber,
|
|
getEndLineNumber,
|
|
getLineClasses,
|
|
} from '~/notes/components/multiline_comment_utils';
|
|
|
|
export default {
|
|
components: {
|
|
GlIcon,
|
|
GlSprintf,
|
|
},
|
|
mixins: [resolvedStatusMixin, glFeatureFlagsMixin()],
|
|
props: {
|
|
draft: {
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
isLast: {
|
|
type: Boolean,
|
|
required: true,
|
|
},
|
|
},
|
|
computed: {
|
|
...mapGetters('diffs', ['getDiffFileByHash']),
|
|
...mapGetters(['getDiscussion']),
|
|
iconName() {
|
|
return this.isDiffDiscussion || this.draft.line_code ? 'doc-text' : 'comment';
|
|
},
|
|
discussion() {
|
|
return this.getDiscussion(this.draft.discussion_id);
|
|
},
|
|
isDiffDiscussion() {
|
|
return this.discussion && this.discussion.diff_discussion;
|
|
},
|
|
titleText() {
|
|
const file = this.discussion ? this.discussion.diff_file : this.draft;
|
|
|
|
if (file) {
|
|
return file.file_path;
|
|
}
|
|
|
|
return sprintf(__("%{authorsName}'s thread"), {
|
|
authorsName: this.discussion.notes.find(note => !note.system).author.name,
|
|
});
|
|
},
|
|
linePosition() {
|
|
if (this.position?.position_type === IMAGE_DIFF_POSITION_TYPE) {
|
|
// eslint-disable-next-line @gitlab/require-i18n-strings
|
|
return `${this.position.x}x ${this.position.y}y`;
|
|
}
|
|
|
|
return this.position?.new_line || this.position?.old_line;
|
|
},
|
|
content() {
|
|
const el = document.createElement('div');
|
|
el.innerHTML = this.draft.note_html;
|
|
|
|
return el.textContent;
|
|
},
|
|
showLinePosition() {
|
|
return this.draft.file_hash || this.isDiffDiscussion;
|
|
},
|
|
position() {
|
|
return this.draft.position || this.discussion.position;
|
|
},
|
|
startLineNumber() {
|
|
return getStartLineNumber(this.position?.line_range);
|
|
},
|
|
endLineNumber() {
|
|
return getEndLineNumber(this.position?.line_range);
|
|
},
|
|
},
|
|
methods: {
|
|
...mapActions('batchComments', ['scrollToDraft']),
|
|
getLineClasses(lineNumber) {
|
|
return getLineClasses(lineNumber);
|
|
},
|
|
},
|
|
showStaysResolved: false,
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<button
|
|
type="button"
|
|
class="review-preview-item menu-item"
|
|
:class="[
|
|
componentClasses,
|
|
{
|
|
'is-last': isLast,
|
|
},
|
|
]"
|
|
@click="scrollToDraft(draft)"
|
|
>
|
|
<span class="review-preview-item-header">
|
|
<gl-icon class="flex-shrink-0" :name="iconName" />
|
|
<span
|
|
class="bold text-nowrap"
|
|
:class="{ 'gl-align-items-center': glFeatures.multilineComments }"
|
|
>
|
|
<span class="review-preview-item-header-text block-truncated">
|
|
{{ titleText }}
|
|
</span>
|
|
<template v-if="showLinePosition">
|
|
<template v-if="!glFeatures.multilineComments"
|
|
>:{{ linePosition }}</template
|
|
>
|
|
<template v-else-if="startLineNumber === endLineNumber">
|
|
:<span :class="getLineClasses(startLineNumber)">{{ startLineNumber }}</span>
|
|
</template>
|
|
<gl-sprintf v-else :message="__(':%{startLine} to %{endLine}')">
|
|
<template #startLine>
|
|
<span class="gl-mr-2" :class="getLineClasses(startLineNumber)">{{
|
|
startLineNumber
|
|
}}</span>
|
|
</template>
|
|
<template #endLine>
|
|
<span class="gl-ml-2" :class="getLineClasses(endLineNumber)">{{
|
|
endLineNumber
|
|
}}</span>
|
|
</template>
|
|
</gl-sprintf>
|
|
</template>
|
|
</span>
|
|
</span>
|
|
<span class="review-preview-item-content">
|
|
<p>{{ content }}</p>
|
|
</span>
|
|
<span
|
|
v-if="draft.discussion_id && resolvedStatusMessage"
|
|
class="review-preview-item-footer draft-note-resolution p-0"
|
|
>
|
|
<gl-icon class="gl-mr-3" name="status_success" /> {{ resolvedStatusMessage }}
|
|
</span>
|
|
</button>
|
|
</template>
|