diff --git a/web/src/views/repo/pipeline/PipelineChangedFiles.vue b/web/src/views/repo/pipeline/PipelineChangedFiles.vue index be3d0b136..b71fd221d 100644 --- a/web/src/views/repo/pipeline/PipelineChangedFiles.vue +++ b/web/src/views/repo/pipeline/PipelineChangedFiles.vue @@ -28,28 +28,48 @@ useWPTitle( ]), ); +function collapseNode(node: TreeNode): TreeNode { + if (!node.isDirectory) return node; + const collapsedChildren = node.children.map(collapseNode); + let currentNode = { ...node, children: collapsedChildren }; + + while (currentNode.children.length === 1 && currentNode.children[0].isDirectory) { + const onlyChild = currentNode.children[0]; + currentNode = { + name: `${currentNode.name}/${onlyChild.name}`, + path: onlyChild.path, + isDirectory: true, + children: onlyChild.children, + }; + } + + return currentNode; +} + const fileTree = computed(() => - (pipeline.value.changed_files ?? []).reduce((acc, file) => { - const parts = file.split('/'); - let currentLevel = acc; + (pipeline.value.changed_files ?? []) + .reduce((acc, file) => { + const parts = file.split('/'); + let currentLevel = acc; - parts.forEach((part, index) => { - const existingNode = currentLevel.find((node) => node.name === part); - if (existingNode) { - currentLevel = existingNode.children; - } else { - const newNode = { - name: part, - path: parts.slice(0, index + 1).join('/'), - isDirectory: index < parts.length - 1, - children: [], - }; - currentLevel.push(newNode); - currentLevel = newNode.children; - } - }); + parts.forEach((part, index) => { + const existingNode = currentLevel.find((node) => node.name === part); + if (existingNode) { + currentLevel = existingNode.children; + } else { + const newNode = { + name: part, + path: parts.slice(0, index + 1).join('/'), + isDirectory: index < parts.length - 1, + children: [], + }; + currentLevel.push(newNode); + currentLevel = newNode.children; + } + }); - return acc; - }, [] as TreeNode[]), + return acc; + }, [] as TreeNode[]) + .map(collapseNode), );