Skip to content

Commit 2960b24

Browse files
#276 Improve File Tree Tab
- make file/folder folded status persistent
1 parent 1d42db7 commit 2960b24

File tree

7 files changed

+33
-45
lines changed

7 files changed

+33
-45
lines changed

binocular-frontend-new/src/components/tabs/fileTree/fileList/fileList.tsx

+3-11
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,9 @@ function FileList(props: { orientation?: string }) {
3333
files: {
3434
name: '/',
3535
type: FileListElementTypeType.Folder,
36-
children: generateFileTree(
37-
files.map((file) => {
38-
return {
39-
file: file,
40-
checked: true,
41-
};
42-
}),
43-
),
44-
element: {
45-
checked: true,
46-
},
36+
children: generateFileTree(files),
37+
checked: true,
38+
foldedOut: true,
4739
},
4840
fileCount: files.length,
4941
}),

binocular-frontend-new/src/components/tabs/fileTree/fileList/fileListElements/fileListFile.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { FileListElementType } from '../../../../../types/data/fileListType.ts';
33
import FileIcon from '../../../../../assets/file_gray.svg';
44
import { updateFileListElement } from '../../../../../redux/reducer/data/filesReducer.ts';
55
import { AppDispatch, useAppDispatch } from '../../../../../redux';
6-
import { updateFileListElementTypeChecked } from '../fileListUtilities/fileTreeUtilities.ts';
76

