Skip to content

Commit 1dfee56

Browse files
authored
fix: improve tree helper types (#248)
* fix: improve tree helper types * fix: improve interface name
1 parent c505abe commit 1dfee56

File tree

4 files changed

+147
-130
lines changed

4 files changed

+147
-130
lines changed

src/extensions/folderTree/index.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,8 @@ export const ExtendsFolderTree: IExtension = {
9393
isEditable: false,
9494
});
9595
} else {
96-
// TODO: improve tree helper types
97-
const node = (tree.get(id) as unknown) as ITreeNodeItemProps;
98-
if (node.name) {
96+
const node = tree.get(id);
97+
if (node?.name) {
9998
tree.update(id, {
10099
isEditable: false,
101100
});

src/services/helper.ts

+124-106
Original file line numberDiff line numberDiff line change
@@ -2,74 +2,61 @@ export function searchById(id) {
22
return (item) => item.id === id;
33
}
44

5+
interface BaseProps {
6+
id?: number;
7+
8+
[key: string]: any;
9+
}
10+
511
export interface IIndex<T> {
612
id?: number;
713
node?: T;
814
parent?: number;
9-
prev?: number;
10-
next?: number;
15+
prev?: number | null;
16+
next?: number | null;
1117
[x: string]: any; // default: children: []
1218
}
1319
export interface IIndexs<T> {
14-
[index: number]: IIndex<T>;
20+
[index: string]: IIndex<T>;
1521
}
16-
export interface ITreeInterface<T = any> {
22+
export interface ITreeInterface<T extends BaseProps> {
1723
count: number;
1824
obj: T;
1925
indexes: IIndexs<T>;
2026
childNodeName: string;
2127
}
2228

23-
export interface ITreeInstance<T = any> {
24-
count: number;
25-
obj: T;
26-
indexes: IIndexs<T>;
27-
childNodeName: string;
28-
generate: (obj) => void;
29-
getIndex: (index: number) => void;
30-
removeIndex: (index: number) => void;
31-
get: (id: number) => void;
32-
remove: (id: number) => void;
33-
update: (id: number, extra) => void;
34-
updateChildren: (children: IIndex<T>) => void;
35-
insert: (obj: T, parentId: number, i: number) => void;
36-
insertBefore: (obj: T, destId: number) => void;
37-
insertAfter: (obj: T, destId: number) => void;
38-
prepend: (obj: T, destId: number) => void;
39-
append: (obj: T, destId: number) => void;
40-
}
41-
42-
export class TreeViewUtil<T = any> implements ITreeInterface<T> {
29+
export class TreeViewUtil<T extends BaseProps> implements ITreeInterface<T> {
4330
count: number;
4431
obj: T;
4532
indexes: IIndexs<T>;
4633
childNodeName: string;
4734

4835
/**
49-
*
50-
* @param obj // tree object
51-
* @param childNodeName // loop properties
52-
* @example indexes data structure example:
36+
*
37+
* indexes data structure example:
38+
* ```ts
5339
* {
54-
[2]: {
55-
id: 2,
56-
node: {},
57-
parent: 1,
58-
prev: null,
59-
next: 3
60-
},
61-
...
62-
}
40+
* [2]: {
41+
* id: 2,
42+
* node: {},
43+
* parent: 1,
44+
* prev: null,
45+
* next: 3
46+
* },
47+
* ...
48+
* }
49+
* ```
6350
*/
64-
constructor(obj?, childNodeName = 'children') {
51+
constructor(obj?: T, childNodeName = 'children') {
6552
this.count = 1; // nodes count
66-
this.obj = obj || { [childNodeName]: [] };
53+
this.obj = obj || ({ [childNodeName]: [] } as any);
6754
this.indexes = {};
6855
this.childNodeName = childNodeName;
6956
this.generate(this.obj);
7057
}
7158

72-
generate(obj) {
59+
generate(obj: T) {
7360
const indexes = this.indexes;
7461
const startId = obj.id;
7562
const self = this;
@@ -114,19 +101,16 @@ export class TreeViewUtil<T = any> implements ITreeInterface<T> {
114101
getIndex(id: number) {
115102
const index = this.indexes[id + ''];
116103
if (index) return index;
104+
return null;
117105
}
118106

119-
removeIndex(index: number) {
120-
const self = this;
121-
del(index);
122-
123-
function del(index) {
124-
delete self.indexes[index.id + ''];
125-
if (index[self.childNodeName]?.length) {
126-
index[self.childNodeName].forEach(function (child) {
127-
del(self.getIndex(child));
128-
});
129-
}
107+
removeIndex(index: IIndex<T>) {
108+
delete this.indexes[index.id + ''];
109+
if (index[this.childNodeName]?.length) {
110+
index[this.childNodeName].forEach((child) => {
111+
const childIndex = this.getIndex(child);
112+
childIndex && this.removeIndex(childIndex);
113+
});
130114
}
131115
}
132116

@@ -138,87 +122,114 @@ export class TreeViewUtil<T = any> implements ITreeInterface<T> {
138122

139123
remove(id: number) {
140124
const index = this.getIndex(id);
141-
const node = this.get(id);
142-
const parentIndex = this.getIndex(index.parent);
143-
const parentNode = this.get(index.parent);
144-
145-
parentNode[this.childNodeName].splice(
146-
parentNode[this.childNodeName].indexOf(node),
147-
1
148-
);
149-
parentIndex[this.childNodeName].splice(
150-
parentIndex[this.childNodeName].indexOf(id),
151-
1
152-
);
153-
this.removeIndex(index);
154-
this.updateChildren(parentIndex[this.childNodeName]);
155-
156-
return node;
125+
if (index) {
126+
const node = this.get(id);
127+
const parentIndex = this.getIndex(index.parent!);
128+
const parentNode = this.get(index.parent!);
129+
130+
if (parentNode && parentIndex) {
131+
parentNode[this.childNodeName].splice(
132+
parentNode[this.childNodeName].indexOf(node),
133+
1
134+
);
135+
parentIndex[this.childNodeName].splice(
136+
parentIndex[this.childNodeName].indexOf(id),
137+
1
138+
);
139+
this.removeIndex(index);
140+
this.updateChildren(parentIndex[this.childNodeName]);
141+
142+
return node;
143+
}
144+
}
145+
return null;
157146
}
158147

159148
update(id: number, extra = {}) {
160149
const index = this.getIndex(id);
161150
const node = this.get(id);
162-
const parentIndex = this.getIndex(index.parent);
163-
const parentNode = this.get(index.parent);
164-
parentNode[this.childNodeName].splice(
165-
parentNode[this.childNodeName].indexOf(node),
166-
1,
167-
{
168-
...node,
169-
...extra,
151+
if (index) {
152+
const parentIndex = this.getIndex(index.parent!);
153+
const parentNode = this.get(index.parent!);
154+
if (parentNode && parentIndex) {
155+
parentNode[this.childNodeName].splice(
156+
parentNode[this.childNodeName].indexOf(node),
157+
1,
158+
{
159+
...node,
160+
...extra,
161+
}
162+
);
163+
this.updateChildren(parentIndex[this.childNodeName]);
164+
return node;
170165
}
171-
);
172-
this.updateChildren(parentIndex[this.childNodeName]);
173-
174-
return node;
166+
}
167+
return null;
175168
}
176169

177170
updateChildren(children: IIndex<T>) {
178171
const self = this;
179172
children.forEach(function (id, i) {
180173
const index = self.getIndex(id);
181-
index.prev = index.next = null;
182-
if (i > 0) index.prev = children[i - 1];
183-
if (i < children.length - 1) index.next = children[i + 1];
174+
if (index) {
175+
index.prev = index.next = null;
176+
if (i > 0) index.prev = children[i - 1];
177+
if (i < children.length - 1) index.next = children[i + 1];
178+
}
184179
});
185180
}
186181

187182
insert(obj: T, parentId: number, i: number) {
188183
const parentIndex = this.getIndex(parentId);
189184
const parentNode = this.get(parentId);
185+
if (parentNode && parentIndex) {
186+
const index = this.generate(obj);
187+
index.parent = parentId;
188+
189+
(parentNode as BaseProps)[this.childNodeName] =
190+
parentNode[this.childNodeName] || [];
191+
parentIndex[this.childNodeName] =
192+
parentIndex[this.childNodeName] || [];
193+
194+
parentNode[this.childNodeName].splice(i, 0, obj);
195+
parentIndex[this.childNodeName].splice(i, 0, index.id);
196+
197+
this.updateChildren(parentIndex[this.childNodeName]);
198+
if (parentIndex.parent) {
199+
const fartherParent = this.getIndex(parentIndex.parent);
200+
fartherParent &&
201+
this.updateChildren(fartherParent[this.childNodeName]);
202+
}
190203

191-
const index = this.generate(obj);
192-
index.parent = parentId;
193-
194-
parentNode[this.childNodeName] = parentNode[this.childNodeName] || [];
195-
parentIndex[this.childNodeName] = parentIndex[this.childNodeName] || [];
196-
197-
parentNode[this.childNodeName].splice(i, 0, obj);
198-
parentIndex[this.childNodeName].splice(i, 0, index.id);
199-
200-
this.updateChildren(parentIndex[this.childNodeName]);
201-
if (parentIndex.parent) {
202-
this.updateChildren(
203-
this.getIndex(parentIndex.parent)[this.childNodeName]
204-
);
204+
return index;
205205
}
206-
207-
return index;
206+
return null;
208207
}
209208

210209
insertBefore(obj: T, destId: number) {
211210
const destIndex = this.getIndex(destId);
212-
const parentId = destIndex.parent;
213-
const i = this.getIndex(parentId)[this.childNodeName].indexOf(destId);
214-
return this.insert(obj, parentId, i);
211+
if (destIndex) {
212+
const parentId = destIndex.parent;
213+
const parent = this.getIndex(parentId!);
214+
if (parent) {
215+
const i = parent[this.childNodeName].indexOf(destId);
216+
return this.insert(obj, parentId!, i);
217+
}
218+
}
219+
return null;
215220
}
216221

217222
insertAfter(obj: T, destId: number) {
218223
const destIndex = this.getIndex(destId);
219-
const parentId = destIndex.parent;
220-
const i = this.getIndex(parentId)[this.childNodeName].indexOf(destId);
221-
return this.insert(obj, parentId, i + 1);
224+
if (destIndex) {
225+
const parentId = destIndex.parent;
226+
const parent = this.getIndex(parentId!);
227+
if (parent) {
228+
const i = parent[this.childNodeName].indexOf(destId);
229+
return this.insert(obj, parentId!, i + 1);
230+
}
231+
}
232+
return null;
222233
}
223234

224235
prepend(obj: T, destId: number) {
@@ -227,7 +238,14 @@ export class TreeViewUtil<T = any> implements ITreeInterface<T> {
227238

228239
append(obj: T, destId: number) {
229240
const destIndex = this.getIndex(destId);
230-
destIndex[this.childNodeName] = destIndex[this.childNodeName] || [];
231-
return this.insert(obj, destId, destIndex[this.childNodeName].length);
241+
if (destIndex) {
242+
destIndex[this.childNodeName] = destIndex[this.childNodeName] || [];
243+
return this.insert(
244+
obj,
245+
destId,
246+
destIndex[this.childNodeName].length
247+
);
248+
}
249+
return null;
232250
}
233251
}

0 commit comments

Comments
 (0)