Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/diffs/components/diff_row.vue')
-rw-r--r--app/assets/javascripts/diffs/components/diff_row.vue268
1 files changed, 205 insertions, 63 deletions
diff --git a/app/assets/javascripts/diffs/components/diff_row.vue b/app/assets/javascripts/diffs/components/diff_row.vue
index c0719e2a7d9..db03da966c3 100644
--- a/app/assets/javascripts/diffs/components/diff_row.vue
+++ b/app/assets/javascripts/diffs/components/diff_row.vue
@@ -1,7 +1,16 @@
<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 {
+ CONTEXT_LINE_CLASS_NAME,
+ PARALLEL_DIFF_VIEW_TYPE,
+ CONFLICT_MARKER_OUR,
+ CONFLICT_MARKER_THEIR,
+ CONFLICT_OUR,
+ CONFLICT_THEIR,
+ CONFLICT_MARKER,
+} from '../constants';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import DiffGutterAvatars from './diff_gutter_avatars.vue';
import * as utils from './diff_row_utils';
@@ -14,6 +23,7 @@ export default {
GlTooltip: GlTooltipDirective,
SafeHtml,
},
+ mixins: [glFeatureFlagsMixin()],
props: {
fileHash: {
type: String,
@@ -37,6 +47,15 @@ export default {
required: false,
default: false,
},
+ index: {
+ type: Number,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ dragging: false,
+ };
},
computed: {
...mapGetters('diffs', ['fileLineCoverage']),
@@ -44,26 +63,40 @@ export default {
...mapState({
isHighlighted(state) {
const line = this.line.left?.line_code ? this.line.left : this.line.right;
- return utils.isHighlighted(state, line, this.isCommented);
+ return utils.isHighlighted(state, line, false);
},
}),
classNameMap() {
return {
[CONTEXT_LINE_CLASS_NAME]: this.line.isContextLineLeft,
- [PARALLEL_DIFF_VIEW_TYPE]: true,
+ [PARALLEL_DIFF_VIEW_TYPE]: !this.inline,
+ commented: this.isCommented,
};
},
parallelViewLeftLineType() {
- return utils.parallelViewLeftLineType(this.line, this.isHighlighted);
+ return utils.parallelViewLeftLineType(this.line, this.isHighlighted || this.isCommented);
},
- coverageState() {
+ coverageStateLeft() {
+ if (!this.inline || !this.line.left) return {};
+ return this.fileLineCoverage(this.filePath, this.line.left.new_line);
+ },
+ coverageStateRight() {
+ if (!this.line.right) return {};
return this.fileLineCoverage(this.filePath, this.line.right.new_line);
},
classNameMapCellLeft() {
- return utils.classNameMapCell(this.line.left, this.isHighlighted, this.isLoggedIn);
+ return utils.classNameMapCell({
+ line: this.line.left,
+ hll: this.isHighlighted || this.isCommented,
+ isLoggedIn: this.isLoggedIn,
+ });
},
classNameMapCellRight() {
- return utils.classNameMapCell(this.line.right, this.isHighlighted, this.isLoggedIn);
+ return utils.classNameMapCell({
+ line: this.line.right,
+ hll: this.isHighlighted || this.isCommented,
+ isLoggedIn: this.isLoggedIn,
+ });
},
addCommentTooltipLeft() {
return utils.addCommentTooltip(this.line.left);
@@ -71,6 +104,12 @@ export default {
addCommentTooltipRight() {
return utils.addCommentTooltip(this.line.right);
},
+ emptyCellRightClassMap() {
+ return { conflict_their: this.line.left?.type === CONFLICT_OUR };
+ },
+ emptyCellLeftClassMap() {
+ return { conflict_our: this.line.right?.type === CONFLICT_THEIR };
+ },
shouldRenderCommentButton() {
return (
this.isLoggedIn &&
@@ -80,6 +119,9 @@ export default {
!this.line.hasDiscussionsRight
);
},
+ isLeftConflictMarker() {
+ return [CONFLICT_MARKER_OUR, CONFLICT_MARKER_THEIR].includes(this.line.left?.type);
+ },
},
mounted() {
this.scrollToLineIfNeededParallel(this.line);
@@ -98,7 +140,9 @@ export default {
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));
+ const [lineClass] = ['left-side', 'right-side'].filter((name) =>
+ line.classList.contains(name),
+ );
if (lineClass) {
table.classList.add(`${lineClass}-selected`);
@@ -107,37 +151,75 @@ export default {
handleCommentButton(line) {
this.showCommentForm({ lineCode: line.line_code, fileHash: this.fileHash });
},
+ conflictText(line) {
+ return line.type === CONFLICT_MARKER_THEIR
+ ? this.$options.THEIR_CHANGES
+ : this.$options.OUR_CHANGES;
+ },
+ onDragEnd() {
+ this.dragging = false;
+ if (!this.glFeatures.dragCommentSelection) return;
+
+ this.$emit('stopdragging');
+ },
+ onDragEnter(line, index) {
+ if (!this.glFeatures.dragCommentSelection) return;
+
+ this.$emit('enterdragging', { ...line, index });
+ },
+ onDragStart(line) {
+ this.$root.$emit('bv::hide::tooltip');
+ this.dragging = true;
+ this.$emit('startdragging', line);
+ },
},
+ OUR_CHANGES: 'HEAD//our changes',
+ THEIR_CHANGES: 'origin//their changes',
+ CONFLICT_MARKER,
+ CONFLICT_MARKER_THEIR,
+ CONFLICT_OUR,
+ CONFLICT_THEIR,
};
</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
+ data-testid="left-side"
+ class="diff-grid-left left-side"
+ @dragover.prevent
+ @dragenter="onDragEnter(line.left, index)"
+ @dragend="onDragEnd"
+ >
+ <template v-if="line.left && line.left.type !== $options.CONFLICT_MARKER">
<div
:class="classNameMapCellLeft"
data-testid="leftLineNumber"
- class="diff-td diff-line-num old_line"
+ class="diff-td diff-line-num"
>
- <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)"
+ <template v-if="!isLeftConflictMarker">
+ <span
+ v-if="shouldRenderCommentButton"
+ v-gl-tooltip
+ data-testid="leftCommentButton"
+ class="add-diff-note tooltip-wrapper"
+ :title="addCommentTooltipLeft"
>
- <gl-icon :size="12" name="comment" />
- </button>
- </span>
+ <button
+ :draggable="glFeatures.dragCommentSelection"
+ type="button"
+ class="add-diff-note note-button js-add-diff-note-button qa-diff-comment"
+ :class="{ 'gl-cursor-grab': dragging }"
+ :disabled="line.left.commentsDisabled"
+ @click="handleCommentButton(line.left)"
+ @dragstart="onDragStart({ ...line.left, index })"
+ >
+ <gl-icon :size="12" name="comment" />
+ </button>
+ </span>
+ </template>
<a
- v-if="line.left.old_line"
+ v-if="line.left.old_line && line.left.type !== $options.CONFLICT_THEIR"
:data-linenumber="line.left.old_line"
:href="line.lineHrefOld"
@click="setHighlightedRow(line.lineCode)"
@@ -157,52 +239,87 @@ export default {
"
/>
</div>
- <div v-if="inline" :class="classNameMapCellLeft" class="diff-td diff-line-num old_line">
+ <div v-if="inline" :class="classNameMapCellLeft" class="diff-td diff-line-num">
<a
- v-if="line.left.new_line"
+ v-if="line.left.new_line && line.left.type !== $options.CONFLICT_OUR"
:data-linenumber="line.left.new_line"
:href="line.lineHrefOld"
@click="setHighlightedRow(line.lineCode)"
>
</a>
</div>
- <div :class="parallelViewLeftLineType" class="diff-td line-coverage left-side"></div>
+ <div
+ v-gl-tooltip.hover
+ :title="coverageStateLeft.text"
+ :class="[...parallelViewLeftLineType, coverageStateLeft.class]"
+ 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"
+ :class="[parallelViewLeftLineType, { parallel: !inline }]"
+ class="diff-td line_content with-coverage left-side"
data-testid="leftContent"
@mousedown="handleParallelLineMouseDown"
- ></div>
+ >
+ <strong v-if="isLeftConflictMarker">{{ conflictText(line.left) }}</strong>
+ <span v-else v-safe-html="line.left.rich_text"></span>
+ </div>
</template>
- <template v-else>
- <div data-testid="leftEmptyCell" class="diff-td diff-line-num old_line empty-cell"></div>
- <div v-if="inline" 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 v-else-if="!inline || (line.left && line.left.type === $options.CONFLICT_MARKER)">
+ <div
+ data-testid="leftEmptyCell"
+ class="diff-td diff-line-num old_line empty-cell"
+ :class="emptyCellLeftClassMap"
+ >
+ &nbsp;
+ </div>
+ <div
+ v-if="inline"
+ class="diff-td diff-line-num old_line empty-cell"
+ :class="emptyCellLeftClassMap"
+ ></div>
+ <div
+ class="diff-td line-coverage left-side empty-cell"
+ :class="emptyCellLeftClassMap"
+ ></div>
+ <div
+ class="diff-td line_content with-coverage left-side empty-cell"
+ :class="[emptyCellLeftClassMap, { parallel: !inline }]"
+ ></div>
</template>
</div>
- <div v-if="!inline" class="diff-grid-right right-side">
+ <div
+ v-if="!inline"
+ data-testid="right-side"
+ class="diff-grid-right right-side"
+ @dragover.prevent
+ @dragenter="onDragEnter(line.right, index)"
+ @dragend="onDragEnd"
+ >
<template v-if="line.right">
<div :class="classNameMapCellRight" 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)"
+ <template v-if="line.right.type !== $options.CONFLICT_MARKER_THEIR">
+ <span
+ v-if="shouldRenderCommentButton"
+ v-gl-tooltip
+ data-testid="rightCommentButton"
+ class="add-diff-note tooltip-wrapper"
+ :title="addCommentTooltipRight"
>
- <gl-icon :size="12" name="comment" />
- </button>
- </span>
+ <button
+ :draggable="glFeatures.dragCommentSelection"
+ type="button"
+ class="add-diff-note note-button js-add-diff-note-button qa-diff-comment"
+ :class="{ 'gl-cursor-grab': dragging }"
+ :disabled="line.right.commentsDisabled"
+ @click="handleCommentButton(line.right)"
+ @dragstart="onDragStart({ ...line.right, index })"
+ >
+ <gl-icon :size="12" name="comment" />
+ </button>
+ </span>
+ </template>
<a
v-if="line.right.new_line"
:data-linenumber="line.right.new_line"
@@ -226,8 +343,12 @@ export default {
</div>
<div
v-gl-tooltip.hover
- :title="coverageState.text"
- :class="[line.right.type, coverageState.class, { hll: isHighlighted }]"
+ :title="coverageStateRight.text"
+ :class="[
+ line.right.type,
+ coverageStateRight.class,
+ { hll: isHighlighted, hll: isCommented },
+ ]"
class="diff-td line-coverage right-side"
></div>
<div
@@ -238,17 +359,38 @@ export default {
line.right.type,
{
hll: isHighlighted,
+ hll: isCommented,
+ parallel: !inline,
},
]"
- class="diff-td line_content with-coverage parallel right-side"
+ class="diff-td line_content with-coverage right-side"
@mousedown="handleParallelLineMouseDown"
- ></div>
+ >
+ <strong v-if="line.right.type === $options.CONFLICT_MARKER_THEIR">{{
+ conflictText(line.right)
+ }}</strong>
+ <span v-else v-safe-html="line.right.rich_text"></span>
+ </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>
+ <div
+ data-testid="rightEmptyCell"
+ class="diff-td diff-line-num old_line empty-cell"
+ :class="emptyCellRightClassMap"
+ ></div>
+ <div
+ v-if="inline"
+ class="diff-td diff-line-num old_line empty-cell"
+ :class="emptyCellRightClassMap"
+ ></div>
+ <div
+ class="diff-td line-coverage right-side empty-cell"
+ :class="emptyCellRightClassMap"
+ ></div>
+ <div
+ class="diff-td line_content with-coverage right-side empty-cell"
+ :class="[emptyCellRightClassMap, { parallel: !inline }]"
+ ></div>
</template>
</div>
</div>