diff --git a/src/controller/explorer/folderTree.tsx b/src/controller/explorer/folderTree.tsx index 9ddfa4307..35171b943 100644 --- a/src/controller/explorer/folderTree.tsx +++ b/src/controller/explorer/folderTree.tsx @@ -105,7 +105,9 @@ export class FolderTreeController const folderTreeState = this.folderTreeService.getState(); const { data, current } = folderTreeState?.folderTree || {}; // The current selected node id or the first root node - const nodeId = current?.id || data?.[0]?.id; + const nodeId = + typeof current?.id === 'undefined' ? data?.[0]?.id : current?.id; + this.emit(FolderTreeEvent.onCreate, type, nodeId); }; diff --git a/src/services/workbench/__tests__/folderTreeService.test.ts b/src/services/workbench/__tests__/folderTreeService.test.ts index 9252f1ed4..7829e7e99 100644 --- a/src/services/workbench/__tests__/folderTreeService.test.ts +++ b/src/services/workbench/__tests__/folderTreeService.test.ts @@ -4,6 +4,7 @@ import { container } from 'tsyringe'; import { FileTypes, IFolderTreeNodeProps, + TreeNodeModel, } from 'mo/model/workbench/explorer/folderTree'; import { expectFnCalled, expectLoggerErrorToBeCalled } from '@test/utils'; @@ -12,6 +13,7 @@ import { FolderTreeService, } from '../explorer/folderTreeService'; import { FolderTreeEvent } from 'mo/model/workbench/explorer/folderTree'; +import { randomId } from 'mo/common/utils'; const TEST_ID = 'test-id'; @@ -135,6 +137,53 @@ describe('Test StatusBarService', () => { expect(folderTreeService.get(mockTreeData.id)?.name).toBe(TEST_ID); }); + test('Should insert a file or a folder in a sorted way', () => { + const mockRootTree = new TreeNodeModel({ + id: randomId(), + name: 'molecule_temp', + fileType: FileTypes.RootFolder, + }); + folderTreeService.add(mockRootTree); + const mockFolder = new TreeNodeModel({ + id: randomId(), + name: 'mock_folder', + fileType: FileTypes.Folder, + isLeaf: false, + }); + folderTreeService.add(mockFolder, mockRootTree.id); + let rootFolder = folderTreeService.get(mockRootTree.id)!; + + expect(rootFolder.children).toHaveLength(1); + + const anotherMockFolder = new TreeNodeModel({ + id: randomId(), + name: 'another_mock_folder', + fileType: FileTypes.Folder, + isLeaf: false, + }); + folderTreeService.add(anotherMockFolder, mockRootTree.id); + rootFolder = folderTreeService.get(mockRootTree.id)!; + + expect(rootFolder.children).toHaveLength(2); + expect(rootFolder.children).toEqual([anotherMockFolder, mockFolder]); + + const mockFile = new TreeNodeModel({ + id: randomId(), + name: 'mock_file', + fileType: FileTypes.File, + isLeaf: true, + }); + folderTreeService.add(mockFile, mockRootTree.id); + rootFolder = folderTreeService.get(mockRootTree.id)!; + + expect(rootFolder.children).toHaveLength(3); + expect(rootFolder.children).toEqual([ + anotherMockFolder, + mockFolder, + mockFile, + ]); + }); + test('Should NOT add root folder when there is a root folder', () => { const mockRootTree: IFolderTreeNodeProps = { id: '0', diff --git a/src/services/workbench/explorer/folderTreeService.ts b/src/services/workbench/explorer/folderTreeService.ts index 72a81c888..d7b5c6be9 100644 --- a/src/services/workbench/explorer/folderTreeService.ts +++ b/src/services/workbench/explorer/folderTreeService.ts @@ -257,6 +257,23 @@ export class FolderTreeService }; } + // Get the position of file by type + // We considered by default that the list is sorted in fileType + private getPosOfType( + type: keyof typeof FileTypes, + folderList: IFolderTreeNodeProps[] + ) { + if (!folderList.length) return 0; + if (type === FileTypes.Folder || type === FileTypes.RootFolder) { + return 0; + } + // find the first file type + const index = folderList.findIndex( + (list) => list.fileType === FileTypes.File + ); + return index === -1 ? folderList.length : index; + } + public add(data: IFolderTreeNodeProps, id?: UniqueId): void { const isRootFolder = data.fileType === 'RootFolder'; @@ -284,10 +301,20 @@ export class FolderTreeService /(?<=\/)[^\/]+$/, `${data.name}` ) || ''; - tree!.prepend(data, currentIndex.parent!); + + const parentNode = tree!.getNode(currentIndex.parent!)!; + const pos = this.getPosOfType( + data.fileType!, + parentNode.children || [] + ); + tree!.insertNode(data, currentIndex.parent!, pos); } else { this.setCurrentFolderLocation(data, id); - tree!.append(data, id); + const pos = this.getPosOfType( + data.fileType!, + currentIndex.node.children || [] + ); + tree?.insertNode(data, currentIndex.id, pos); } cloneData[index] = tree!.obj; diff --git a/src/workbench/sidebar/explore/style.scss b/src/workbench/sidebar/explore/style.scss index f99a6b065..06a4cd3cb 100644 --- a/src/workbench/sidebar/explore/style.scss +++ b/src/workbench/sidebar/explore/style.scss @@ -10,7 +10,8 @@ } #{$folderTree} { - height: 100%; + min-height: 100%; + padding-bottom: 22px; &--editable { background: rgba(0, 0, 0, 0.3);