225 lines
7.6 KiB
Vue
225 lines
7.6 KiB
Vue
<script>
|
|
import diffContentMixin from '../mixins/diff_content';
|
|
import {
|
|
EMPTY_CELL_TYPE,
|
|
MATCH_LINE_TYPE,
|
|
CONTEXT_LINE_TYPE,
|
|
OLD_NO_NEW_LINE_TYPE,
|
|
NEW_NO_NEW_LINE_TYPE,
|
|
LINE_HOVER_CLASS_NAME,
|
|
LINE_UNFOLD_CLASS_NAME,
|
|
LINE_POSITION_RIGHT,
|
|
} from '../constants';
|
|
|
|
export default {
|
|
mixins: [diffContentMixin],
|
|
computed: {
|
|
parallelDiffLines() {
|
|
return this.normalizedDiffLines.map(line => {
|
|
if (!line.left) {
|
|
Object.assign(line, { left: { type: EMPTY_CELL_TYPE } });
|
|
} else if (!line.right) {
|
|
Object.assign(line, { right: { type: EMPTY_CELL_TYPE } });
|
|
}
|
|
|
|
return line;
|
|
});
|
|
},
|
|
},
|
|
methods: {
|
|
hasDiscussion(line) {
|
|
const discussions = this.discussionsByLineCode;
|
|
const hasDiscussion = discussions[line.left.lineCode] || discussions[line.right.lineCode];
|
|
|
|
return hasDiscussion;
|
|
},
|
|
getClassName(line, position) {
|
|
const { type, lineCode } = line[position];
|
|
const isMatchLine = type === MATCH_LINE_TYPE;
|
|
const isContextLine = !isMatchLine && type !== EMPTY_CELL_TYPE && type !== CONTEXT_LINE_TYPE;
|
|
const isMetaLine = type === OLD_NO_NEW_LINE_TYPE || type === NEW_NO_NEW_LINE_TYPE;
|
|
const isSameLine = this.hoveredLineCode && this.hoveredLineCode === lineCode;
|
|
const isSameSection = position === this.hoveredSection;
|
|
|
|
return {
|
|
[type]: type,
|
|
[LINE_UNFOLD_CLASS_NAME]: isMatchLine,
|
|
[LINE_HOVER_CLASS_NAME]:
|
|
this.isLoggedIn && isContextLine && isSameLine && isSameSection && !isMetaLine,
|
|
};
|
|
},
|
|
handleMouse(e, line, isHover) {
|
|
if (isHover) {
|
|
const cell = e.target.closest('td');
|
|
|
|
if (this.$refs.leftLines.indexOf(cell) > -1) {
|
|
this.hoveredLineCode = line.left.lineCode;
|
|
this.hoveredSection = 'left';
|
|
} else if (this.$refs.rightLines.indexOf(cell) > -1) {
|
|
this.hoveredLineCode = line.right.lineCode;
|
|
this.hoveredSection = 'right';
|
|
}
|
|
} else {
|
|
this.hoveredLineCode = null;
|
|
this.hoveredSection = null;
|
|
}
|
|
},
|
|
shouldRenderDiscussionsRow(line) {
|
|
const hasDiscussion = this.hasDiscussion(line) && this.hasAnyExpandedDiscussion(line);
|
|
const hasCommentFormOnLeft = this.diffLineCommentForms[line.left.lineCode];
|
|
const hasCommentFormOnRight = this.diffLineCommentForms[line.right.lineCode];
|
|
|
|
return hasDiscussion || hasCommentFormOnLeft || hasCommentFormOnRight;
|
|
},
|
|
shouldRenderDiscussions(line, position) {
|
|
const { lineCode } = line[position];
|
|
let render = this.discussionsByLineCode[lineCode] && this.isDiscussionExpanded(lineCode);
|
|
|
|
// Avoid rendering context line discussions on the right side in parallel view
|
|
if (position === LINE_POSITION_RIGHT) {
|
|
render = render && line.right.type;
|
|
}
|
|
|
|
return render;
|
|
},
|
|
hasAnyExpandedDiscussion(line) {
|
|
const isLeftExpanded = this.isDiscussionExpanded(line.left.lineCode);
|
|
const isRightExpanded = this.isDiscussionExpanded(line.right.lineCode);
|
|
|
|
return isLeftExpanded || isRightExpanded;
|
|
},
|
|
getLineCode(line, side) {
|
|
const lineCode = side.lineCode;
|
|
if (lineCode) {
|
|
return lineCode;
|
|
}
|
|
|
|
return `${this.fileHash}_${line.left.oldLine}_${line.right.newLine}`;
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
:class="userColorScheme"
|
|
:data-commit-id="commitId"
|
|
class="code diff-wrap-lines js-syntax-highlight text-file">
|
|
<table>
|
|
<tbody>
|
|
<template
|
|
v-for="(line, index) in parallelDiffLines"
|
|
>
|
|
<tr
|
|
:key="index"
|
|
:class="getRowClass(line)"
|
|
class="line_holder parallel"
|
|
@mouseover="handleMouse($event, line, true)"
|
|
@mouseout="handleMouse($event, line, false)"
|
|
>
|
|
<td
|
|
ref="leftLines"
|
|
:class="getClassName(line, 'left')"
|
|
class="diff-line-num old_line"
|
|
>
|
|
<diff-line-gutter-content
|
|
:file-hash="fileHash"
|
|
:line-type="line.left.type"
|
|
:line-code="line.left.lineCode"
|
|
:line-number="line.left.oldLine"
|
|
:meta-data="line.left.metaData"
|
|
:show-comment-button="true"
|
|
:context-lines-path="diffFile.contextLinesPath"
|
|
:is-bottom="index + 1 === diffLinesLength"
|
|
line-position="left"
|
|
@showCommentForm="handleShowCommentForm"
|
|
/>
|
|
</td>
|
|
<td
|
|
ref="leftLines"
|
|
:class="getClassName(line, 'left')"
|
|
:id="getLineCode(line, line.left)"
|
|
class="line_content parallel left-side"
|
|
v-html="line.left.richText"
|
|
>
|
|
</td>
|
|
<td
|
|
ref="rightLines"
|
|
:class="getClassName(line, 'right')"
|
|
class="diff-line-num new_line"
|
|
>
|
|
<diff-line-gutter-content
|
|
:file-hash="fileHash"
|
|
:line-type="line.right.type"
|
|
:line-code="line.right.lineCode"
|
|
:line-number="line.right.newLine"
|
|
:meta-data="line.right.metaData"
|
|
:show-comment-button="true"
|
|
:context-lines-path="diffFile.contextLinesPath"
|
|
:is-bottom="index + 1 === diffLinesLength"
|
|
line-position="right"
|
|
@showCommentForm="handleShowCommentForm"
|
|
/>
|
|
</td>
|
|
<td
|
|
ref="rightLines"
|
|
:class="getClassName(line, 'right')"
|
|
:id="getLineCode(line, line.right)"
|
|
class="line_content parallel right-side"
|
|
v-html="line.right.richText"
|
|
>
|
|
</td>
|
|
</tr>
|
|
<tr
|
|
v-if="shouldRenderDiscussionsRow(line)"
|
|
:key="line.left.lineCode || line.right.lineCode"
|
|
:class="hasDiscussion(line) ? '' : 'js-temp-notes-holder'"
|
|
class="notes_holder"
|
|
>
|
|
<td class="notes_line old"></td>
|
|
<td class="notes_content parallel old">
|
|
<div
|
|
v-if="shouldRenderDiscussions(line, 'left')"
|
|
class="content"
|
|
>
|
|
<diff-discussions
|
|
:discussions="discussionsByLineCode[line.left.lineCode]"
|
|
/>
|
|
</div>
|
|
<diff-line-note-form
|
|
v-if="diffLineCommentForms[line.left.lineCode] &&
|
|
diffLineCommentForms[line.left.lineCode]"
|
|
:diff-file="diffFile"
|
|
:diff-lines="diffLines"
|
|
:line="line.left"
|
|
:note-target-line="diffLines[index].left"
|
|
position="left"
|
|
/>
|
|
</td>
|
|
<td class="notes_line new"></td>
|
|
<td class="notes_content parallel new">
|
|
<div
|
|
v-if="shouldRenderDiscussions(line, 'right')"
|
|
class="content"
|
|
>
|
|
<diff-discussions
|
|
:discussions="discussionsByLineCode[line.right.lineCode]"
|
|
/>
|
|
</div>
|
|
<diff-line-note-form
|
|
v-if="diffLineCommentForms[line.right.lineCode] &&
|
|
diffLineCommentForms[line.right.lineCode] && line.right.type"
|
|
:diff-file="diffFile"
|
|
:diff-lines="diffLines"
|
|
:line="line.right"
|
|
:note-target-line="diffLines[index].right"
|
|
position="right"
|
|
/>
|
|
</td>
|
|
</tr>
|
|
</template>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</template>
|