272 lines
8.7 KiB
Vue
272 lines
8.7 KiB
Vue
|
<script>
|
||
|
import { mapActions, mapGetters, mapState } from 'vuex';
|
||
|
import { GlTooltipDirective, GlIcon, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
|
||
|
import { CONTEXT_LINE_CLASS_NAME, PARALLEL_DIFF_VIEW_TYPE } from '../constants';
|
||
|
import DiffGutterAvatars from './diff_gutter_avatars.vue';
|
||
|
import * as utils from './diff_row_utils';
|
||
|
|
||
|
export default {
|
||
|
components: {
|
||
|
GlIcon,
|
||
|
DiffGutterAvatars,
|
||
|
},
|
||
|
directives: {
|
||
|
GlTooltip: GlTooltipDirective,
|
||
|
SafeHtml,
|
||
|
},
|
||
|
props: {
|
||
|
fileHash: {
|
||
|
type: String,
|
||
|
required: true,
|
||
|
},
|
||
|
filePath: {
|
||
|
type: String,
|
||
|
required: true,
|
||
|
},
|
||
|
line: {
|
||
|
type: Object,
|
||
|
required: true,
|
||
|
},
|
||
|
isCommented: {
|
||
|
type: Boolean,
|
||
|
required: false,
|
||
|
default: false,
|
||
|
},
|
||
|
inline: {
|
||
|
type: Boolean,
|
||
|
required: false,
|
||
|
default: false,
|
||
|
},
|
||
|
},
|
||
|
computed: {
|
||
|
...mapGetters('diffs', ['fileLineCoverage']),
|
||
|
...mapGetters(['isLoggedIn']),
|
||
|
...mapState({
|
||
|
isHighlighted(state) {
|
||
|
const line = this.line.left?.line_code ? this.line.left : this.line.right;
|
||
|
return utils.isHighlighted(state, line, this.isCommented);
|
||
|
},
|
||
|
}),
|
||
|
classNameMap() {
|
||
|
return {
|
||
|
[CONTEXT_LINE_CLASS_NAME]: this.line.isContextLineLeft,
|
||
|
[PARALLEL_DIFF_VIEW_TYPE]: true,
|
||
|
};
|
||
|
},
|
||
|
parallelViewLeftLineType() {
|
||
|
return utils.parallelViewLeftLineType(this.line, this.isHighlighted);
|
||
|
},
|
||
|
coverageState() {
|
||
|
return this.fileLineCoverage(this.filePath, this.line.right.new_line);
|
||
|
},
|
||
|
classNameMapCellLeft() {
|
||
|
return utils.classNameMapCell(this.line.left, this.isHighlighted, this.isLoggedIn);
|
||
|
},
|
||
|
classNameMapCellRight() {
|
||
|
return utils.classNameMapCell(this.line.right, this.isHighlighted, this.isLoggedIn);
|
||
|
},
|
||
|
addCommentTooltipLeft() {
|
||
|
return utils.addCommentTooltip(this.line.left);
|
||
|
},
|
||
|
addCommentTooltipRight() {
|
||
|
return utils.addCommentTooltip(this.line.right);
|
||
|
},
|
||
|
shouldRenderCommentButton() {
|
||
|
return (
|
||
|
this.isLoggedIn &&
|
||
|
!this.line.isContextLineLeft &&
|
||
|
!this.line.isMetaLineLeft &&
|
||
|
!this.line.hasDiscussionsLeft &&
|
||
|
!this.line.hasDiscussionsRight
|
||
|
);
|
||
|
},
|
||
|
},
|
||
|
mounted() {
|
||
|
this.scrollToLineIfNeededParallel(this.line);
|
||
|
},
|
||
|
methods: {
|
||
|
...mapActions('diffs', [
|
||
|
'scrollToLineIfNeededParallel',
|
||
|
'showCommentForm',
|
||
|
'setHighlightedRow',
|
||
|
'toggleLineDiscussions',
|
||
|
]),
|
||
|
// Prevent text selecting on both sides of parallel diff view
|
||
|
// Backport of the same code from legacy diff notes.
|
||
|
handleParallelLineMouseDown(e) {
|
||
|
const line = e.currentTarget;
|
||
|
const table = line.closest('.diff-table');
|
||
|
|
||
|
table.classList.remove('left-side-selected', 'right-side-selected');
|
||
|
const [lineClass] = ['left-side', 'right-side'].filter(name => line.classList.contains(name));
|
||
|
|
||
|
if (lineClass) {
|
||
|
table.classList.add(`${lineClass}-selected`);
|
||
|
}
|
||
|
},
|
||
|
handleCommentButton(line) {
|
||
|
this.showCommentForm({ lineCode: line.line_code, fileHash: this.fileHash });
|
||
|
},
|
||
|
},
|
||
|
};
|
||
|
</script>
|
||
|
|
||
|
<template>
|
||
|
<div :class="classNameMap" class="diff-grid-row diff-tr line_holder">
|
||
|
<div class="diff-grid-left left-side">
|
||
|
<template v-if="line.left">
|
||
|
<div
|
||
|
:class="classNameMapCellLeft"
|
||
|
data-testid="leftLineNumber"
|
||
|
class="diff-td diff-line-num old_line"
|
||
|
>
|
||
|
<span
|
||
|
v-if="shouldRenderCommentButton"
|
||
|
v-gl-tooltip
|
||
|
data-testid="leftCommentButton"
|
||
|
class="add-diff-note tooltip-wrapper"
|
||
|
:title="addCommentTooltipLeft"
|
||
|
>
|
||
|
<button
|
||
|
type="button"
|
||
|
class="add-diff-note note-button js-add-diff-note-button qa-diff-comment"
|
||
|
:disabled="line.left.commentsDisabled"
|
||
|
@click="handleCommentButton(line.left)"
|
||
|
>
|
||
|
<gl-icon :size="12" name="comment" />
|
||
|
</button>
|
||
|
</span>
|
||
|
<a
|
||
|
v-if="line.left.old_line"
|
||
|
:data-linenumber="line.left.old_line"
|
||
|
:href="line.lineHrefOld"
|
||
|
@click="setHighlightedRow(line.lineCode)"
|
||
|
>
|
||
|
</a>
|
||
|
<diff-gutter-avatars
|
||
|
v-if="line.hasDiscussionsLeft"
|
||
|
:discussions="line.left.discussions"
|
||
|
:discussions-expanded="line.left.discussionsExpanded"
|
||
|
data-testid="leftDiscussions"
|
||
|
@toggleLineDiscussions="
|
||
|
toggleLineDiscussions({
|
||
|
lineCode: line.left.line_code,
|
||
|
fileHash,
|
||
|
expanded: !line.left.discussionsExpanded,
|
||
|
})
|
||
|
"
|
||
|
/>
|
||
|
</div>
|
||
|
<div :class="classNameMapCellLeft" class="diff-td diff-line-num old_line">
|
||
|
<a
|
||
|
v-if="line.left.old_line"
|
||
|
:data-linenumber="line.left.old_line"
|
||
|
:href="line.lineHrefOld"
|
||
|
@click="setHighlightedRow(line.lineCode)"
|
||
|
>
|
||
|
</a>
|
||
|
</div>
|
||
|
<div :class="parallelViewLeftLineType" class="diff-td line-coverage left-side"></div>
|
||
|
<div
|
||
|
:id="line.left.line_code"
|
||
|
:key="line.left.line_code"
|
||
|
v-safe-html="line.left.rich_text"
|
||
|
:class="parallelViewLeftLineType"
|
||
|
class="diff-td line_content with-coverage parallel left-side"
|
||
|
data-testid="leftContent"
|
||
|
@mousedown="handleParallelLineMouseDown"
|
||
|
></div>
|
||
|
</template>
|
||
|
<template v-else>
|
||
|
<div data-testid="leftEmptyCell" class="diff-td diff-line-num old_line empty-cell"></div>
|
||
|
<div class="diff-td diff-line-num old_line empty-cell"></div>
|
||
|
<div class="diff-td line-coverage left-side empty-cell"></div>
|
||
|
<div class="diff-td line_content with-coverage parallel left-side empty-cell"></div>
|
||
|
</template>
|
||
|
</div>
|
||
|
<div
|
||
|
v-if="!inline || (line.right && Boolean(line.right.type))"
|
||
|
class="diff-grid-right right-side"
|
||
|
>
|
||
|
<template v-if="line.right">
|
||
|
<div
|
||
|
:class="classNameMapCellRight"
|
||
|
data-testid="rightLineNumber"
|
||
|
class="diff-td diff-line-num new_line"
|
||
|
>
|
||
|
<span
|
||
|
v-if="shouldRenderCommentButton"
|
||
|
v-gl-tooltip
|
||
|
data-testid="rightCommentButton"
|
||
|
class="add-diff-note tooltip-wrapper"
|
||
|
:title="addCommentTooltipRight"
|
||
|
>
|
||
|
<button
|
||
|
type="button"
|
||
|
class="add-diff-note note-button js-add-diff-note-button qa-diff-comment"
|
||
|
:disabled="line.right.commentsDisabled"
|
||
|
@click="handleCommentButton(line.right)"
|
||
|
>
|
||
|
<gl-icon :size="12" name="comment" />
|
||
|
</button>
|
||
|
</span>
|
||
|
<a
|
||
|
v-if="line.right.new_line"
|
||
|
:data-linenumber="line.right.new_line"
|
||
|
:href="line.lineHrefNew"
|
||
|
@click="setHighlightedRow(line.lineCode)"
|
||
|
>
|
||
|
</a>
|
||
|
<diff-gutter-avatars
|
||
|
v-if="line.hasDiscussionsRight"
|
||
|
:discussions="line.right.discussions"
|
||
|
:discussions-expanded="line.right.discussionsExpanded"
|
||
|
data-testid="rightDiscussions"
|
||
|
@toggleLineDiscussions="
|
||
|
toggleLineDiscussions({
|
||
|
lineCode: line.right.line_code,
|
||
|
fileHash,
|
||
|
expanded: !line.right.discussionsExpanded,
|
||
|
})
|
||
|
"
|
||
|
/>
|
||
|
</div>
|
||
|
<div :class="classNameMapCellRight" class="diff-td diff-line-num new_line">
|
||
|
<a
|
||
|
v-if="line.right.new_line"
|
||
|
:data-linenumber="line.right.new_line"
|
||
|
:href="line.lineHrefNew"
|
||
|
@click="setHighlightedRow(line.lineCode)"
|
||
|
>
|
||
|
</a>
|
||
|
</div>
|
||
|
<div
|
||
|
v-gl-tooltip.hover
|
||
|
:title="coverageState.text"
|
||
|
:class="[line.right.type, coverageState.class, { hll: isHighlighted }]"
|
||
|
class="diff-td line-coverage right-side"
|
||
|
></div>
|
||
|
<div
|
||
|
:id="line.right.line_code"
|
||
|
:key="line.right.rich_text"
|
||
|
v-safe-html="line.right.rich_text"
|
||
|
:class="[
|
||
|
line.right.type,
|
||
|
{
|
||
|
hll: isHighlighted,
|
||
|
},
|
||
|
]"
|
||
|
class="diff-td line_content with-coverage parallel right-side"
|
||
|
@mousedown="handleParallelLineMouseDown"
|
||
|
></div>
|
||
|
</template>
|
||
|
<template v-else>
|
||
|
<div data-testid="rightEmptyCell" class="diff-td diff-line-num old_line empty-cell"></div>
|
||
|
<div class="diff-td diff-line-num old_line empty-cell"></div>
|
||
|
<div class="diff-td line-coverage right-side empty-cell"></div>
|
||
|
<div class="diff-td line_content with-coverage parallel right-side empty-cell"></div>
|
||
|
</template>
|
||
|
</div>
|
||
|
</div>
|
||
|
</template>
|