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/app.vue')
-rw-r--r--app/assets/javascripts/diffs/components/app.vue189
1 files changed, 124 insertions, 65 deletions
diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue
index 35d1a564178..02307150e2f 100644
--- a/app/assets/javascripts/diffs/components/app.vue
+++ b/app/assets/javascripts/diffs/components/app.vue
@@ -1,8 +1,8 @@
<script>
import { GlLoadingIcon, GlPagination, GlSprintf, GlAlert } from '@gitlab/ui';
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
-import Mousetrap from 'mousetrap';
import { mapState, mapGetters, mapActions } from 'vuex';
+import { convertToGraphQLId } from '~/graphql_shared/utils';
import api from '~/api';
import {
keysFor,
@@ -11,16 +11,18 @@ import {
MR_COMMITS_NEXT_COMMIT,
MR_COMMITS_PREVIOUS_COMMIT,
} from '~/behaviors/shortcuts/keybindings';
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import { isSingleViewStyle } from '~/helpers/diffs_helper';
import { helpPagePath } from '~/helpers/help_page_helper';
import { parseBoolean } from '~/lib/utils/common_utils';
+import { Mousetrap } from '~/lib/mousetrap';
import { updateHistory } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import PanelResizer from '~/vue_shared/components/panel_resizer.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import notesEventHub from '~/notes/event_hub';
+import { DynamicScroller, DynamicScrollerItem } from 'vendor/vue-virtual-scroller';
import {
TREE_LIST_WIDTH_STORAGE_KEY,
INITIAL_TREE_WIDTH,
@@ -39,12 +41,15 @@ import {
TRACKING_WHITESPACE_HIDE,
TRACKING_SINGLE_FILE_MODE,
TRACKING_MULTIPLE_FILES_MODE,
+ EVT_MR_PREPARED,
} from '../constants';
import diffsEventHub from '../event_hub';
import { reviewStatuses } from '../utils/file_reviews';
import { diffsApp } from '../utils/performance';
+import { updateChangesTabCount } from '../utils/merge_request';
import { queueRedisHllEvents } from '../utils/queue_events';
+import FindingsDrawer from './shared/findings_drawer.vue';
import CollapsedFilesWarning from './collapsed_files_warning.vue';
import CommitWidget from './commit_widget.vue';
import CompareVersions from './compare_versions.vue';
@@ -53,15 +58,15 @@ import HiddenFilesWarning from './hidden_files_warning.vue';
import NoChanges from './no_changes.vue';
import TreeList from './tree_list.vue';
import VirtualScrollerScrollSync from './virtual_scroller_scroll_sync';
+import PreRenderer from './pre_renderer.vue';
export default {
name: 'DiffsApp',
components: {
- DynamicScroller: () =>
- import('vendor/vue-virtual-scroller').then(({ DynamicScroller }) => DynamicScroller),
- DynamicScrollerItem: () =>
- import('vendor/vue-virtual-scroller').then(({ DynamicScrollerItem }) => DynamicScrollerItem),
- PreRenderer: () => import('./pre_renderer.vue').then((PreRenderer) => PreRenderer),
+ FindingsDrawer,
+ DynamicScroller,
+ DynamicScrollerItem,
+ PreRenderer,
VirtualScrollerScrollSync,
CompareVersions,
DiffFile,
@@ -75,6 +80,8 @@ export default {
GlPagination,
GlSprintf,
GlAlert,
+ GenerateTestFileDrawer: () =>
+ import('ee_component/ai/components/generate_test_file_drawer.vue'),
},
mixins: [glFeatureFlagsMixin()],
alerts: {
@@ -95,6 +102,10 @@ export default {
type: String,
required: true,
},
+ endpointDiffForPath: {
+ type: String,
+ required: true,
+ },
endpointCoverage: {
type: String,
required: false,
@@ -195,6 +206,7 @@ export default {
numTotalFiles: 'realSize',
numVisibleFiles: 'size',
}),
+ ...mapState('findingsDrawer', ['activeDrawer']),
...mapState('diffs', [
'showTreeList',
'isLoading',
@@ -218,6 +230,7 @@ export default {
'showWhitespace',
'targetBranchName',
'branchName',
+ 'generateTestFilePath',
]),
...mapGetters('diffs', [
'whichCollapsedTypes',
@@ -226,8 +239,10 @@ export default {
'isVirtualScrollingEnabled',
'isBatchLoading',
'isBatchLoadingError',
+ 'flatBlobsList',
]),
...mapGetters(['isNotesFetched', 'getNoteableData']),
+ ...mapGetters('findingsDrawer', ['activeDrawer']),
diffs() {
if (!this.viewDiffsFileByFile) {
return this.diffFiles;
@@ -241,7 +256,10 @@ export default {
return this.currentUser.can_fork === true && this.currentUser.can_create_merge_request;
},
renderDiffFiles() {
- return this.diffFiles.length > 0;
+ return this.flatBlobsList.length > 0;
+ },
+ diffsIncomplete() {
+ return this.flatBlobsList.length !== this.diffFiles.length;
},
renderFileTree() {
return this.renderDiffFiles && this.showTreeList;
@@ -253,7 +271,7 @@ export default {
return this.startVersion === null && this.latestDiff;
},
showFileByFileNavigation() {
- return this.diffFiles.length > 1 && this.viewDiffsFileByFile;
+ return this.flatBlobsList.length > 1 && this.viewDiffsFileByFile;
},
currentFileNumber() {
return this.currentDiffIndex + 1;
@@ -264,9 +282,9 @@ export default {
return currentDiffIndex >= 1 ? currentDiffIndex : null;
},
nextFileNumber() {
- const { currentFileNumber, diffFiles } = this;
+ const { currentFileNumber, flatBlobsList } = this;
- return currentFileNumber < diffFiles.length ? currentFileNumber + 1 : null;
+ return currentFileNumber < flatBlobsList.length ? currentFileNumber + 1 : null;
},
visibleWarning() {
let visible = false;
@@ -284,6 +302,9 @@ export default {
fileReviews() {
return reviewStatuses(this.diffFiles, this.mrReviews);
},
+ resourceId() {
+ return convertToGraphQLId('MergeRequest', this.getNoteableData.id);
+ },
},
watch: {
commit(newCommit, oldCommit) {
@@ -303,6 +324,11 @@ export default {
diffViewType() {
this.adjustView();
},
+ viewDiffsFileByFile(newViewFileByFile) {
+ if (!newViewFileByFile && this.diffsIncomplete && this.glFeatures.singleFileFileByFile) {
+ this.refetchDiffData({ refetchMeta: false });
+ }
+ },
shouldShow() {
// When the shouldShow property changed to true, the route is rendered for the first time
// and if we have the isLoading as true this means we didn't fetch the data
@@ -321,6 +347,7 @@ export default {
endpoint: this.endpoint,
endpointMetadata: this.endpointMetadata,
endpointBatch: this.endpointBatch,
+ endpointDiffForPath: this.endpointDiffForPath,
endpointCoverage: this.endpointCoverage,
endpointUpdateUser: this.endpointUpdateUser,
projectPath: this.projectPath,
@@ -331,8 +358,6 @@ export default {
mrReviews: this.rehydratedMrReviews,
});
- this.interfaceWithDOM();
-
if (this.endpointCodequality) {
this.setCodequalityEndpoint(this.endpointCodequality);
}
@@ -385,7 +410,7 @@ export default {
this.subscribeToEvents();
this.unwatchDiscussions = this.$watch(
- () => `${this.diffFiles.length}:${this.$store.state.notes.discussions.length}`,
+ () => `${this.flatBlobsList.length}:${this.$store.state.notes.discussions.length}`,
() => {
this.setDiscussions();
@@ -420,41 +445,51 @@ export default {
'setCodequalityEndpoint',
'fetchDiffFilesMeta',
'fetchDiffFilesBatch',
+ 'fetchFileByFile',
'fetchCoverageFiles',
'fetchCodequality',
+ 'rereadNoteHash',
'startRenderDiffsQueue',
'assignDiscussionsToDiff',
'setHighlightedRow',
'cacheTreeListWidth',
- 'scrollToFile',
+ 'goToFile',
'setShowTreeList',
'navigateToDiffFileIndex',
'setFileByFile',
'disableVirtualScroller',
+ 'setGenerateTestFilePath',
]),
+ ...mapActions('findingsDrawer', ['setDrawer']),
+ closeDrawer() {
+ this.setDrawer({});
+ },
subscribeToEvents() {
notesEventHub.$once('fetchDiffData', this.fetchData);
notesEventHub.$on('refetchDiffData', this.refetchDiffData);
+ if (this.glFeatures.singleFileFileByFile) {
+ diffsEventHub.$on('diffFilesModified', this.setDiscussions);
+ notesEventHub.$on('fetchedNotesData', this.rereadNoteHash);
+ }
+ diffsEventHub.$on(EVT_MR_PREPARED, this.fetchData);
},
unsubscribeFromEvents() {
+ diffsEventHub.$off(EVT_MR_PREPARED, this.fetchData);
+ if (this.glFeatures.singleFileFileByFile) {
+ notesEventHub.$off('fetchedNotesData', this.rereadNoteHash);
+ diffsEventHub.$off('diffFilesModified', this.setDiscussions);
+ }
notesEventHub.$off('refetchDiffData', this.refetchDiffData);
notesEventHub.$off('fetchDiffData', this.fetchData);
},
- interfaceWithDOM() {
- this.diffsTab = document.querySelector('.js-diffs-tab');
- },
- updateChangesTabCount() {
- const badge = this.diffsTab.querySelector('.gl-badge');
-
- if (this.diffsTab && badge) {
- badge.textContent = this.diffFilesLength;
- }
- },
navigateToDiffFileNumber(number) {
- this.navigateToDiffFileIndex(number - 1);
+ this.navigateToDiffFileIndex({
+ index: number - 1,
+ singleFile: this.glFeatures.singleFileFileByFile,
+ });
},
- refetchDiffData() {
- this.fetchData(false);
+ refetchDiffData({ refetchMeta = true } = {}) {
+ this.fetchData({ toggleTree: false, fetchMeta: refetchMeta });
},
needsReload() {
return this.diffFiles.length && isSingleViewStyle(this.diffFiles[0]);
@@ -462,42 +497,52 @@ export default {
needsFirstLoad() {
return !this.diffFiles.length;
},
- fetchData(toggleTree = true) {
- this.fetchDiffFilesMeta()
- .then((data) => {
- let realSize = 0;
-
- if (data) {
- realSize = data.real_size;
- }
-
- this.diffFilesLength = parseInt(realSize, 10) || 0;
- if (toggleTree) {
- this.setTreeDisplay();
- }
-
- this.updateChangesTabCount();
- })
- .catch(() => {
- createAlert({
- message: __('Something went wrong on our end. Please try again!'),
+ fetchData({ toggleTree = true, fetchMeta = true } = {}) {
+ if (fetchMeta) {
+ this.fetchDiffFilesMeta()
+ .then((data) => {
+ let realSize = 0;
+
+ if (data) {
+ realSize = data.real_size;
+
+ if (this.viewDiffsFileByFile && this.glFeatures.singleFileFileByFile) {
+ this.fetchFileByFile();
+ }
+ }
+
+ this.diffFilesLength = parseInt(realSize, 10) || 0;
+ if (toggleTree) {
+ this.setTreeDisplay();
+ }
+
+ updateChangesTabCount({
+ count: this.diffFilesLength,
+ });
+ })
+ .catch(() => {
+ createAlert({
+ message: __('Something went wrong on our end. Please try again!'),
+ });
});
- });
+ }
- this.fetchDiffFilesBatch()
- .then(() => {
- if (toggleTree) this.setTreeDisplay();
- // 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();
- })
- .catch(() => {
- createAlert({
- message: __('Something went wrong on our end. Please try again!'),
+ if (!this.viewDiffsFileByFile || !this.glFeatures.singleFileFileByFile) {
+ this.fetchDiffFilesBatch()
+ .then(() => {
+ if (toggleTree) this.setTreeDisplay();
+ // 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();
+ })
+ .catch(() => {
+ createAlert({
+ message: __('Something went wrong on our end. Please try again!'),
+ });
});
- });
+ }
if (this.endpointCoverage) {
this.fetchCoverageFiles();
@@ -572,8 +617,11 @@ export default {
},
jumpToFile(step) {
const targetIndex = this.currentDiffIndex + step;
- if (targetIndex >= 0 && targetIndex < this.diffFiles.length) {
- this.scrollToFile({ path: this.diffFiles[targetIndex].file_path });
+ if (targetIndex >= 0 && targetIndex < this.flatBlobsList.length) {
+ this.goToFile({
+ path: this.flatBlobsList[targetIndex].path,
+ singleFile: this.glFeatures.singleFileFileByFile,
+ });
}
},
setTreeDisplay() {
@@ -582,7 +630,7 @@ export default {
if (storedTreeShow !== null) {
showTreeList = parseBoolean(storedTreeShow);
- } else if (!bp.isDesktop() || (!this.isBatchLoading && this.diffFiles.length <= 1)) {
+ } else if (!bp.isDesktop() || (!this.isBatchLoading && this.flatBlobsList.length <= 1)) {
showTreeList = false;
}
@@ -634,6 +682,11 @@ export default {
<template>
<div v-show="shouldShow">
+ <findings-drawer
+ v-if="glFeatures.codeQualityInlineDrawer"
+ :drawer="activeDrawer"
+ @close="closeDrawer"
+ />
<div v-if="isLoading || !isTreeLoaded" class="loading"><gl-loading-icon size="lg" /></div>
<div v-else id="diffs" :class="{ active: shouldShow }" class="diffs tab-pane">
<compare-versions :diff-files-count-text="numTotalFiles" />
@@ -753,7 +806,7 @@ export default {
/>
<gl-sprintf :message="__('File %{current} of %{total}')">
<template #current>{{ currentFileNumber }}</template>
- <template #total>{{ diffFiles.length }}</template>
+ <template #total>{{ flatBlobsList.length }}</template>
</gl-sprintf>
</div>
<gl-loading-icon v-else-if="retrievingBatches" size="lg" />
@@ -765,5 +818,11 @@ export default {
</div>
</div>
</div>
+ <generate-test-file-drawer
+ v-if="getNoteableData.id"
+ :resource-id="resourceId"
+ :file-path="generateTestFilePath"
+ @close="() => setGenerateTestFilePath('')"
+ />
</div>
</template>