Collapses directory structure in merge request tree

Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/53069
This commit is contained in:
Phil Hughes 2019-01-15 13:37:21 +00:00
parent f821a53b45
commit 9ff20ad76d
No known key found for this signature in database
GPG Key ID: 32245528C52E0F9F
7 changed files with 102 additions and 8 deletions

View File

@ -32,3 +32,5 @@ export const LINES_TO_BE_RENDERED_DIRECTLY = 100;
export const MAX_LINES_TO_BE_RENDERED = 2000;
export const MR_TREE_SHOW_KEY = 'mr_tree_show';
export const TREE_TYPE = 'tree';

View File

@ -5,6 +5,7 @@ import createFlash from '~/flash';
import { s__ } from '~/locale';
import { handleLocationHash, historyPushState, scrollToElement } from '~/lib/utils/common_utils';
import { mergeUrlParams, getLocationHash } from '~/lib/utils/url_utility';
import TreeWorker from '../workers/tree_worker';
import eventHub from '../../notes/event_hub';
import { getDiffPositionByLineCode, getNoteFormData } from './utils';
import * as types from './mutation_types';
@ -21,17 +22,29 @@ export const setBaseConfig = ({ commit }, options) => {
};
export const fetchDiffFiles = ({ state, commit }) => {
const worker = new TreeWorker();
commit(types.SET_LOADING, true);
worker.addEventListener('message', ({ data }) => {
commit(types.SET_TREE_DATA, data);
worker.terminate();
});
return axios
.get(state.endpoint)
.then(res => {
commit(types.SET_LOADING, false);
commit(types.SET_MERGE_REQUEST_DIFFS, res.data.merge_request_diffs || []);
commit(types.SET_DIFF_DATA, res.data);
worker.postMessage(state.diffFiles);
return Vue.nextTick();
})
.then(handleLocationHash);
.then(handleLocationHash)
.catch(() => worker.terminate());
};
export const setHighlightedRow = ({ commit }, lineCode) => {

View File

@ -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 CLOSE_DIFF_FILE_COMMENT_FORM = 'CLOSE_DIFF_FILE_COMMENT_FORM';
export const SET_HIGHLIGHTED_ROW = 'SET_HIGHLIGHTED_ROW';
export const SET_TREE_DATA = 'SET_TREE_DATA';

View File

@ -1,5 +1,4 @@
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { sortTree } from '~/ide/stores/utils';
import {
findDiffFile,
addLineReferences,
@ -7,7 +6,6 @@ import {
addContextLines,
prepareDiffData,
isDiscussionApplicableToLine,
generateTreeList,
} from './utils';
import * as types from './mutation_types';
@ -23,12 +21,9 @@ export default {
[types.SET_DIFF_DATA](state, data) {
prepareDiffData(data);
const { tree, treeEntries } = generateTreeList(data.diff_files);
Object.assign(state, {
...convertObjectPropsToCamelCase(data),
tree: sortTree(tree),
treeEntries,
});
},
@ -239,4 +234,8 @@ export default {
[types.SET_HIGHLIGHTED_ROW](state, lineCode) {
state.highlightedRow = lineCode;
},
[types.SET_TREE_DATA](state, { treeEntries, tree }) {
state.treeEntries = treeEntries;
state.tree = tree;
},
};

View File

@ -11,6 +11,7 @@ import {
MATCH_LINE_TYPE,
LINES_TO_BE_RENDERED_DIRECTLY,
MAX_LINES_TO_BE_RENDERED,
TREE_TYPE,
} from '../constants';
export function findDiffFile(files, hash) {
@ -289,8 +290,63 @@ export function isDiscussionApplicableToLine({ discussion, diffPosition, latestD
return latestDiff && discussion.active && line_code === discussion.line_code;
}
export const generateTreeList = files =>
files.reduce(
export const getLowestSingleFolder = folder => {
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) => {
const split = file.new_path.split('/');
@ -335,6 +391,9 @@ export const generateTreeList = files =>
{ treeEntries: {}, tree: [] },
);
return { treeEntries, tree: flattenTree(tree) };
};
export const getDiffMode = diffFile => {
const diffModeKey = Object.keys(diffModes).find(key => diffFile[`${key}_file`]);
return (

View File

@ -0,0 +1,14 @@
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),
});
});

View File

@ -0,0 +1,5 @@
---
title: Collapse directory structure in merge request file tree
merge_request:
author:
type: changed