File moved
File moved
File moved
File moved
File moved
File moved
...@@ -24,7 +24,7 @@ const EMPTY_STAGE_TEXTS = { ...@@ -24,7 +24,7 @@ const EMPTY_STAGE_TEXTS = {
'The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.', 'The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.',
), ),
production: __( production: __(
'The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.', 'The total stage shows the time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.',
), ),
}; };
... ...
......
...@@ -115,7 +115,10 @@ export default { ...@@ -115,7 +115,10 @@ export default {
<div role="rowheader" class="table-mobile-header">{{ s__('DeployKeys|Deploy key') }}</div> <div role="rowheader" class="table-mobile-header">{{ s__('DeployKeys|Deploy key') }}</div>
<div class="table-mobile-content qa-key"> <div class="table-mobile-content qa-key">
<strong class="title qa-key-title"> {{ deployKey.title }} </strong> <strong class="title qa-key-title"> {{ deployKey.title }} </strong>
<div class="fingerprint qa-key-fingerprint">{{ deployKey.fingerprint }}</div> <div class="fingerprint" data-qa-selector="key_md5_fingerprint">
{{ __('MD5') }}:{{ deployKey.fingerprint }}
</div>
<div class="fingerprint">{{ __('SHA256') }}:{{ deployKey.fingerprint_sha256 }}</div>
</div> </div>
</div> </div>
<div class="table-section section-30 section-wrap"> <div class="table-section section-30 section-wrap">
... ...
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
import { mapState, mapGetters, mapActions } from 'vuex'; import { mapState, mapGetters, mapActions } from 'vuex';
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } from '@gitlab/ui';
import Mousetrap from 'mousetrap'; import Mousetrap from 'mousetrap';
import Icon from '~/vue_shared/components/icon.vue';
import { __ } from '~/locale'; import { __ } from '~/locale';
import createFlash from '~/flash'; import createFlash from '~/flash';
import PanelResizer from '~/vue_shared/components/panel_resizer.vue'; import PanelResizer from '~/vue_shared/components/panel_resizer.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { isSingleViewStyle } from '~/helpers/diffs_helper';
import eventHub from '../../notes/event_hub'; import eventHub from '../../notes/event_hub';
import CompareVersions from './compare_versions.vue'; import CompareVersions from './compare_versions.vue';
import DiffFile from './diff_file.vue'; import DiffFile from './diff_file.vue';
...@@ -27,7 +27,6 @@ import { ...@@ -27,7 +27,6 @@ import {
export default { export default {
name: 'DiffsApp', name: 'DiffsApp',
components: { components: {
Icon,
CompareVersions, CompareVersions,
DiffFile, DiffFile,
NoChanges, NoChanges,
...@@ -95,8 +94,8 @@ export default { ...@@ -95,8 +94,8 @@ export default {
parseInt(localStorage.getItem(TREE_LIST_WIDTH_STORAGE_KEY), 10) || INITIAL_TREE_WIDTH; parseInt(localStorage.getItem(TREE_LIST_WIDTH_STORAGE_KEY), 10) || INITIAL_TREE_WIDTH;
return { return {
assignedDiscussions: false,
treeWidth, treeWidth,
diffFilesLength: 0,
}; };
}, },
computed: { computed: {
...@@ -114,6 +113,7 @@ export default { ...@@ -114,6 +113,7 @@ export default {
numVisibleFiles: state => state.diffs.size, numVisibleFiles: state => state.diffs.size,
plainDiffPath: state => state.diffs.plainDiffPath, plainDiffPath: state => state.diffs.plainDiffPath,
emailPatchPath: state => state.diffs.emailPatchPath, emailPatchPath: state => state.diffs.emailPatchPath,
retrievingBatches: state => state.diffs.retrievingBatches,
}), }),
...mapState('diffs', ['showTreeList', 'isLoading', 'startVersion']), ...mapState('diffs', ['showTreeList', 'isLoading', 'startVersion']),
...mapGetters('diffs', ['isParallelView', 'currentDiffIndex']), ...mapGetters('diffs', ['isParallelView', 'currentDiffIndex']),
...@@ -144,12 +144,12 @@ export default { ...@@ -144,12 +144,12 @@ export default {
isLimitedContainer() { isLimitedContainer() {
return !this.showTreeList && !this.isParallelView && !this.isFluidLayout; return !this.showTreeList && !this.isParallelView && !this.isFluidLayout;
}, },
shouldSetDiscussions() {
return this.isNotesFetched && !this.assignedDiscussions && !this.isLoading;
},
}, },
watch: { watch: {
diffViewType() { diffViewType() {
if (this.needsReload() || this.needsFirstLoad()) {
this.refetchDiffData();
}
this.adjustView(); this.adjustView();
}, },
shouldShow() { shouldShow() {
...@@ -163,11 +163,6 @@ export default { ...@@ -163,11 +163,6 @@ export default {
}, },
isLoading: 'adjustView', isLoading: 'adjustView',
showTreeList: 'adjustView', showTreeList: 'adjustView',
shouldSetDiscussions(newVal) {
if (newVal) {
this.setDiscussions();
}
},
}, },
mounted() { mounted() {
this.setBaseConfig({ this.setBaseConfig({
...@@ -192,10 +187,24 @@ export default { ...@@ -192,10 +187,24 @@ export default {
}, },
created() { created() {
this.adjustView(); this.adjustView();
eventHub.$once('fetchedNotesData', this.setDiscussions);
eventHub.$once('fetchDiffData', this.fetchData); eventHub.$once('fetchDiffData', this.fetchData);
eventHub.$on('refetchDiffData', this.refetchDiffData); eventHub.$on('refetchDiffData', this.refetchDiffData);
this.CENTERED_LIMITED_CONTAINER_CLASSES = CENTERED_LIMITED_CONTAINER_CLASSES; this.CENTERED_LIMITED_CONTAINER_CLASSES = CENTERED_LIMITED_CONTAINER_CLASSES;
this.unwatchDiscussions = this.$watch(
() => `${this.diffFiles.length}:${this.$store.state.notes.discussions.length}`,
() => this.setDiscussions(),
);
this.unwatchRetrievingBatches = this.$watch(
() => `${this.retrievingBatches}:${this.$store.state.notes.discussions.length}`,
() => {
if (!this.retrievingBatches && this.$store.state.notes.discussions.length) {
this.unwatchDiscussions();
this.unwatchRetrievingBatches();
}
},
);
}, },
beforeDestroy() { beforeDestroy() {
eventHub.$off('fetchDiffData', this.fetchData); eventHub.$off('fetchDiffData', this.fetchData);
...@@ -217,7 +226,6 @@ export default { ...@@ -217,7 +226,6 @@ export default {
'toggleShowTreeList', 'toggleShowTreeList',
]), ]),
refetchDiffData() { refetchDiffData() {
this.assignedDiscussions = false;
this.fetchData(false); this.fetchData(false);
}, },
startDiffRendering() { startDiffRendering() {
...@@ -228,10 +236,21 @@ export default { ...@@ -228,10 +236,21 @@ export default {
{ timeout: 1000 }, { timeout: 1000 },
); );
}, },
needsReload() {
return (
this.glFeatures.singleMrDiffView &&
this.diffFiles.length &&
isSingleViewStyle(this.diffFiles[0])
);
},
needsFirstLoad() {
return this.glFeatures.singleMrDiffView && !this.diffFiles.length;
},
fetchData(toggleTree = true) { fetchData(toggleTree = true) {
if (this.glFeatures.diffsBatchLoad) { if (this.glFeatures.diffsBatchLoad) {
this.fetchDiffFilesMeta() this.fetchDiffFilesMeta()
.then(() => { .then(({ real_size }) => {
this.diffFilesLength = parseInt(real_size, 10);
if (toggleTree) this.hideTreeListIfJustOneFile(); if (toggleTree) this.hideTreeListIfJustOneFile();
this.startDiffRendering(); this.startDiffRendering();
...@@ -241,19 +260,28 @@ export default { ...@@ -241,19 +260,28 @@ export default {
}); });
this.fetchDiffFilesBatch() this.fetchDiffFilesBatch()
.then(() => {
// Guarantee the discussions are assigned after the batch finishes.
// Just watching the length of the discussions or the diff files
// isn't enough, because with split diff loading, neither will
// change when loading the other half of the diff files.
this.setDiscussions();
})
.then(() => this.startDiffRendering()) .then(() => this.startDiffRendering())
.catch(() => { .catch(() => {
createFlash(__('Something went wrong on our end. Please try again!')); createFlash(__('Something went wrong on our end. Please try again!'));
}); });
} else { } else {
this.fetchDiffFiles() this.fetchDiffFiles()
.then(() => { .then(({ real_size }) => {
this.diffFilesLength = parseInt(real_size, 10);
if (toggleTree) { if (toggleTree) {
this.hideTreeListIfJustOneFile(); this.hideTreeListIfJustOneFile();
} }
requestIdleCallback( requestIdleCallback(
() => { () => {
this.setDiscussions();
this.startRenderDiffsQueue(); this.startRenderDiffsQueue();
}, },
{ timeout: 1000 }, { timeout: 1000 },
...@@ -269,9 +297,6 @@ export default { ...@@ -269,9 +297,6 @@ export default {
} }
}, },
setDiscussions() { setDiscussions() {
if (this.shouldSetDiscussions) {
this.assignedDiscussions = true;
requestIdleCallback( requestIdleCallback(
() => () =>
this.assignDiscussionsToDiff() this.assignDiscussionsToDiff()
...@@ -279,7 +304,6 @@ export default { ...@@ -279,7 +304,6 @@ export default {
.then(this.startTaskList), .then(this.startTaskList),
{ timeout: 1000 }, { timeout: 1000 },
); );
}
}, },
adjustView() { adjustView() {
if (this.shouldShow) { if (this.shouldShow) {
...@@ -337,6 +361,7 @@ export default { ...@@ -337,6 +361,7 @@ export default {
:merge-request-diff="mergeRequestDiff" :merge-request-diff="mergeRequestDiff"
:target-branch="targetBranch" :target-branch="targetBranch"
:is-limited-container="isLimitedContainer" :is-limited-container="isLimitedContainer"
:diff-files-length="diffFilesLength"
/> />
<hidden-files-warning <hidden-files-warning
...@@ -349,7 +374,7 @@ export default { ...@@ -349,7 +374,7 @@ export default {
<div <div
:data-can-create-note="getNoteableData.current_user.can_create_note" :data-can-create-note="getNoteableData.current_user.can_create_note"
class="files d-flex prepend-top-default" class="files d-flex"
> >
<div <div
v-show="showTreeList" v-show="showTreeList"
... ...
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue'; import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import CIIcon from '~/vue_shared/components/ci_icon.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import CommitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue'; import CommitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue';
import initUserPopovers from '../../user_popovers'; import initUserPopovers from '../../user_popovers';
...@@ -25,7 +24,6 @@ export default { ...@@ -25,7 +24,6 @@ export default {
UserAvatarLink, UserAvatarLink,
Icon, Icon,
ClipboardButton, ClipboardButton,
CIIcon,
TimeAgoTooltip, TimeAgoTooltip,
CommitPipelineStatus, CommitPipelineStatus,
}, },
... ...
......
<script> <script>
/* eslint-disable @gitlab/vue-i18n/no-bare-strings */
import { mapActions, mapGetters, mapState } from 'vuex'; import { mapActions, mapGetters, mapState } from 'vuex';
import { GlTooltipDirective, GlLink, GlButton } from '@gitlab/ui'; import { GlTooltipDirective, GlLink, GlButton } from '@gitlab/ui';
import { __ } from '~/locale'; import { __ } from '~/locale';
...@@ -42,9 +41,13 @@ export default { ...@@ -42,9 +41,13 @@ export default {
required: false, required: false,
default: false, default: false,
}, },
diffFilesLength: {
type: Number,
required: true,
},
}, },
computed: { computed: {
...mapGetters('diffs', ['hasCollapsedFile', 'diffFilesLength']), ...mapGetters('diffs', ['hasCollapsedFile']),
...mapState('diffs', [ ...mapState('diffs', [
'commit', 'commit',
'showTreeList', 'showTreeList',
...@@ -59,9 +62,6 @@ export default { ...@@ -59,9 +62,6 @@ export default {
showDropdowns() { showDropdowns() {
return !this.commit && this.mergeRequestDiffs.length; return !this.commit && this.mergeRequestDiffs.length;
}, },
fileTreeIcon() {
return this.showTreeList ? 'collapse-left' : 'expand-left';
},
toggleFileBrowserTitle() { toggleFileBrowserTitle() {
return this.showTreeList ? __('Hide file browser') : __('Show file browser'); return this.showTreeList ? __('Hide file browser') : __('Show file browser');
}, },
...@@ -87,7 +87,7 @@ export default { ...@@ -87,7 +87,7 @@ export default {
</script> </script>
<template> <template>
<div class="mr-version-controls border-top border-bottom"> <div class="mr-version-controls border-top">
<div <div
class="mr-version-menus-container content-block" class="mr-version-menus-container content-block"
:class="{ :class="{
...@@ -104,17 +104,17 @@ export default { ...@@ -104,17 +104,17 @@ export default {
:title="toggleFileBrowserTitle" :title="toggleFileBrowserTitle"
@click="toggleShowTreeList" @click="toggleShowTreeList"
> >
<icon :name="fileTreeIcon" /> <icon name="file-tree" />
</button> </button>
<div v-if="showDropdowns" class="d-flex align-items-center compare-versions-container"> <div v-if="showDropdowns" class="d-flex align-items-center compare-versions-container">
Changes between {{ __('Compare') }}
<compare-versions-dropdown <compare-versions-dropdown
:other-versions="mergeRequestDiffs" :other-versions="mergeRequestDiffs"
:merge-request-version="mergeRequestDiff" :merge-request-version="mergeRequestDiff"
:show-commit-count="true" :show-commit-count="true"
class="mr-version-dropdown" class="mr-version-dropdown"
/> />
and {{ __('and') }}
<compare-versions-dropdown <compare-versions-dropdown
:other-versions="comparableDiffs" :other-versions="comparableDiffs"
:base-version-path="baseVersionPath" :base-version-path="baseVersionPath"
... ...
......
...@@ -4,6 +4,7 @@ import _ from 'underscore'; ...@@ -4,6 +4,7 @@ import _ from 'underscore';
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } from '@gitlab/ui';
import { __, sprintf } from '~/locale'; import { __, sprintf } from '~/locale';
import createFlash from '~/flash'; import createFlash from '~/flash';
import { hasDiff } from '~/helpers/diffs_helper';
import eventHub from '../../notes/event_hub'; import eventHub from '../../notes/event_hub';
import DiffFileHeader from './diff_file_header.vue'; import DiffFileHeader from './diff_file_header.vue';
import DiffContent from './diff_content.vue'; import DiffContent from './diff_content.vue';
...@@ -55,12 +56,7 @@ export default { ...@@ -55,12 +56,7 @@ export default {
return this.isLoadingCollapsedDiff || (!this.file.renderIt && !this.isCollapsed); return this.isLoadingCollapsedDiff || (!this.file.renderIt && !this.isCollapsed);
}, },
hasDiff() { hasDiff() {
return ( return hasDiff(this.file);
(this.file.highlighted_diff_lines &&
this.file.parallel_diff_lines &&
this.file.parallel_diff_lines.length > 0) ||
!this.file.blob.readable_text
);
}, },
isFileTooLarge() { isFileTooLarge() {
return this.file.viewer.error === diffViewerErrors.too_large; return this.file.viewer.error === diffViewerErrors.too_large;
... ...
......
<script> <script>
import _ from 'underscore'; import _ from 'underscore';
import { mapActions, mapGetters } from 'vuex'; import { mapActions, mapGetters } from 'vuex';
import { GlButton, GlTooltipDirective, GlTooltip, GlLoadingIcon } from '@gitlab/ui'; import { GlButton, GlTooltipDirective, GlLoadingIcon } from '@gitlab/ui';
import { polyfillSticky } from '~/lib/utils/sticky'; import { polyfillSticky } from '~/lib/utils/sticky';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
...@@ -15,7 +15,6 @@ import { scrollToElement } from '~/lib/utils/common_utils'; ...@@ -15,7 +15,6 @@ import { scrollToElement } from '~/lib/utils/common_utils';
export default { export default {
components: { components: {
GlTooltip,
GlLoadingIcon, GlLoadingIcon,
GlButton, GlButton,
ClipboardButton, ClipboardButton,
...@@ -124,6 +123,20 @@ export default { ...@@ -124,6 +123,20 @@ export default {
} }
return s__('MRDiff|Show full file'); return s__('MRDiff|Show full file');
}, },
changedFile() {
const {
new_path: changed,
deleted_file: deleted,
new_file: tempFile,
...diffFile
} = this.diffFile;
return {
...diffFile,
changed: Boolean(changed),
deleted,
tempFile,
};
},
}, },
mounted() { mounted() {
polyfillSticky(this.$refs.header); polyfillSticky(this.$refs.header);
...@@ -222,7 +235,7 @@ export default { ...@@ -222,7 +235,7 @@ export default {
<div <div
v-if="!diffFile.submodule && addMergeRequestButtons" v-if="!diffFile.submodule && addMergeRequestButtons"
class="file-actions d-none d-sm-block" class="file-actions d-none d-sm-flex align-items-center"
> >
<diff-stats :added-lines="diffFile.added_lines" :removed-lines="diffFile.removed_lines" /> <diff-stats :added-lines="diffFile.added_lines" :removed-lines="diffFile.removed_lines" />
<div class="btn-group" role="group"> <div class="btn-group" role="group">
... ...
......
<script> <script>
import Icon from '~/vue_shared/components/icon.vue';
import { n__ } from '~/locale'; import { n__ } from '~/locale';
export default { export default {
components: { Icon },
props: { props: {
addedLines: { addedLines: {
type: Number, type: Number,
...@@ -21,7 +19,7 @@ export default { ...@@ -21,7 +19,7 @@ export default {
}, },
computed: { computed: {
filesText() { filesText() {
return n__('File', 'Files', this.diffFilesLength); return n__('file', 'files', this.diffFilesLength);
}, },
isCompareVersionsHeader() { isCompareVersionsHeader() {
return Boolean(this.diffFilesLength); return Boolean(this.diffFilesLength);
...@@ -39,14 +37,21 @@ export default { ...@@ -39,14 +37,21 @@ export default {
}" }"
> >
<div v-if="diffFilesLength !== null" class="diff-stats-group"> <div v-if="diffFilesLength !== null" class="diff-stats-group">
<icon name="doc-code" class="diff-stats-icon text-secondary" /> <span class="text-secondary bold">{{ diffFilesLength }} {{ filesText }}</span>
<strong>{{ diffFilesLength }} {{ filesText }}</strong>
</div> </div>
<div class="diff-stats-group cgreen"> <div
<icon name="file-addition" class="diff-stats-icon" /> <strong>{{ addedLines }}</strong> class="diff-stats-group cgreen d-flex align-items-center"
:class="{ bold: isCompareVersionsHeader }"
>
<span>+</span>
<span class="js-file-addition-line">{{ addedLines }}</span>
</div> </div>
<div class="diff-stats-group cred"> <div
<icon name="file-deletion" class="diff-stats-icon" /> <strong>{{ removedLines }}</strong> class="diff-stats-group cred d-flex align-items-center"
:class="{ bold: isCompareVersionsHeader }"
>
<span>-</span>
<span class="js-file-deletion-line">{{ removedLines }}</span>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import Icon from '~/vue_shared/components/icon.vue';
import DiffExpansionCell from './diff_expansion_cell.vue'; import DiffExpansionCell from './diff_expansion_cell.vue';
import { MATCH_LINE_TYPE } from '../constants'; import { MATCH_LINE_TYPE } from '../constants';
export default { export default {
components: { components: {
Icon,
DiffExpansionCell, DiffExpansionCell,
}, },
props: { props: {
... ...
......
...@@ -4,7 +4,6 @@ import { GlTooltipDirective } from '@gitlab/ui'; ...@@ -4,7 +4,6 @@ import { GlTooltipDirective } from '@gitlab/ui';
import { s__, sprintf } from '~/locale'; import { s__, sprintf } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import FileRow from '~/vue_shared/components/file_row.vue'; import FileRow from '~/vue_shared/components/file_row.vue';
import FileRowStats from './file_row_stats.vue';
export default { export default {
directives: { directives: {
...@@ -48,9 +47,6 @@ export default { ...@@ -48,9 +47,6 @@ export default {
return acc; return acc;
}, []); }, []);
}, },
fileRowExtraComponent() {
return this.hideFileStats ? null : FileRowStats;
},
}, },
methods: { methods: {
...mapActions('diffs', ['toggleTreeOpen', 'scrollToFile']), ...mapActions('diffs', ['toggleTreeOpen', 'scrollToFile']),
...@@ -58,8 +54,8 @@ export default { ...@@ -58,8 +54,8 @@ export default {
this.search = ''; this.search = '';
}, },
}, },
searchPlaceholder: sprintf(s__('MergeRequest|Filter files or search with %{modifier_key}+p'), { searchPlaceholder: sprintf(s__('MergeRequest|Search files (%{modifier_key}P)'), {
modifier_key: /Mac/i.test(navigator.userAgent) ? 'cmd' : 'ctrl', modifier_key: /Mac/i.test(navigator.userAgent) ? '⌘' : 'Ctrl+',
}), }),
}; };
</script> </script>
...@@ -97,7 +93,6 @@ export default { ...@@ -97,7 +93,6 @@ export default {
:file="file" :file="file"
:level="0" :level="0"
:hide-extra-on-tree="true" :hide-extra-on-tree="true"
:extra-component="fileRowExtraComponent"
:show-changed-icon="true" :show-changed-icon="true"
@toggleTreeOpen="toggleTreeOpen" @toggleTreeOpen="toggleTreeOpen"
@clickFile="scrollToFile" @clickFile="scrollToFile"
... ...
......
...@@ -64,6 +64,11 @@ export const fetchDiffFiles = ({ state, commit }) => { ...@@ -64,6 +64,11 @@ export const fetchDiffFiles = ({ state, commit }) => {
const urlParams = { const urlParams = {
w: state.showWhitespace ? '0' : '1', w: state.showWhitespace ? '0' : '1',
}; };
let returnData;
if (state.useSingleDiffStyle) {
urlParams.view = state.diffViewType;
}
commit(types.SET_LOADING, true); commit(types.SET_LOADING, true);
...@@ -83,26 +88,42 @@ export const fetchDiffFiles = ({ state, commit }) => { ...@@ -83,26 +88,42 @@ export const fetchDiffFiles = ({ state, commit }) => {
worker.postMessage(state.diffFiles); worker.postMessage(state.diffFiles);
returnData = res.data;
return Vue.nextTick(); return Vue.nextTick();
}) })
.then(handleLocationHash) .then(() => {
handleLocationHash();
return returnData;
})
.catch(() => worker.terminate()); .catch(() => worker.terminate());
}; };
export const fetchDiffFilesBatch = ({ commit, state }) => { export const fetchDiffFilesBatch = ({ commit, state }) => {
const urlParams = {
per_page: DIFFS_PER_PAGE,
w: state.showWhitespace ? '0' : '1',
};
if (state.useSingleDiffStyle) {
urlParams.view = state.diffViewType;
}
commit(types.SET_BATCH_LOADING, true); commit(types.SET_BATCH_LOADING, true);
commit(types.SET_RETRIEVING_BATCHES, true);
const getBatch = page => const getBatch = page =>
axios axios
.get(state.endpointBatch, { .get(state.endpointBatch, {
params: { page, per_page: DIFFS_PER_PAGE, w: state.showWhitespace ? '0' : '1' }, params: { ...urlParams, page },
}) })
.then(({ data: { pagination, diff_files } }) => { .then(({ data: { pagination, diff_files } }) => {
commit(types.SET_DIFF_DATA_BATCH, { diff_files }); commit(types.SET_DIFF_DATA_BATCH, { diff_files });
commit(types.SET_BATCH_LOADING, false); commit(types.SET_BATCH_LOADING, false);
if (!pagination.next_page) commit(types.SET_RETRIEVING_BATCHES, false);
return pagination.next_page; return pagination.next_page;
}) })
.then(nextPage => nextPage && getBatch(nextPage)); .then(nextPage => nextPage && getBatch(nextPage))
.catch(() => commit(types.SET_RETRIEVING_BATCHES, false));
return getBatch() return getBatch()
.then(handleLocationHash) .then(handleLocationHash)
...@@ -131,6 +152,7 @@ export const fetchDiffFilesMeta = ({ commit, state }) => { ...@@ -131,6 +152,7 @@ export const fetchDiffFilesMeta = ({ commit, state }) => {
prepareDiffData(data); prepareDiffData(data);
worker.postMessage(data.diff_files); worker.postMessage(data.diff_files);
return data;
}) })
.catch(() => worker.terminate()); .catch(() => worker.terminate());
}; };
...@@ -147,7 +169,10 @@ export const assignDiscussionsToDiff = ( ...@@ -147,7 +169,10 @@ export const assignDiscussionsToDiff = (
{ commit, state, rootState }, { commit, state, rootState },
discussions = rootState.notes.discussions, discussions = rootState.notes.discussions,
) => { ) => {
const diffPositionByLineCode = getDiffPositionByLineCode(state.diffFiles); const diffPositionByLineCode = getDiffPositionByLineCode(
state.diffFiles,
state.useSingleDiffStyle,
);
const hash = getLocationHash(); const hash = getLocationHash();
discussions discussions
...@@ -336,24 +361,23 @@ export const toggleFileDiscussions = ({ getters, dispatch }, diff) => { ...@@ -336,24 +361,23 @@ export const toggleFileDiscussions = ({ getters, dispatch }, diff) => {
export const toggleFileDiscussionWrappers = ({ commit }, diff) => { export const toggleFileDiscussionWrappers = ({ commit }, diff) => {
const discussionWrappersExpanded = allDiscussionWrappersExpanded(diff); const discussionWrappersExpanded = allDiscussionWrappersExpanded(diff);
let linesWithDiscussions; const lineCodesWithDiscussions = new Set();
if (diff.highlighted_diff_lines) { const { parallel_diff_lines: parallelLines, highlighted_diff_lines: inlineLines } = diff;
linesWithDiscussions = diff.highlighted_diff_lines.filter(line => line.discussions.length); const allLines = inlineLines.concat(
} parallelLines.map(line => line.left),
if (diff.parallel_diff_lines) { parallelLines.map(line => line.right),
linesWithDiscussions = diff.parallel_diff_lines.filter(
line =>
(line.left && line.left.discussions.length) ||
(line.right && line.right.discussions.length),
); );
} const lineHasDiscussion = line => Boolean(line?.discussions.length);
const registerDiscussionLine = line => lineCodesWithDiscussions.add(line.line_code);
allLines.filter(lineHasDiscussion).forEach(registerDiscussionLine);
if (linesWithDiscussions.length) { if (lineCodesWithDiscussions.size) {
linesWithDiscussions.forEach(line => { Array.from(lineCodesWithDiscussions).forEach(lineCode => {
commit(types.TOGGLE_LINE_DISCUSSIONS, { commit(types.TOGGLE_LINE_DISCUSSIONS, {
fileHash: diff.file_hash, fileHash: diff.file_hash,
lineCode: line.line_code,
expanded: !discussionWrappersExpanded, expanded: !discussionWrappersExpanded,
lineCode,
}); });
}); });
} }
... ...
......
...@@ -95,8 +95,6 @@ export const allBlobs = (state, getters) => ...@@ -95,8 +95,6 @@ export const allBlobs = (state, getters) =>
return acc; return acc;
}, []); }, []);
export const diffFilesLength = state => state.diffFiles.length;
export const getCommentFormForDiffFile = state => fileHash => export const getCommentFormForDiffFile = state => fileHash =>
state.commentForms.find(form => form.fileHash === fileHash); state.commentForms.find(form => form.fileHash === fileHash);
... ...
......
...@@ -9,6 +9,7 @@ const defaultViewType = INLINE_DIFF_VIEW_TYPE; ...@@ -9,6 +9,7 @@ const defaultViewType = INLINE_DIFF_VIEW_TYPE;
export default () => ({ export default () => ({
isLoading: true, isLoading: true,
isBatchLoading: false, isBatchLoading: false,
retrievingBatches: false,
addedLines: null, addedLines: null,
removedLines: null, removedLines: null,
endpoint: '', endpoint: '',
... ...
......
export const SET_BASE_CONFIG = 'SET_BASE_CONFIG'; export const SET_BASE_CONFIG = 'SET_BASE_CONFIG';
export const SET_LOADING = 'SET_LOADING'; export const SET_LOADING = 'SET_LOADING';
export const SET_BATCH_LOADING = 'SET_BATCH_LOADING'; export const SET_BATCH_LOADING = 'SET_BATCH_LOADING';
export const SET_RETRIEVING_BATCHES = 'SET_RETRIEVING_BATCHES';
export const SET_DIFF_DATA = 'SET_DIFF_DATA'; export const SET_DIFF_DATA = 'SET_DIFF_DATA';
export const SET_DIFF_DATA_BATCH = 'SET_DIFF_DATA_BATCH'; export const SET_DIFF_DATA_BATCH = 'SET_DIFF_DATA_BATCH';
export const SET_DIFF_VIEW_TYPE = 'SET_DIFF_VIEW_TYPE'; export const SET_DIFF_VIEW_TYPE = 'SET_DIFF_VIEW_TYPE';
... ...
......