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')
-rw-r--r--app/assets/javascripts/diffs/components/app.vue4
-rw-r--r--app/assets/javascripts/diffs/components/collapsed_files_warning.vue2
-rw-r--r--app/assets/javascripts/diffs/components/commit_item.vue10
-rw-r--r--app/assets/javascripts/diffs/components/commit_widget.vue13
-rw-r--r--app/assets/javascripts/diffs/components/compare_dropdown_layout.vue2
-rw-r--r--app/assets/javascripts/diffs/components/compare_versions.vue1
-rw-r--r--app/assets/javascripts/diffs/components/diff_content.vue8
-rw-r--r--app/assets/javascripts/diffs/components/diff_file.vue46
-rw-r--r--app/assets/javascripts/diffs/components/diff_file_header.vue212
-rw-r--r--app/assets/javascripts/diffs/components/diff_row_utils.js99
-rw-r--r--app/assets/javascripts/diffs/components/diff_stats.vue2
-rw-r--r--app/assets/javascripts/diffs/components/diff_table_cell.vue206
-rw-r--r--app/assets/javascripts/diffs/components/edit_button.vue64
-rw-r--r--app/assets/javascripts/diffs/components/inline_diff_table_row.vue95
-rw-r--r--app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue8
-rw-r--r--app/assets/javascripts/diffs/components/parallel_diff_table_row.vue182
16 files changed, 327 insertions, 627 deletions
diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue
index dd5addbf1e3..085f951147f 100644
--- a/app/assets/javascripts/diffs/components/app.vue
+++ b/app/assets/javascripts/diffs/components/app.vue
@@ -474,7 +474,7 @@ export default {
<div
v-if="showTreeList"
:style="{ width: `${treeWidth}px` }"
- class="diff-tree-list js-diff-tree-list mr-3"
+ class="diff-tree-list js-diff-tree-list px-3 pr-md-0"
>
<panel-resizer
:size.sync="treeWidth"
@@ -487,7 +487,7 @@ export default {
<tree-list :hide-file-stats="hideFileStats" />
</div>
<div
- class="diff-files-holder"
+ class="col-12 col-md-auto diff-files-holder"
:class="{
[CENTERED_LIMITED_CONTAINER_CLASSES]: isLimitedContainer,
}"
diff --git a/app/assets/javascripts/diffs/components/collapsed_files_warning.vue b/app/assets/javascripts/diffs/components/collapsed_files_warning.vue
index dded3643115..270bbfb99b7 100644
--- a/app/assets/javascripts/diffs/components/collapsed_files_warning.vue
+++ b/app/assets/javascripts/diffs/components/collapsed_files_warning.vue
@@ -50,7 +50,7 @@ export default {
</script>
<template>
- <div v-if="!isDismissed" data-testid="root" :class="containerClasses">
+ <div v-if="!isDismissed" data-testid="root" :class="containerClasses" class="col-12">
<gl-alert
:dismissible="true"
:title="__('Some changes are not shown')"
diff --git a/app/assets/javascripts/diffs/components/commit_item.vue b/app/assets/javascripts/diffs/components/commit_item.vue
index 23669eecce2..09abdbe25d7 100644
--- a/app/assets/javascripts/diffs/components/commit_item.vue
+++ b/app/assets/javascripts/diffs/components/commit_item.vue
@@ -1,7 +1,7 @@
<script>
/* eslint-disable vue/no-v-html */
import { mapActions } from 'vuex';
-import { GlButtonGroup, GlButton, GlIcon, GlTooltipDirective } from '@gitlab/ui';
+import { GlButtonGroup, GlButton, GlTooltipDirective, GlIcon } from '@gitlab/ui';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
@@ -182,14 +182,14 @@ export default {
:endpoint="commit.pipeline_status_path"
class="d-inline-flex"
/>
- <div class="commit-sha-group">
- <div class="label label-monospace monospace" v-text="commit.short_id"></div>
+ <gl-button-group class="gl-ml-4" data-testid="commit-sha-group">
+ <gl-button label class="gl-font-monospace" v-text="commit.short_id" />
<clipboard-button
:text="commit.id"
:title="__('Copy commit SHA')"
- class="btn btn-default"
+ class="input-group-text"
/>
- </div>
+ </gl-button-group>
<div
v-if="hasNeighborCommits && glFeatures.mrCommitNeighborNav"
class="commit-nav-buttons ml-3"
diff --git a/app/assets/javascripts/diffs/components/commit_widget.vue b/app/assets/javascripts/diffs/components/commit_widget.vue
index 5c7e84bd87c..b1a2b2a72ea 100644
--- a/app/assets/javascripts/diffs/components/commit_widget.vue
+++ b/app/assets/javascripts/diffs/components/commit_widget.vue
@@ -1,19 +1,6 @@
<script>
import CommitItem from './commit_item.vue';
-/**
- * CommitWidget
- *
- * -----------------------------------------------------------------
- * WARNING: Please keep changes up-to-date with the following files:
- * - `views/projects/merge_requests/diffs/_commit_widget.html.haml`
- * -----------------------------------------------------------------
- *
- * This Component was cloned from a HAML view. For the time being,
- * they coexist, but there is an issue to remove the duplication.
- * https://gitlab.com/gitlab-org/gitlab-foss/issues/51613
- *
- */
export default {
components: {
CommitItem,
diff --git a/app/assets/javascripts/diffs/components/compare_dropdown_layout.vue b/app/assets/javascripts/diffs/components/compare_dropdown_layout.vue
index 8263e938e69..adef5d94624 100644
--- a/app/assets/javascripts/diffs/components/compare_dropdown_layout.vue
+++ b/app/assets/javascripts/diffs/components/compare_dropdown_layout.vue
@@ -32,7 +32,7 @@ export default {
<gl-icon :size="12" name="angle-down" class="position-absolute" />
</a>
<div class="dropdown-menu dropdown-select dropdown-menu-selectable">
- <div class="dropdown-content">
+ <div class="dropdown-content" data-qa-selector="dropdown_content">
<ul>
<li v-for="version in versions" :key="version.id">
<a :class="{ 'is-active': version.selected }" :href="version.href">
diff --git a/app/assets/javascripts/diffs/components/compare_versions.vue b/app/assets/javascripts/diffs/components/compare_versions.vue
index b94874c5644..b1ebd8e6ebc 100644
--- a/app/assets/javascripts/diffs/components/compare_versions.vue
+++ b/app/assets/javascripts/diffs/components/compare_versions.vue
@@ -100,6 +100,7 @@ export default {
<compare-dropdown-layout
:versions="diffCompareDropdownTargetVersions"
class="mr-version-compare-dropdown"
+ data-qa-selector="target_version_dropdown"
/>
</template>
<template #source>
diff --git a/app/assets/javascripts/diffs/components/diff_content.vue b/app/assets/javascripts/diffs/components/diff_content.vue
index 9ecb9a44443..e68260b3e62 100644
--- a/app/assets/javascripts/diffs/components/diff_content.vue
+++ b/app/assets/javascripts/diffs/components/diff_content.vue
@@ -85,11 +85,9 @@ export default {
},
},
updated() {
- if (window.gon?.features?.codeNavigation) {
- this.$nextTick(() => {
- eventHub.$emit('showBlobInteractionZones', this.diffFile.new_path);
- });
- }
+ this.$nextTick(() => {
+ eventHub.$emit('showBlobInteractionZones', this.diffFile.new_path);
+ });
},
methods: {
...mapActions('diffs', ['saveDiffDiscussion', 'closeDiffFileCommentForm']),
diff --git a/app/assets/javascripts/diffs/components/diff_file.vue b/app/assets/javascripts/diffs/components/diff_file.vue
index 9a7ed76bad3..529723a349d 100644
--- a/app/assets/javascripts/diffs/components/diff_file.vue
+++ b/app/assets/javascripts/diffs/components/diff_file.vue
@@ -1,32 +1,26 @@
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
import { escape } from 'lodash';
-import { GlButton, GlLoadingIcon, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
+import { GlLoadingIcon, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
-import { sprintf } from '~/locale';
+import { __, sprintf } from '~/locale';
import { deprecatedCreateFlash as createFlash } from '~/flash';
import { hasDiff } from '~/helpers/diffs_helper';
import eventHub from '../../notes/event_hub';
import DiffFileHeader from './diff_file_header.vue';
import DiffContent from './diff_content.vue';
import { diffViewerErrors } from '~/ide/constants';
-import { GENERIC_ERROR, DIFF_FILE } from '../i18n';
export default {
components: {
DiffFileHeader,
DiffContent,
- GlButton,
GlLoadingIcon,
},
directives: {
SafeHtml,
},
mixins: [glFeatureFlagsMixin()],
- i18n: {
- genericError: GENERIC_ERROR,
- ...DIFF_FILE,
- },
props: {
file: {
type: Object,
@@ -50,7 +44,7 @@ export default {
return {
isLoadingCollapsedDiff: false,
forkMessageVisible: false,
- isCollapsed: this.file.viewer.collapsed || false,
+ isCollapsed: this.file.viewer.automaticallyCollapsed || false,
};
},
computed: {
@@ -59,7 +53,7 @@ export default {
...mapGetters('diffs', ['getDiffFileDiscussions']),
viewBlobLink() {
return sprintf(
- this.$options.i18n.blobView,
+ __('You can %{linkStart}view the blob%{linkEnd} instead.'),
{
linkStart: `<a href="${escape(this.file.view_path)}">`,
linkEnd: '</a>',
@@ -81,7 +75,9 @@ export default {
},
forkMessage() {
return sprintf(
- this.$options.i18n.editInFork,
+ __(
+ "You're not allowed to %{tag_start}edit%{tag_end} files in this project directly. Please fork this project, make your changes there, and submit a merge request.",
+ ),
{
tag_start: '<span class="js-file-fork-suggestion-section-action">',
tag_end: '</span>',
@@ -100,16 +96,16 @@ export default {
},
'file.file_hash': {
handler: function watchFileHash() {
- if (this.viewDiffsFileByFile && this.file.viewer.collapsed) {
+ if (this.viewDiffsFileByFile && this.file.viewer.automaticallyCollapsed) {
this.isCollapsed = false;
this.handleLoadCollapsedDiff();
} else {
- this.isCollapsed = this.file.viewer.collapsed || false;
+ this.isCollapsed = this.file.viewer.automaticallyCollapsed || false;
}
},
immediate: true,
},
- 'file.viewer.collapsed': function setIsCollapsed(newVal) {
+ 'file.viewer.automaticallyCollapsed': function setIsCollapsed(newVal) {
if (!this.viewDiffsFileByFile) {
this.isCollapsed = newVal;
}
@@ -152,7 +148,7 @@ export default {
})
.catch(() => {
this.isLoadingCollapsedDiff = false;
- createFlash(this.$options.i18n.genericError);
+ createFlash(__('Something went wrong on our end. Please try again!'));
});
},
showForkMessage() {
@@ -192,14 +188,14 @@ export default {
<a
:href="file.fork_path"
class="js-fork-suggestion-button btn btn-grouped btn-inverted btn-success"
- >{{ $options.i18n.fork }}</a
+ >{{ __('Fork') }}</a
>
<button
class="js-cancel-fork-suggestion-button btn btn-grouped"
type="button"
@click="hideForkMessage"
>
- {{ $options.i18n.cancel }}
+ {{ __('Cancel') }}
</button>
</div>
<gl-loading-icon v-if="showLoadingIcon" class="diff-content loading" />
@@ -209,17 +205,11 @@ export default {
<div v-safe-html="errorMessage" class="nothing-here-block"></div>
</div>
<template v-else>
- <div v-show="isCollapsed" class="gl-p-7 gl-text-center collapsed-file-warning">
- <p class="gl-mb-8 gl-mt-5">
- {{ $options.i18n.collapsed }}
- </p>
- <gl-button
- class="gl-alert-action gl-mb-5"
- data-testid="expandButton"
- @click="handleToggle"
- >
- {{ $options.i18n.expand }}
- </gl-button>
+ <div v-show="isCollapsed" class="nothing-here-block diff-collapsed">
+ {{ __('This diff is collapsed.') }}
+ <a class="click-to-expand js-click-to-expand" href="#" @click.prevent="handleToggle">{{
+ __('Click to expand it.')
+ }}</a>
</div>
<diff-content
v-show="!isCollapsed && !isFileTooLarge"
diff --git a/app/assets/javascripts/diffs/components/diff_file_header.vue b/app/assets/javascripts/diffs/components/diff_file_header.vue
index fded391cc84..ee8a8737f44 100644
--- a/app/assets/javascripts/diffs/components/diff_file_header.vue
+++ b/app/assets/javascripts/diffs/components/diff_file_header.vue
@@ -1,34 +1,37 @@
<script>
-/* eslint-disable vue/no-v-html */
import { escape } from 'lodash';
import { mapActions, mapGetters } from 'vuex';
import {
- GlDeprecatedButton,
GlTooltipDirective,
GlSafeHtmlDirective,
- GlLoadingIcon,
GlIcon,
GlButton,
+ GlButtonGroup,
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownSectionHeader,
+ GlDropdownDivider,
} from '@gitlab/ui';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import FileIcon from '~/vue_shared/components/file_icon.vue';
import { truncateSha } from '~/lib/utils/text_utility';
import { __, s__, sprintf } from '~/locale';
import { diffViewerModes } from '~/ide/constants';
-import EditButton from './edit_button.vue';
import DiffStats from './diff_stats.vue';
import { scrollToElement } from '~/lib/utils/common_utils';
export default {
components: {
- GlLoadingIcon,
- GlDeprecatedButton,
ClipboardButton,
- EditButton,
GlIcon,
FileIcon,
DiffStats,
GlButton,
+ GlButtonGroup,
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownSectionHeader,
+ GlDropdownDivider,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -69,6 +72,11 @@ export default {
default: false,
},
},
+ data() {
+ return {
+ moreActionsShown: false,
+ };
+ },
computed: {
...mapGetters('diffs', ['diffHasExpandedDiscussions', 'diffHasDiscussions']),
diffContentIDSelector() {
@@ -151,6 +159,13 @@ export default {
}
return s__('MRDiff|Show full file');
},
+ showEditButton() {
+ return (
+ this.diffFile.blob?.readable_text &&
+ !this.diffFile.deleted_file &&
+ (this.diffFile.edit_path || this.diffFile.ide_edit_path)
+ );
+ },
},
methods: {
...mapActions('diffs', [
@@ -162,8 +177,11 @@ export default {
handleToggleFile() {
this.$emit('toggleFile');
},
- showForkMessage() {
- this.$emit('showForkMessage');
+ showForkMessage(e) {
+ if (this.canCurrentUserFork && !this.diffFile.can_modify_blob) {
+ e.preventDefault();
+ this.$emit('showForkMessage');
+ }
},
handleFileNameClick(e) {
const isLinkToOtherPage =
@@ -179,6 +197,9 @@ export default {
}
}
},
+ setMoreActionsShown(val) {
+ this.moreActionsShown = val;
+ },
},
};
</script>
@@ -186,10 +207,11 @@ export default {
<template>
<div
ref="header"
+ :class="{ 'gl-z-dropdown-menu!': moreActionsShown }"
class="js-file-title file-title file-title-flex-parent"
@click.self="handleToggleFile"
>
- <div class="file-header-content">
+ <div class="file-header-content gl-display-flex gl-align-items-center gl-pr-0!">
<gl-icon
v-if="collapsible"
ref="collapseIcon"
@@ -202,7 +224,7 @@ export default {
<a
ref="titleWrapper"
:v-once="!viewDiffsFileByFile"
- class="gl-mr-2"
+ class="gl-mr-2 gl-text-decoration-none!"
:href="titleLink"
@click="handleFileNameClick"
>
@@ -210,20 +232,27 @@ export default {
<span v-if="isFileRenamed">
<strong
v-gl-tooltip
+ v-safe-html="diffFile.old_path_html"
:title="diffFile.old_path"
class="file-title-name"
- v-html="diffFile.old_path_html"
></strong>
<strong
v-gl-tooltip
+ v-safe-html="diffFile.new_path_html"
:title="diffFile.new_path"
class="file-title-name"
- v-html="diffFile.new_path_html"
></strong>
</span>
- <strong v-else v-gl-tooltip :title="filePath" class="file-title-name" data-container="body">
+ <strong
+ v-else
+ v-gl-tooltip
+ :title="filePath"
+ class="file-title-name"
+ data-container="body"
+ data-qa-selector="file_name_content"
+ >
{{ filePath }}
</strong>
</a>
@@ -232,7 +261,8 @@ export default {
:title="__('Copy file path')"
:text="diffFile.file_path"
:gfm="gfmCopyText"
- css-class="btn-default btn-transparent btn-clipboard"
+ data-testid="diff-file-copy-clipboard"
+ category="tertiary"
data-track-event="click_copy_file_button"
data-track-label="diff_copy_file_path_button"
data-track-property="diff_copy_file"
@@ -247,93 +277,95 @@ export default {
<div
v-if="!diffFile.submodule && addMergeRequestButtons"
- class="file-actions d-none d-sm-flex align-items-center flex-wrap"
+ class="file-actions d-flex align-items-center flex-wrap"
>
<diff-stats :added-lines="diffFile.added_lines" :removed-lines="diffFile.removed_lines" />
- <div class="btn-group" role="group">
- <template v-if="diffFile.blob && diffFile.blob.readable_text">
- <span v-gl-tooltip.hover :title="s__('MergeRequests|Toggle comments for this file')">
- <gl-deprecated-button
- ref="toggleDiscussionsButton"
- :disabled="!diffHasDiscussions(diffFile)"
- :class="{ active: diffHasExpandedDiscussions(diffFile) }"
- class="js-btn-vue-toggle-comments btn"
- data-qa-selector="toggle_comments_button"
- data-track-event="click_toggle_comments_button"
- data-track-label="diff_toggle_comments_button"
- data-track-property="diff_toggle_comments"
- type="button"
- @click="toggleFileDiscussionWrappers(diffFile)"
- >
- <gl-icon name="comment" />
- </gl-deprecated-button>
- </span>
-
- <edit-button
- v-if="!diffFile.deleted_file"
- :can-current-user-fork="canCurrentUserFork"
- :edit-path="diffFile.edit_path"
- :can-modify-blob="diffFile.can_modify_blob"
- data-track-event="click_toggle_edit_button"
- data-track-label="diff_toggle_edit_button"
- data-track-property="diff_toggle_edit"
- @showForkMessage="showForkMessage"
- />
- </template>
-
- <a
- v-if="diffFile.replaced_view_path"
- ref="replacedFileButton"
- :href="diffFile.replaced_view_path"
- class="btn view-file"
- v-html="viewReplacedFileButtonText"
- >
- </a>
- <gl-deprecated-button
- v-if="!diffFile.is_fully_expanded"
- ref="expandDiffToFullFileButton"
- v-gl-tooltip.hover
- :title="expandDiffToFullFileTitle"
- class="expand-file"
- data-track-event="click_toggle_view_full_button"
- data-track-label="diff_toggle_view_full_button"
- data-track-property="diff_toggle_view_full"
- @click="toggleFullDiff(diffFile.file_path)"
- >
- <gl-loading-icon v-if="diffFile.isLoadingFullFile" color="dark" inline />
- <gl-icon v-else-if="diffFile.isShowingFullFile" name="doc-changes" />
- <gl-icon v-else name="doc-expand" />
- </gl-deprecated-button>
- <gl-deprecated-button
- ref="viewButton"
- v-gl-tooltip.hover
- :href="diffFile.view_path"
- target="_blank"
- class="view-file"
- data-track-event="click_toggle_view_sha_button"
- data-track-label="diff_toggle_view_sha_button"
- data-track-property="diff_toggle_view_sha"
- :title="viewFileButtonText"
- >
- <gl-icon name="doc-text" />
- </gl-deprecated-button>
-
- <a
+ <gl-button-group class="gl-pt-0!">
+ <gl-button
v-if="diffFile.external_url"
ref="externalLink"
v-gl-tooltip.hover
:href="diffFile.external_url"
:title="`View on ${diffFile.formatted_external_url}`"
target="_blank"
- rel="noopener noreferrer"
data-track-event="click_toggle_external_button"
data-track-label="diff_toggle_external_button"
data-track-property="diff_toggle_external"
- class="btn btn-file-option"
+ icon="external-link"
+ />
+ <gl-dropdown
+ v-gl-tooltip.hover.focus="__('More actions')"
+ right
+ toggle-class="btn-icon js-diff-more-actions"
+ class="gl-pt-0!"
+ @show="setMoreActionsShown(true)"
+ @hidden="setMoreActionsShown(false)"
>
- <gl-icon name="external-link" />
- </a>
- </div>
+ <template #button-content>
+ <gl-icon name="ellipsis_v" class="mr-0" />
+ <span class="sr-only">{{ __('More actions') }}</span>
+ </template>
+ <gl-dropdown-section-header>
+ {{ __('More actions') }}
+ </gl-dropdown-section-header>
+ <gl-dropdown-item
+ v-if="diffFile.replaced_view_path"
+ ref="replacedFileButton"
+ v-safe-html="viewReplacedFileButtonText"
+ :href="diffFile.replaced_view_path"
+ target="_blank"
+ />
+ <gl-dropdown-item ref="viewButton" :href="diffFile.view_path" target="_blank">
+ {{ viewFileButtonText }}
+ </gl-dropdown-item>
+ <template v-if="showEditButton">
+ <gl-dropdown-item
+ v-if="diffFile.edit_path"
+ ref="editButton"
+ :href="diffFile.edit_path"
+ class="js-edit-blob"
+ @click="showForkMessage"
+ >
+ {{ __('Edit in single-file editor') }}
+ </gl-dropdown-item>
+ <gl-dropdown-item
+ v-if="diffFile.edit_path"
+ ref="ideEditButton"
+ :href="diffFile.ide_edit_path"
+ class="js-ide-edit-blob"
+ >
+ {{ __('Edit in Web IDE') }}
+ </gl-dropdown-item>
+ </template>
+
+ <template v-if="!diffFile.viewer.automaticallyCollapsed">
+ <gl-dropdown-divider
+ v-if="!diffFile.is_fully_expanded || diffHasDiscussions(diffFile)"
+ />
+
+ <gl-dropdown-item
+ v-if="diffHasDiscussions(diffFile)"
+ ref="toggleDiscussionsButton"
+ data-qa-selector="toggle_comments_button"
+ @click="toggleFileDiscussionWrappers(diffFile)"
+ >
+ <template v-if="diffHasExpandedDiscussions(diffFile)">
+ {{ __('Hide comments on this file') }}
+ </template>
+ <template v-else>
+ {{ __('Show comments on this file') }}
+ </template>
+ </gl-dropdown-item>
+ <gl-dropdown-item
+ v-if="!diffFile.is_fully_expanded"
+ ref="expandDiffToFullFileButton"
+ @click="toggleFullDiff(diffFile.file_path)"
+ >
+ {{ expandDiffToFullFileTitle }}
+ </gl-dropdown-item>
+ </template>
+ </gl-dropdown>
+ </gl-button-group>
</div>
<div
diff --git a/app/assets/javascripts/diffs/components/diff_row_utils.js b/app/assets/javascripts/diffs/components/diff_row_utils.js
new file mode 100644
index 00000000000..998320c3245
--- /dev/null
+++ b/app/assets/javascripts/diffs/components/diff_row_utils.js
@@ -0,0 +1,99 @@
+import { getParameterByName, parseBoolean } from '~/lib/utils/common_utils';
+import { __ } from '~/locale';
+import {
+ MATCH_LINE_TYPE,
+ CONTEXT_LINE_TYPE,
+ LINE_HOVER_CLASS_NAME,
+ OLD_NO_NEW_LINE_TYPE,
+ NEW_NO_NEW_LINE_TYPE,
+ EMPTY_CELL_TYPE,
+} from '../constants';
+
+export const isHighlighted = (state, line, isCommented) => {
+ if (isCommented) return true;
+
+ const lineCode = line?.line_code;
+ return lineCode ? lineCode === state.diffs.highlightedRow : false;
+};
+
+export const isContextLine = type => type === CONTEXT_LINE_TYPE;
+
+export const isMatchLine = type => type === MATCH_LINE_TYPE;
+
+export const isMetaLine = type =>
+ [OLD_NO_NEW_LINE_TYPE, NEW_NO_NEW_LINE_TYPE, EMPTY_CELL_TYPE].includes(type);
+
+export const shouldRenderCommentButton = (
+ isLoggedIn,
+ isCommentButtonRendered,
+ featureMergeRefHeadComments = false,
+) => {
+ if (!isCommentButtonRendered) {
+ return false;
+ }
+
+ if (isLoggedIn) {
+ const isDiffHead = parseBoolean(getParameterByName('diff_head'));
+ return !isDiffHead || featureMergeRefHeadComments;
+ }
+
+ return false;
+};
+
+export const hasDiscussions = line => line?.discussions?.length > 0;
+
+export const lineHref = line => `#${line?.line_code || ''}`;
+
+export const lineCode = line => {
+ if (!line) return undefined;
+ return line.line_code || line.left?.line_code || line.right?.line_code;
+};
+
+export const classNameMapCell = (line, hll, isLoggedIn, isHover) => {
+ if (!line) return [];
+ const { type } = line;
+
+ return [
+ type,
+ {
+ hll,
+ [LINE_HOVER_CLASS_NAME]: isLoggedIn && isHover && !isContextLine(type) && !isMetaLine(type),
+ },
+ ];
+};
+
+export const addCommentTooltip = line => {
+ let tooltip;
+ if (!line) return tooltip;
+
+ tooltip = __('Add a comment to this line');
+ const brokenSymlinks = line.commentsDisabled;
+
+ if (brokenSymlinks) {
+ if (brokenSymlinks.wasSymbolic || brokenSymlinks.isSymbolic) {
+ tooltip = __(
+ 'Commenting on symbolic links that replace or are replaced by files is currently not supported.',
+ );
+ } else if (brokenSymlinks.wasReal || brokenSymlinks.isReal) {
+ tooltip = __(
+ 'Commenting on files that replace or are replaced by symbolic links is currently not supported.',
+ );
+ }
+ }
+
+ return tooltip;
+};
+
+export const parallelViewLeftLineType = (line, hll) => {
+ if (line?.right?.type === NEW_NO_NEW_LINE_TYPE) {
+ return OLD_NO_NEW_LINE_TYPE;
+ }
+
+ const lineTypeClass = line?.left ? line.left.type : EMPTY_CELL_TYPE;
+
+ return [lineTypeClass, { hll }];
+};
+
+export const shouldShowCommentButton = (hover, context, meta, discussions) => {
+ return hover && !context && !meta && !discussions;
+};
diff --git a/app/assets/javascripts/diffs/components/diff_stats.vue b/app/assets/javascripts/diffs/components/diff_stats.vue
index 05fbbd39fae..f229fc4cf60 100644
--- a/app/assets/javascripts/diffs/components/diff_stats.vue
+++ b/app/assets/javascripts/diffs/components/diff_stats.vue
@@ -42,7 +42,7 @@ export default {
class="diff-stats"
:class="{
'is-compare-versions-header d-none d-lg-inline-flex': isCompareVersionsHeader,
- 'd-inline-flex': !isCompareVersionsHeader,
+ 'd-none d-sm-inline-flex': !isCompareVersionsHeader,
}"
>
<div v-if="hasDiffFiles" class="diff-stats-group">
diff --git a/app/assets/javascripts/diffs/components/diff_table_cell.vue b/app/assets/javascripts/diffs/components/diff_table_cell.vue
deleted file mode 100644
index 49982a81372..00000000000
--- a/app/assets/javascripts/diffs/components/diff_table_cell.vue
+++ /dev/null
@@ -1,206 +0,0 @@
-<script>
-import { mapGetters, mapActions } from 'vuex';
-import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
-import { getParameterByName, parseBoolean } from '~/lib/utils/common_utils';
-import DiffGutterAvatars from './diff_gutter_avatars.vue';
-import { __ } from '~/locale';
-import {
- CONTEXT_LINE_TYPE,
- LINE_POSITION_RIGHT,
- EMPTY_CELL_TYPE,
- OLD_NO_NEW_LINE_TYPE,
- OLD_LINE_TYPE,
- NEW_NO_NEW_LINE_TYPE,
- LINE_HOVER_CLASS_NAME,
-} from '../constants';
-
-export default {
- components: {
- DiffGutterAvatars,
- GlIcon,
- },
- directives: {
- GlTooltip: GlTooltipDirective,
- },
- props: {
- line: {
- type: Object,
- required: true,
- },
- fileHash: {
- type: String,
- required: true,
- },
- isHighlighted: {
- type: Boolean,
- required: true,
- },
- showCommentButton: {
- type: Boolean,
- required: false,
- default: false,
- },
- linePosition: {
- type: String,
- required: false,
- default: '',
- },
- lineType: {
- type: String,
- required: false,
- default: '',
- },
- isBottom: {
- type: Boolean,
- required: false,
- default: false,
- },
- isHover: {
- type: Boolean,
- required: false,
- default: false,
- },
- },
- data() {
- return {
- isCommentButtonRendered: false,
- };
- },
- computed: {
- ...mapGetters(['isLoggedIn']),
- lineCode() {
- return (
- this.line.line_code ||
- (this.line.left && this.line.left.line_code) ||
- (this.line.right && this.line.right.line_code)
- );
- },
- lineHref() {
- return `#${this.line.line_code || ''}`;
- },
- shouldShowCommentButton() {
- return this.isHover && !this.isContextLine && !this.isMetaLine && !this.hasDiscussions;
- },
- hasDiscussions() {
- return this.line.discussions && this.line.discussions.length > 0;
- },
- shouldShowAvatarsOnGutter() {
- if (!this.line.type && this.linePosition === LINE_POSITION_RIGHT) {
- return false;
- }
- return this.showCommentButton && this.hasDiscussions;
- },
- shouldRenderCommentButton() {
- if (!this.isCommentButtonRendered) {
- return false;
- }
-
- if (this.isLoggedIn && this.showCommentButton) {
- const isDiffHead = parseBoolean(getParameterByName('diff_head'));
- return !isDiffHead || gon.features?.mergeRefHeadComments;
- }
-
- return false;
- },
- isContextLine() {
- return this.line.type === CONTEXT_LINE_TYPE;
- },
- isMetaLine() {
- const { type } = this.line;
-
- return (
- type === OLD_NO_NEW_LINE_TYPE || type === NEW_NO_NEW_LINE_TYPE || type === EMPTY_CELL_TYPE
- );
- },
- classNameMap() {
- const { type } = this.line;
-
- return [
- type,
- {
- hll: this.isHighlighted,
- [LINE_HOVER_CLASS_NAME]:
- this.isLoggedIn && this.isHover && !this.isContextLine && !this.isMetaLine,
- },
- ];
- },
- lineNumber() {
- return this.lineType === OLD_LINE_TYPE ? this.line.old_line : this.line.new_line;
- },
- addCommentTooltip() {
- const brokenSymlinks = this.line.commentsDisabled;
- let tooltip = __('Add a comment to this line');
-
- if (brokenSymlinks) {
- if (brokenSymlinks.wasSymbolic || brokenSymlinks.isSymbolic) {
- tooltip = __(
- 'Commenting on symbolic links that replace or are replaced by files is currently not supported.',
- );
- } else if (brokenSymlinks.wasReal || brokenSymlinks.isReal) {
- tooltip = __(
- 'Commenting on files that replace or are replaced by symbolic links is currently not supported.',
- );
- }
- }
-
- return tooltip;
- },
- },
- mounted() {
- this.unwatchShouldShowCommentButton = this.$watch('shouldShowCommentButton', newVal => {
- if (newVal) {
- this.isCommentButtonRendered = true;
- this.unwatchShouldShowCommentButton();
- }
- });
- },
- beforeDestroy() {
- this.unwatchShouldShowCommentButton();
- },
- methods: {
- ...mapActions('diffs', ['showCommentForm', 'setHighlightedRow', 'toggleLineDiscussions']),
- handleCommentButton() {
- this.showCommentForm({ lineCode: this.line.line_code, fileHash: this.fileHash });
- },
- },
-};
-</script>
-
-<template>
- <td ref="td" :class="classNameMap">
- <span
- ref="addNoteTooltip"
- v-gl-tooltip
- class="add-diff-note tooltip-wrapper"
- :title="addCommentTooltip"
- >
- <button
- v-if="shouldRenderCommentButton"
- v-show="shouldShowCommentButton"
- ref="addDiffNoteButton"
- type="button"
- class="add-diff-note note-button js-add-diff-note-button qa-diff-comment"
- :disabled="line.commentsDisabled"
- @click="handleCommentButton"
- >
- <gl-icon :size="12" name="comment" />
- </button>
- </span>
- <a
- v-if="lineNumber"
- ref="lineNumberRef"
- :data-linenumber="lineNumber"
- :href="lineHref"
- @click="setHighlightedRow(lineCode)"
- >
- </a>
- <diff-gutter-avatars
- v-if="shouldShowAvatarsOnGutter"
- :discussions="line.discussions"
- :discussions-expanded="line.discussionsExpanded"
- @toggleLineDiscussions="
- toggleLineDiscussions({ lineCode, fileHash, expanded: !line.discussionsExpanded })
- "
- />
- </td>
-</template>
diff --git a/app/assets/javascripts/diffs/components/edit_button.vue b/app/assets/javascripts/diffs/components/edit_button.vue
deleted file mode 100644
index ff1af5569dc..00000000000
--- a/app/assets/javascripts/diffs/components/edit_button.vue
+++ /dev/null
@@ -1,64 +0,0 @@
-<script>
-import { GlTooltipDirective, GlDeprecatedButton, GlIcon } from '@gitlab/ui';
-import { __ } from '~/locale';
-
-export default {
- components: {
- GlDeprecatedButton,
- GlIcon,
- },
- directives: {
- GlTooltip: GlTooltipDirective,
- },
- props: {
- editPath: {
- type: String,
- required: false,
- default: '',
- },
- canCurrentUserFork: {
- type: Boolean,
- required: true,
- },
- canModifyBlob: {
- type: Boolean,
- required: false,
- default: false,
- },
- },
- computed: {
- tooltipTitle() {
- if (this.isDisabled) {
- return __("Can't edit as source branch was deleted");
- }
-
- return __('Edit file');
- },
- isDisabled() {
- return !this.editPath;
- },
- },
- methods: {
- handleEditClick(evt) {
- if (this.canCurrentUserFork && !this.canModifyBlob) {
- evt.preventDefault();
- this.$emit('showForkMessage');
- }
- },
- },
-};
-</script>
-
-<template>
- <span v-gl-tooltip.top :title="tooltipTitle">
- <gl-deprecated-button
- :href="editPath"
- :disabled="isDisabled"
- :class="{ 'cursor-not-allowed': isDisabled }"
- class="rounded-0 js-edit-blob"
- @click.native="handleEditClick"
- >
- <gl-icon name="pencil" />
- </gl-deprecated-button>
- </span>
-</template>
diff --git a/app/assets/javascripts/diffs/components/inline_diff_table_row.vue b/app/assets/javascripts/diffs/components/inline_diff_table_row.vue
index 7fab750089e..f9d491603cb 100644
--- a/app/assets/javascripts/diffs/components/inline_diff_table_row.vue
+++ b/app/assets/javascripts/diffs/components/inline_diff_table_row.vue
@@ -1,22 +1,9 @@
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
import { GlTooltipDirective, GlIcon, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
-import {
- MATCH_LINE_TYPE,
- NEW_LINE_TYPE,
- OLD_LINE_TYPE,
- CONTEXT_LINE_TYPE,
- CONTEXT_LINE_CLASS_NAME,
- LINE_POSITION_LEFT,
- LINE_POSITION_RIGHT,
- LINE_HOVER_CLASS_NAME,
- OLD_NO_NEW_LINE_TYPE,
- NEW_NO_NEW_LINE_TYPE,
- EMPTY_CELL_TYPE,
-} from '../constants';
-import { __ } from '~/locale';
-import { getParameterByName, parseBoolean } from '~/lib/utils/common_utils';
+import { CONTEXT_LINE_CLASS_NAME } from '../constants';
import DiffGutterAvatars from './diff_gutter_avatars.vue';
+import * as utils from './diff_row_utils';
export default {
components: {
@@ -61,14 +48,11 @@ export default {
...mapGetters('diffs', ['fileLineCoverage']),
...mapState({
isHighlighted(state) {
- if (this.isCommented) return true;
-
- const lineCode = this.line.line_code;
- return lineCode ? lineCode === state.diffs.highlightedRow : false;
+ return utils.isHighlighted(state, this.line, this.isCommented);
},
}),
isContextLine() {
- return this.line.type === CONTEXT_LINE_TYPE;
+ return utils.isContextLine(this.line.type);
},
classNameMap() {
return [
@@ -82,82 +66,48 @@ export default {
return this.line.line_code || `${this.fileHash}_${this.line.old_line}_${this.line.new_line}`;
},
isMatchLine() {
- return this.line.type === MATCH_LINE_TYPE;
+ return utils.isMatchLine(this.line.type);
},
coverageState() {
return this.fileLineCoverage(this.filePath, this.line.new_line);
},
isMetaLine() {
- const { type } = this.line;
-
- return (
- type === OLD_NO_NEW_LINE_TYPE || type === NEW_NO_NEW_LINE_TYPE || type === EMPTY_CELL_TYPE
- );
+ return utils.isMetaLine(this.line.type);
},
classNameMapCell() {
- const { type } = this.line;
-
- return [
- type,
- {
- hll: this.isHighlighted,
- [LINE_HOVER_CLASS_NAME]:
- this.isLoggedIn && this.isHover && !this.isContextLine && !this.isMetaLine,
- },
- ];
+ return utils.classNameMapCell(this.line, this.isHighlighted, this.isLoggedIn, this.isHover);
},
addCommentTooltip() {
- const brokenSymlinks = this.line.commentsDisabled;
- let tooltip = __('Add a comment to this line');
-
- if (brokenSymlinks) {
- if (brokenSymlinks.wasSymbolic || brokenSymlinks.isSymbolic) {
- tooltip = __(
- 'Commenting on symbolic links that replace or are replaced by files is currently not supported.',
- );
- } else if (brokenSymlinks.wasReal || brokenSymlinks.isReal) {
- tooltip = __(
- 'Commenting on files that replace or are replaced by symbolic links is currently not supported.',
- );
- }
- }
-
- return tooltip;
+ return utils.addCommentTooltip(this.line);
},
shouldRenderCommentButton() {
- if (this.isLoggedIn) {
- const isDiffHead = parseBoolean(getParameterByName('diff_head'));
- return !isDiffHead || gon.features?.mergeRefHeadComments;
- }
-
- return false;
+ return utils.shouldRenderCommentButton(
+ this.isLoggedIn,
+ true,
+ gon.features?.mergeRefHeadComments,
+ );
},
shouldShowCommentButton() {
- return this.isHover && !this.isContextLine && !this.isMetaLine && !this.hasDiscussions;
+ return utils.shouldShowCommentButton(
+ this.isHover,
+ this.isContextLine,
+ this.isMetaLine,
+ this.hasDiscussions,
+ );
},
hasDiscussions() {
- return this.line.discussions && this.line.discussions.length > 0;
+ return utils.hasDiscussions(this.line);
},
lineHref() {
- return `#${this.line.line_code || ''}`;
+ return utils.lineHref(this.line);
},
lineCode() {
- return (
- this.line.line_code ||
- (this.line.left && this.line.left.line_code) ||
- (this.line.right && this.line.right.line_code)
- );
+ return utils.lineCode(this.line);
},
shouldShowAvatarsOnGutter() {
return this.hasDiscussions;
},
},
- created() {
- this.newLineType = NEW_LINE_TYPE;
- this.oldLineType = OLD_LINE_TYPE;
- this.linePositionLeft = LINE_POSITION_LEFT;
- this.linePositionRight = LINE_POSITION_RIGHT;
- },
mounted() {
this.scrollToLineIfNeededInline(this.line);
},
@@ -242,6 +192,7 @@ export default {
class="line-coverage"
></td>
<td
+ :key="line.line_code"
v-safe-html="line.rich_text"
:class="[
line.type,
diff --git a/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue b/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue
index b525490f7cc..127e3f214cf 100644
--- a/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue
+++ b/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue
@@ -113,8 +113,8 @@ export default {
},
methods: {
...mapActions('diffs', ['showCommentForm']),
- showNewDiscussionForm() {
- this.showCommentForm({ lineCode: this.line.line_code, fileHash: this.diffFileHash });
+ showNewDiscussionForm(lineCode) {
+ this.showCommentForm({ lineCode, fileHash: this.diffFileHash });
},
},
};
@@ -134,7 +134,7 @@ export default {
v-if="!hasDraftLeft"
:has-form="showLeftSideCommentForm"
:render-reply-placeholder="shouldRenderReplyPlaceholderOnLeft"
- @showNewDiscussionForm="showNewDiscussionForm"
+ @showNewDiscussionForm="showNewDiscussionForm(line.left.line_code)"
>
<template #form>
<diff-line-note-form
@@ -159,7 +159,7 @@ export default {
v-if="!hasDraftRight"
:has-form="showRightSideCommentForm"
:render-reply-placeholder="shouldRenderReplyPlaceholderOnRight"
- @showNewDiscussionForm="showNewDiscussionForm"
+ @showNewDiscussionForm="showNewDiscussionForm(line.right.line_code)"
>
<template #form>
<diff-line-note-form
diff --git a/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue b/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue
index 0bf47dc77a6..06dcadb2dc1 100644
--- a/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue
+++ b/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue
@@ -2,21 +2,9 @@
import { mapActions, mapGetters, mapState } from 'vuex';
import $ from 'jquery';
import { GlTooltipDirective, GlIcon, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
-import {
- MATCH_LINE_TYPE,
- NEW_LINE_TYPE,
- OLD_LINE_TYPE,
- CONTEXT_LINE_TYPE,
- CONTEXT_LINE_CLASS_NAME,
- OLD_NO_NEW_LINE_TYPE,
- PARALLEL_DIFF_VIEW_TYPE,
- NEW_NO_NEW_LINE_TYPE,
- EMPTY_CELL_TYPE,
- LINE_HOVER_CLASS_NAME,
-} from '../constants';
-import { __ } from '~/locale';
-import { getParameterByName, parseBoolean } from '~/lib/utils/common_utils';
+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: {
@@ -63,20 +51,15 @@ export default {
...mapGetters(['isLoggedIn']),
...mapState({
isHighlighted(state) {
- if (this.isCommented) return true;
-
- const lineCode =
- (this.line.left && this.line.left.line_code) ||
- (this.line.right && this.line.right.line_code);
-
- return lineCode ? lineCode === state.diffs.highlightedRow : false;
+ const line = this.line.left?.line_code ? this.line.left : this.line.right;
+ return utils.isHighlighted(state, line, this.isCommented);
},
}),
isContextLineLeft() {
- return this.line.left && this.line.left.type === CONTEXT_LINE_TYPE;
+ return utils.isContextLine(this.line.left?.type);
},
isContextLineRight() {
- return this.line.right && this.line.right.type === CONTEXT_LINE_TYPE;
+ return utils.isContextLine(this.line.right?.type);
},
classNameMap() {
return {
@@ -85,157 +68,84 @@ export default {
};
},
parallelViewLeftLineType() {
- if (this.line.right && this.line.right.type === NEW_NO_NEW_LINE_TYPE) {
- return OLD_NO_NEW_LINE_TYPE;
- }
-
- const lineTypeClass = this.line.left ? this.line.left.type : EMPTY_CELL_TYPE;
-
- return [
- lineTypeClass,
- {
- hll: this.isHighlighted,
- },
- ];
+ return utils.parallelViewLeftLineType(this.line, this.isHighlighted);
},
isMatchLineLeft() {
- return this.line.left && this.line.left.type === MATCH_LINE_TYPE;
+ return utils.isMatchLine(this.line.left?.type);
},
isMatchLineRight() {
- return this.line.right && this.line.right.type === MATCH_LINE_TYPE;
+ return utils.isMatchLine(this.line.right?.type);
},
coverageState() {
return this.fileLineCoverage(this.filePath, this.line.right.new_line);
},
classNameMapCellLeft() {
- const { type } = this.line.left;
-
- return [
- type,
- {
- hll: this.isHighlighted,
- [LINE_HOVER_CLASS_NAME]:
- this.isLoggedIn && this.isLeftHover && !this.isContextLineLeft && !this.isMetaLineLeft,
- },
- ];
+ return utils.classNameMapCell(
+ this.line.left,
+ this.isHighlighted,
+ this.isLoggedIn,
+ this.isLeftHover,
+ );
},
classNameMapCellRight() {
- const { type } = this.line.right;
-
- return [
- type,
- {
- hll: this.isHighlighted,
- [LINE_HOVER_CLASS_NAME]:
- this.isLoggedIn &&
- this.isRightHover &&
- !this.isContextLineRight &&
- !this.isMetaLineRight,
- },
- ];
+ return utils.classNameMapCell(
+ this.line.right,
+ this.isHighlighted,
+ this.isLoggedIn,
+ this.isRightHover,
+ );
},
addCommentTooltipLeft() {
- const brokenSymlinks = this.line.left.commentsDisabled;
- let tooltip = __('Add a comment to this line');
-
- if (brokenSymlinks) {
- if (brokenSymlinks.wasSymbolic || brokenSymlinks.isSymbolic) {
- tooltip = __(
- 'Commenting on symbolic links that replace or are replaced by files is currently not supported.',
- );
- } else if (brokenSymlinks.wasReal || brokenSymlinks.isReal) {
- tooltip = __(
- 'Commenting on files that replace or are replaced by symbolic links is currently not supported.',
- );
- }
- }
-
- return tooltip;
+ return utils.addCommentTooltip(this.line.left);
},
addCommentTooltipRight() {
- const brokenSymlinks = this.line.right.commentsDisabled;
- let tooltip = __('Add a comment to this line');
-
- if (brokenSymlinks) {
- if (brokenSymlinks.wasSymbolic || brokenSymlinks.isSymbolic) {
- tooltip = __(
- 'Commenting on symbolic links that replace or are replaced by files is currently not supported.',
- );
- } else if (brokenSymlinks.wasReal || brokenSymlinks.isReal) {
- tooltip = __(
- 'Commenting on files that replace or are replaced by symbolic links is currently not supported.',
- );
- }
- }
-
- return tooltip;
+ return utils.addCommentTooltip(this.line.right);
},
shouldRenderCommentButton() {
- if (!this.isCommentButtonRendered) {
- return false;
- }
-
- if (this.isLoggedIn) {
- const isDiffHead = parseBoolean(getParameterByName('diff_head'));
- return !isDiffHead || gon.features?.mergeRefHeadComments;
- }
-
- return false;
+ return utils.shouldRenderCommentButton(
+ this.isLoggedIn,
+ this.isCommentButtonRendered,
+ gon.features?.mergeRefHeadComments,
+ );
},
shouldShowCommentButtonLeft() {
- return (
- this.isLeftHover &&
- !this.isContextLineLeft &&
- !this.isMetaLineLeft &&
- !this.hasDiscussionsLeft
+ return utils.shouldShowCommentButton(
+ this.isLeftHover,
+ this.isContextLineLeft,
+ this.isMetaLineLeft,
+ this.hasDiscussionsLeft,
);
},
shouldShowCommentButtonRight() {
- return (
- this.isRightHover &&
- !this.isContextLineRight &&
- !this.isMetaLineRight &&
- !this.hasDiscussionsRight
+ return utils.shouldShowCommentButton(
+ this.isRightHover,
+ this.isContextLineRight,
+ this.isMetaLineRight,
+ this.hasDiscussionsRight,
);
},
hasDiscussionsLeft() {
- return this.line.left?.discussions?.length > 0;
+ return utils.hasDiscussions(this.line.left);
},
hasDiscussionsRight() {
- return this.line.right?.discussions?.length > 0;
+ return utils.hasDiscussions(this.line.right);
},
lineHrefOld() {
- return `#${this.line.left.line_code || ''}`;
+ return utils.lineHref(this.line.left);
},
lineHrefNew() {
- return `#${this.line.right.line_code || ''}`;
+ return utils.lineHref(this.line.right);
},
lineCode() {
- return (
- (this.line.left && this.line.left.line_code) ||
- (this.line.right && this.line.right.line_code)
- );
+ return utils.lineCode(this.line);
},
isMetaLineLeft() {
- const type = this.line.left?.type;
-
- return (
- type === OLD_NO_NEW_LINE_TYPE || type === NEW_NO_NEW_LINE_TYPE || type === EMPTY_CELL_TYPE
- );
+ return utils.isMetaLine(this.line.left?.type);
},
isMetaLineRight() {
- const type = this.line.right?.type;
-
- return (
- type === OLD_NO_NEW_LINE_TYPE || type === NEW_NO_NEW_LINE_TYPE || type === EMPTY_CELL_TYPE
- );
+ return utils.isMetaLine(this.line.right?.type);
},
},
- created() {
- this.newLineType = NEW_LINE_TYPE;
- this.oldLineType = OLD_LINE_TYPE;
- this.parallelDiffViewType = PARALLEL_DIFF_VIEW_TYPE;
- },
mounted() {
this.scrollToLineIfNeededParallel(this.line);
this.unwatchShouldShowCommentButton = this.$watch(
@@ -341,6 +251,7 @@ export default {
<td :class="parallelViewLeftLineType" class="line-coverage left-side"></td>
<td
:id="line.left.line_code"
+ :key="line.left.line_code"
v-safe-html="line.left.rich_text"
:class="parallelViewLeftLineType"
class="line_content with-coverage parallel left-side"
@@ -401,6 +312,7 @@ export default {
></td>
<td
:id="line.right.line_code"
+ :key="line.right.rich_text"
v-safe-html="line.right.rich_text"
:class="[
line.right.type,