Skip to content

Commit 8802b1f

Browse files
authored
feat: support sort in folderTree (#524)
* feat: support sort in folderTree * feat: improve check hidden files
1 parent 0d76520 commit 8802b1f

File tree

2 files changed

+159
-2
lines changed

2 files changed

+159
-2
lines changed

src/services/workbench/__tests__/folderTreeService.test.ts

+116-1
Original file line numberDiff line numberDiff line change
@@ -272,10 +272,125 @@ describe('Test StatusBarService', () => {
272272
const children = data[0].children!;
273273
expect(children).toHaveLength(2);
274274
expect(children[0]).toEqual({
275-
...pendingNode,
275+
...fileNode,
276276
});
277277
});
278278

279+
test('Should in sort', () => {
280+
const ignoreFolder = new TreeNodeModel({
281+
id: 'ignore-folder',
282+
fileType: FileTypes.Folder,
283+
name: '.git',
284+
isLeaf: false,
285+
children: [],
286+
});
287+
const normalFolder = new TreeNodeModel({
288+
id: 'nomral-folder',
289+
fileType: FileTypes.Folder,
290+
name: 'folder',
291+
isLeaf: false,
292+
children: [],
293+
});
294+
const normalFile = new TreeNodeModel({
295+
id: 'nomral-file',
296+
fileType: FileTypes.File,
297+
name: 'file',
298+
isLeaf: true,
299+
children: [],
300+
});
301+
const ignoreFile = new TreeNodeModel({
302+
id: 'ignore-file',
303+
fileType: FileTypes.File,
304+
name: '.gitignore',
305+
isLeaf: true,
306+
children: [],
307+
});
308+
const root = new TreeNodeModel({
309+
id: 'root',
310+
fileType: FileTypes.RootFolder,
311+
name: 'root-test',
312+
isLeaf: false,
313+
children: [ignoreFile, normalFile, normalFolder, ignoreFolder],
314+
});
315+
folderTreeService.add(root);
316+
317+
// let data = folderTreeService.getState().folderTree?.data || [];
318+
let rootNode = folderTreeService.get('root')!;
319+
expect(rootNode.children?.map((i) => i.name)).toEqual([
320+
'.git',
321+
'folder',
322+
'.gitignore',
323+
'file',
324+
]);
325+
326+
// add a file
327+
folderTreeService.add(
328+
new TreeNodeModel({
329+
id: 'another-ignore-file',
330+
fileType: FileTypes.File,
331+
name: '.prettierignore',
332+
isLeaf: true,
333+
children: [],
334+
}),
335+
'root'
336+
);
337+
338+
rootNode = folderTreeService.get('root')!;
339+
expect(rootNode.children?.map((i) => i.name)).toEqual([
340+
'.git',
341+
'folder',
342+
'.gitignore',
343+
'.prettierignore',
344+
'file',
345+
]);
346+
347+
// add a folder
348+
folderTreeService.add(
349+
new TreeNodeModel({
350+
id: 'another-normal-folder',
351+
fileType: FileTypes.Folder,
352+
name: 'another-folder',
353+
isLeaf: false,
354+
children: [],
355+
}),
356+
'root'
357+
);
358+
359+
rootNode = folderTreeService.get('root')!;
360+
expect(rootNode.children?.map((i) => i.name)).toEqual([
361+
'.git',
362+
'another-folder',
363+
'folder',
364+
'.gitignore',
365+
'.prettierignore',
366+
'file',
367+
]);
368+
369+
// add a input
370+
folderTreeService.add(
371+
new TreeNodeModel({
372+
id: 'create-folder',
373+
fileType: FileTypes.Folder,
374+
name: '',
375+
isEditable: true,
376+
isLeaf: false,
377+
children: [],
378+
}),
379+
'root'
380+
);
381+
382+
rootNode = folderTreeService.get('root')!;
383+
expect(rootNode.children?.map((i) => i.name)).toEqual([
384+
'',
385+
'.git',
386+
'another-folder',
387+
'folder',
388+
'.gitignore',
389+
'.prettierignore',
390+
'file',
391+
]);
392+
});
393+
279394
test('Should support to set entry', () => {
280395
folderTreeService.setEntry(Button);
281396
expect(folderTreeService.getState().entry).toEqual(Button);

src/services/workbench/explorer/folderTreeService.ts

+43-1
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,42 @@ export class FolderTreeService
157157
this.builtinService = container.resolve(BuiltinService);
158158
}
159159

160+
private isHiddenFile(file: IFolderTreeNodeProps) {
161+
return !!file.name?.startsWith('.');
162+
}
163+
164+
private sortTree(tree: IFolderTreeNodeProps[]) {
165+
tree.sort((pre, cur) => {
166+
// folder before file
167+
if (pre.isLeaf !== cur.isLeaf) {
168+
return pre.isLeaf! > cur.isLeaf! ? 1 : -1;
169+
}
170+
171+
// in general, both have name
172+
if (pre.name && cur.name) {
173+
const isHiddenFilePre = Number(this.isHiddenFile(pre));
174+
const isHiddenFileCur = Number(this.isHiddenFile(cur));
175+
// one is hidden file and another is not
176+
if (isHiddenFilePre ^ isHiddenFileCur) {
177+
return isHiddenFilePre ? -1 : 1;
178+
}
179+
// both are hidden files
180+
if (isHiddenFilePre & isHiddenFilePre) {
181+
// hidden file
182+
return pre.name
183+
.substring(1)
184+
.localeCompare(cur.name.substring(1));
185+
}
186+
return pre.name.localeCompare(cur.name!);
187+
}
188+
189+
// the node which is creating would without name
190+
return pre.isEditable ? -1 : 1;
191+
});
192+
193+
tree.forEach((treeNode) => this.sortTree(treeNode.children || []));
194+
}
195+
160196
public reset() {
161197
this.setState({
162198
folderTree: {
@@ -221,6 +257,8 @@ export class FolderTreeService
221257
// if root folder exists, then do nothing
222258
return;
223259
}
260+
261+
this.sortTree(folder.children || []);
224262
this.setState({
225263
folderTree: { ...folderTree, data: [folder] },
226264
});
@@ -319,6 +357,7 @@ export class FolderTreeService
319357
}
320358

321359
cloneData[index] = tree!.obj;
360+
this.sortTree(cloneData[index].children || []);
322361
this.setState({
323362
folderTree: {
324363
...this.state.folderTree,
@@ -363,7 +402,10 @@ export class FolderTreeService
363402
return;
364403
}
365404
tree.updateNode(id, restData);
366-
if (index > -1) nextData[index] = tree.obj;
405+
if (index > -1) {
406+
nextData[index] = tree.obj;
407+
this.sortTree(nextData[index].children || []);
408+
}
367409
this.setState({
368410
folderTree,
369411
});

0 commit comments

Comments
 (0)