From 35988a24394ee87843c5669762f6b9d60396c585 Mon Sep 17 00:00:00 2001 From: Thomas Randolph Date: Mon, 29 Sep 2025 18:50:59 -0600 Subject: [PATCH 1/2] Sort diff file tree entries by key instead of full path This fixes the tree showing an order that does not match with either the list of diff files or the display of the file explorer in list mode. Changelog: fixed --- app/assets/javascripts/diffs/store/actions.js | 2 +- .../diffs/stores/legacy_diffs/actions.js | 2 +- app/assets/javascripts/ide/stores/utils.js | 30 ++++++++++--------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js index bf5aeed1ef0b2e..dd2249e0b257fe 100644 --- a/app/assets/javascripts/diffs/store/actions.js +++ b/app/assets/javascripts/diffs/store/actions.js @@ -358,7 +358,7 @@ export const fetchDiffFilesMeta = ({ commit, state }) => { eventHub.$emit(EVT_PERF_MARK_FILE_TREE_END); commit(types.SET_TREE_DATA, { treeEntries, - tree: sortTree(tree), + tree: sortTree(tree, 'key'), }); return data; diff --git a/app/assets/javascripts/diffs/stores/legacy_diffs/actions.js b/app/assets/javascripts/diffs/stores/legacy_diffs/actions.js index 7c4f7a63dd2f71..a5f54a2d072c12 100644 --- a/app/assets/javascripts/diffs/stores/legacy_diffs/actions.js +++ b/app/assets/javascripts/diffs/stores/legacy_diffs/actions.js @@ -360,7 +360,7 @@ export function fetchDiffFilesMeta() { eventHub.$emit(EVT_PERF_MARK_FILE_TREE_END); this[types.SET_TREE_DATA]({ treeEntries, - tree: sortTree(tree), + tree: sortTree(tree, 'key'), }); return data; diff --git a/app/assets/javascripts/ide/stores/utils.js b/app/assets/javascripts/ide/stores/utils.js index f84104a47ed93e..95ef1ff72c591c 100644 --- a/app/assets/javascripts/ide/stores/utils.js +++ b/app/assets/javascripts/ide/stores/utils.js @@ -61,17 +61,19 @@ export const decorateData = (entity) => { }); }; -const sortTreesByTypeAndName = (a, b) => { - if (a.type === 'tree' && b.type === 'blob') { - return -1; - } - if (a.type === 'blob' && b.type === 'tree') { - return 1; - } - if (a.name < b.name) return -1; - if (a.name > b.name) return 1; - return 0; -}; +function sortTreesByTypeAndOther(key) { + return (a, b) => { + if (a.type === 'tree' && b.type === 'blob') { + return -1; + } + if (a.type === 'blob' && b.type === 'tree') { + return 1; + } + if (a[key] < b[key]) return -1; + if (a[key] > b[key]) return 1; + return 0; + }; +} export const linkTreeNodes = (tree) => { return tree.map((entity) => @@ -81,11 +83,11 @@ export const linkTreeNodes = (tree) => { ); }; -export const sortTree = (sortedTree) => +export const sortTree = (sortedTree, key = 'name') => sortedTree .map((entity) => Object.assign(entity, { - tree: entity.tree.length ? sortTree(entity.tree) : [], + tree: entity.tree.length ? sortTree(entity.tree, key) : [], }), ) - .sort(sortTreesByTypeAndName); + .sort(sortTreesByTypeAndOther(key)); -- GitLab From 165f005e57810d0595a644c493895af590eacd72 Mon Sep 17 00:00:00 2001 From: Thomas Randolph Date: Mon, 29 Sep 2025 19:28:29 -0600 Subject: [PATCH 2/2] Test new "alternate key" behavior of the sortTree function There were no tests at all, so this also tests that the default behavior works, and that the special logic to put sub-directories first works. --- spec/frontend/ide/stores/utils_spec.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 spec/frontend/ide/stores/utils_spec.js diff --git a/spec/frontend/ide/stores/utils_spec.js b/spec/frontend/ide/stores/utils_spec.js new file mode 100644 index 00000000000000..09a76c5154f054 --- /dev/null +++ b/spec/frontend/ide/stores/utils_spec.js @@ -0,0 +1,23 @@ +import { sortTree } from '~/ide/stores/utils'; + +describe('IDE store utils', () => { + describe('sortTree', () => { + const treeEntries = [ + { id: 1, name: 'a', key: 'z', type: 'blob', tree: [] }, + { id: 2, name: 'z', key: 'a', type: 'blob', tree: [] }, + { id: 3, name: 't', key: 't', type: 'tree', tree: [] }, + ]; + + it.each` + description | treeIn | key | sequenceOut + ${'sorts by name when no key is provided'} | ${[treeEntries[1], treeEntries[0]]} | ${undefined} | ${[1, 2]} + ${'sorts by the provided key'} | ${[treeEntries[0], treeEntries[1]]} | ${'key'} | ${[2, 1]} + ${'sorts sub-trees above blobs'} | ${treeEntries} | ${undefined} | ${[3, 1, 2]} + `('$description', ({ treeIn, key, sequenceOut }) => { + const sorted = sortTree(treeIn, key); + const ids = sorted.map((entry) => entry.id); + + expect(ids).toEqual(sequenceOut); + }); + }); +}); -- GitLab