87
function FileListFile(props: { file: FileListElementType }) {
98
const dispatch: AppDispatch = useAppDispatch();
@@ -13,8 +12,8 @@ function FileListFile(props: { file: FileListElementType }) {
1312
<input
1413
type={'checkbox'}
1514
className={'checkbox checkbox-accent checkbox-xs'}
16-
checked={props.file.element.checked}
17-
onChange={(e) => dispatch(updateFileListElement(updateFileListElementTypeChecked(props.file, e.target.checked)))}
15+
checked={props.file.checked}
16+
onChange={(e) => dispatch(updateFileListElement({ ...props.file, checked: e.target.checked }))}
1817
/>
1918
<div className={fileListElementsStyles.element}>
2019
<img src={FileIcon} alt={`folder ${props.file.name}`} />

binocular-frontend-new/src/components/tabs/fileTree/fileList/fileListElements/fileListFolder.tsx

+11-10
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,30 @@
11
import fileListElementsStyles from './fileListElements.module.scss';
22
import { FileListElementType, FileListElementTypeType } from '../../../../../types/data/fileListType.ts';
3-
import { useState } from 'react';
43
import FolderIcon from '../../../../../assets/folder_gray.svg';
54
import FolderOpenIcon from '../../../../../assets/folder_open_gray.svg';
65
import FileListFile from './fileListFile.tsx';
76
import { AppDispatch, useAppDispatch } from '../../../../../redux';
87
import { updateFileListElement } from '../../../../../redux/reducer/data/filesReducer.ts';
9-
import { updateFileListElementTypeChecked } from '../fileListUtilities/fileTreeUtilities.ts';
108

119
function FileListFolder(props: { folder: FileListElementType; foldedOut: boolean }) {
1210
const dispatch: AppDispatch = useAppDispatch();
13-
const [foldedOut, setFoldedOut] = useState(props.foldedOut);
1411

1512
return (
1613
<>
17-
{foldedOut ? (
14+
{props.folder.foldedOut ? (
1815
<>
1916
<div className={'flex items-center'}>
2017
{props.folder.id !== undefined && (
2118
<input
2219
type={'checkbox'}
2320
className={'checkbox checkbox-accent checkbox-xs'}
24-
checked={props.folder.element.checked}
25-
onChange={(e) => dispatch(updateFileListElement(updateFileListElementTypeChecked(props.folder, e.target.checked)))}
21+
checked={props.folder.checked}
22+
onChange={(e) => dispatch(updateFileListElement({ ...props.folder, checked: e.target.checked }))}
2623
/>
2724
)}
28-
<div className={fileListElementsStyles.element} onClick={() => setFoldedOut(false)}>
25+
<div
26+
className={fileListElementsStyles.element}
27+
onClick={() => dispatch(updateFileListElement({ ...props.folder, foldedOut: false }))}>
2928
<img src={FolderOpenIcon} alt={`folder open ${props.folder.name}`} />
3029
<span>{props.folder.name}</span>
3130
</div>
@@ -58,10 +57,12 @@ function FileListFolder(props: { folder: FileListElementType; foldedOut: boolean
5857
<input
5958
type={'checkbox'}
6059
className={'checkbox checkbox-accent checkbox-xs'}
61-
checked={props.folder.element.checked}
62-
onChange={(e) => dispatch(updateFileListElement(updateFileListElementTypeChecked(props.folder, e.target.checked)))}
60+
checked={props.folder.checked}
61+
onChange={(e) => dispatch(updateFileListElement({ ...props.folder, checked: e.target.checked }))}
6362
/>
64-
<div onClick={() => setFoldedOut(true)} className={fileListElementsStyles.element}>
63+
<div
64+
onClick={() => dispatch(updateFileListElement({ ...props.folder, foldedOut: true }))}
65+
className={fileListElementsStyles.element}>
6566
<img src={FolderIcon} alt={`folder ${props.folder.name}`} />
6667
<span>{props.folder.name}</span>
6768
</div>
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
import { FileListElementType, FileListElementTypeType } from '../../../../../types/data/fileListType.ts';
2-
import { FileType } from '../../../../../types/data/fileType.ts';
2+
import { DataPluginFile } from '../../../../../plugins/interfaces/dataPluginInterfaces/dataPluginFiles.ts';
33

4-
export function generateFileTree(files: FileType[]): FileListElementType[] {
4+
export function generateFileTree(files: DataPluginFile[]): FileListElementType[] {
55
return convertData(files).content;
66
}
77

8-
function convertData(files: FileType[]) {
8+
function convertData(files: DataPluginFile[]) {
99
const convertedData = { content: [] };
1010
let id = 0;
1111
for (const file of files) {
12-
if (file.file) {
13-
const pathParts = file.file.path.split('/');
12+
if (file) {
13+
const pathParts = file.path.split('/');
1414
id = genPathObjectString(convertedData.content, pathParts, file, id);
1515
}
1616
}
1717
return convertedData;
1818
}
1919

20-
function genPathObjectString(convertedData: FileListElementType[], pathParts: string[], file: FileType, id: number) {
20+
function genPathObjectString(convertedData: FileListElementType[], pathParts: string[], file: DataPluginFile, id: number) {
2121
const currElm = pathParts.shift();
2222
id++;
2323
if (currElm) {
@@ -26,7 +26,9 @@ function genPathObjectString(convertedData: FileListElementType[], pathParts: st
2626
name: currElm,
2727
id: id,
2828
type: FileListElementTypeType.File,
29+
checked: true,
2930
element: file,
31+
foldedOut: false,
3032
});
3133
} else {
3234
let elem = convertedData.find((d) => d.name === currElm);
@@ -36,7 +38,8 @@ function genPathObjectString(convertedData: FileListElementType[], pathParts: st
3638
id: id,
3739
type: FileListElementTypeType.Folder,
3840
children: [],
39-
element: { checked: true },
41+
checked: true,
42+
foldedOut: false,
4043
};
4144
if (elem.children) {
4245
id = genPathObjectString(elem.children, pathParts, file, id);
@@ -51,7 +54,3 @@ function genPathObjectString(convertedData: FileListElementType[], pathParts: st
5154
}
5255
return id;
5356
}
54-
55-
export function updateFileListElementTypeChecked(fileListElement: FileListElementType, checked: boolean) {
56-
return { ...fileListElement, element: { ...fileListElement.element, checked: checked } };
57-
}

binocular-frontend-new/src/redux/reducer/data/filesReducer.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,11 @@ function updateFileListElementRecursive(
5858
fileList.children = fileList.children.map((f: FileListElementType) => {
5959
let elementChecked = checked;
6060
if (f.id === element.id) {
61-
elementChecked = element.element.checked;
61+
elementChecked = element.checked;
62+
f.foldedOut = element.foldedOut;
6263
}
6364
if (elementChecked !== undefined) {
64-
f.element.checked = elementChecked;
65+
f.checked = elementChecked;
6566
}
6667
updateFileListElementRecursive(f, element, elementChecked);
6768
return f;

binocular-frontend-new/src/types/data/fileListType.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
import { FileType } from './fileType.ts';
1+
import { DataPluginFile } from '../../plugins/interfaces/dataPluginInterfaces/dataPluginFiles.ts';
22

33
export interface FileListElementType {
44
name: string;
55
id?: number;
66
type: FileListElementTypeType;
7-
element: FileType;
7+
element?: DataPluginFile;
88
children?: FileListElementType[];
9+
checked: boolean;
10+
foldedOut: boolean;
911
}
1012

1113
export enum FileListElementTypeType {

binocular-frontend-new/src/types/data/fileType.ts

-6
This file was deleted.

0 commit comments

Comments
 (0)