Commit 9ff20ad7 authored by Phil Hughes's avatar Phil Hughes

Collapses directory structure in merge request tree

Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/53069
parent f821a53b
...@@ -32,3 +32,5 @@ export const LINES_TO_BE_RENDERED_DIRECTLY = 100; ...@@ -32,3 +32,5 @@ export const LINES_TO_BE_RENDERED_DIRECTLY = 100;
export const MAX_LINES_TO_BE_RENDERED = 2000; export const MAX_LINES_TO_BE_RENDERED = 2000;
export const MR_TREE_SHOW_KEY = 'mr_tree_show'; export const MR_TREE_SHOW_KEY = 'mr_tree_show';
export const TREE_TYPE = 'tree';
...@@ -5,6 +5,7 @@ import createFlash from '~/flash'; ...@@ -5,6 +5,7 @@ import createFlash from '~/flash';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { handleLocationHash, historyPushState, scrollToElement } from '~/lib/utils/common_utils'; import { handleLocationHash, historyPushState, scrollToElement } from '~/lib/utils/common_utils';
import { mergeUrlParams, getLocationHash } from '~/lib/utils/url_utility'; import { mergeUrlParams, getLocationHash } from '~/lib/utils/url_utility';
import TreeWorker from '../workers/tree_worker';
import eventHub from '../../notes/event_hub'; import eventHub from '../../notes/event_hub';
import { getDiffPositionByLineCode, getNoteFormData } from './utils'; import { getDiffPositionByLineCode, getNoteFormData } from './utils';
import * as types from './mutation_types'; import * as types from './mutation_types';
...@@ -21,17 +22,29 @@ export const setBaseConfig = ({ commit }, options) => { ...@@ -21,17 +22,29 @@ export const setBaseConfig = ({ commit }, options) => {
}; };
export const fetchDiffFiles = ({ state, commit }) => { export const fetchDiffFiles = ({ state, commit }) => {
const worker = new TreeWorker();
commit(types.SET_LOADING, true); commit(types.SET_LOADING, true);
worker.addEventListener('message', ({ data }) => {
commit(types.SET_TREE_DATA, data);
worker.terminate();
});
return axios return axios
.get(state.endpoint) .get(state.endpoint)
.then(res => { .then(res => {
commit(types.SET_LOADING, false); commit(types.SET_LOADING, false);
commit(types.SET_MERGE_REQUEST_DIFFS, res.data.merge_request_diffs || []); commit(types.SET_MERGE_REQUEST_DIFFS, res.data.merge_request_diffs || []);
commit(types.SET_DIFF_DATA, res.data); commit(types.SET_DIFF_DATA, res.data);
worker.postMessage(state.diffFiles);
return Vue.nextTick(); return Vue.nextTick();
}) })
.then(handleLocationHash); .then(handleLocationHash)
.catch(() => worker.terminate());
}; };
export const setHighlightedRow = ({ commit }, lineCode) => { export const setHighlightedRow = ({ commit }, lineCode) => {
......
...@@ -18,3 +18,5 @@ export const OPEN_DIFF_FILE_COMMENT_FORM = 'OPEN_DIFF_FILE_COMMENT_FORM'; ...@@ -18,3 +18,5 @@ export const OPEN_DIFF_FILE_COMMENT_FORM = 'OPEN_DIFF_FILE_COMMENT_FORM';
export const UPDATE_DIFF_FILE_COMMENT_FORM = 'UPDATE_DIFF_FILE_COMMENT_FORM'; export const UPDATE_DIFF_FILE_COMMENT_FORM = 'UPDATE_DIFF_FILE_COMMENT_FORM';
export const CLOSE_DIFF_FILE_COMMENT_FORM = 'CLOSE_DIFF_FILE_COMMENT_FORM'; export const CLOSE_DIFF_FILE_COMMENT_FORM = 'CLOSE_DIFF_FILE_COMMENT_FORM';
export const SET_HIGHLIGHTED_ROW = 'SET_HIGHLIGHTED_ROW'; export const SET_HIGHLIGHTED_ROW = 'SET_HIGHLIGHTED_ROW';
export const SET_TREE_DATA = 'SET_TREE_DATA';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { sortTree } from '~/ide/stores/utils';
import { import {
findDiffFile, findDiffFile,
addLineReferences, addLineReferences,
...@@ -7,7 +6,6 @@ import { ...@@ -7,7 +6,6 @@ import {
addContextLines, addContextLines,
prepareDiffData, prepareDiffData,
isDiscussionApplicableToLine, isDiscussionApplicableToLine,
generateTreeList,
} from './utils'; } from './utils';
import * as types from './mutation_types'; import * as types from './mutation_types';
...@@ -23,12 +21,9 @@ export default { ...@@ -23,12 +21,9 @@ export default {
[types.SET_DIFF_DATA](state, data) { [types.SET_DIFF_DATA](state, data) {
prepareDiffData(data); prepareDiffData(data);
const { tree, treeEntries } = generateTreeList(data.diff_files);
Object.assign(state, { Object.assign(state, {
...convertObjectPropsToCamelCase(data), ...convertObjectPropsToCamelCase(data),
tree: sortTree(tree),
treeEntries,
}); });
}, },
...@@ -239,4 +234,8 @@ export default { ...@@ -239,4 +234,8 @@ export default {
[types.SET_HIGHLIGHTED_ROW](state, lineCode) { [types.SET_HIGHLIGHTED_ROW](state, lineCode) {
state.highlightedRow = lineCode; state.highlightedRow = lineCode;
}, },
[types.SET_TREE_DATA](state, { treeEntries, tree }) {
state.treeEntries = treeEntries;
state.tree = tree;
},
}; };
...@@ -11,6 +11,7 @@ import { ...@@ -11,6 +11,7 @@ import {
MATCH_LINE_TYPE, MATCH_LINE_TYPE,
LINES_TO_BE_RENDERED_DIRECTLY, LINES_TO_BE_RENDERED_DIRECTLY,
MAX_LINES_TO_BE_RENDERED, MAX_LINES_TO_BE_RENDERED,
TREE_TYPE,
} from '../constants'; } from '../constants';
export function findDiffFile(files, hash) { export function findDiffFile(files, hash) {
...@@ -289,8 +290,63 @@ export function isDiscussionApplicableToLine({ discussion, diffPosition, latestD ...@@ -289,8 +290,63 @@ export function isDiscussionApplicableToLine({ discussion, diffPosition, latestD
return latestDiff && discussion.active && line_code === discussion.line_code; return latestDiff && discussion.active && line_code === discussion.line_code;
} }
export const generateTreeList = files => export const getLowestSingleFolder = folder => {
files.reduce( const getFolder = (blob, start = []) =>
blob.tree.reduce(
(acc, file) => {
const shouldGetFolder = file.tree.length === 1 && file.tree[0].type === TREE_TYPE;
const currentFileTypeTree = file.type === TREE_TYPE;
const path = shouldGetFolder || currentFileTypeTree ? acc.path.concat(file.name) : acc.path;
const tree = shouldGetFolder || currentFileTypeTree ? acc.tree.concat(file) : acc.tree;
if (shouldGetFolder) {
const firstFolder = getFolder(file);
path.push(firstFolder.path);
tree.push(...firstFolder.tree);
}
return {
...acc,
path,
tree,
};
},
{ path: start, tree: [] },
);
const { path, tree } = getFolder(folder, [folder.name]);
return {
path: path.join('/'),
treeAcc: tree.length ? tree[tree.length - 1].tree : null,
};
};
export const flattenTree = tree => {
const flatten = blobTree =>
blobTree.reduce((acc, file) => {
const blob = file;
let treeToFlatten = blob.tree;
if (file.type === TREE_TYPE && file.tree.length === 1) {
const { treeAcc, path } = getLowestSingleFolder(file);
if (treeAcc) {
blob.name = path;
treeToFlatten = flatten(treeAcc);
}
}
blob.tree = flatten(treeToFlatten);
return acc.concat(blob);
}, []);
return flatten(tree);
};
export const generateTreeList = files => {
const { treeEntries, tree } = files.reduce(
(acc, file) => { (acc, file) => {
const split = file.new_path.split('/'); const split = file.new_path.split('/');
...@@ -335,6 +391,9 @@ export const generateTreeList = files => ...@@ -335,6 +391,9 @@ export const generateTreeList = files =>
{ treeEntries: {}, tree: [] }, { treeEntries: {}, tree: [] },
); );
return { treeEntries, tree: flattenTree(tree) };
};
export const getDiffMode = diffFile => { export const getDiffMode = diffFile => {
const diffModeKey = Object.keys(diffModes).find(key => diffFile[`${key}_file`]); const diffModeKey = Object.keys(diffModes).find(key => diffFile[`${key}_file`]);
return ( return (
......
import { sortTree } from '~/ide/stores/utils';
import { generateTreeList } from '../store/utils';
// eslint-disable-next-line no-restricted-globals
self.addEventListener('message', e => {
const { data } = e;
const { treeEntries, tree } = generateTreeList(data);
// eslint-disable-next-line no-restricted-globals
self.postMessage({
treeEntries,
tree: sortTree(tree),
});
});
---
title: Collapse directory structure in merge request file tree
merge_request:
author:
type: changed
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment