@headless-tree/core 0.0.11 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/lib/cjs/core/build-static-instance.js +1 -2
- package/lib/cjs/core/create-tree.js +7 -4
- package/lib/cjs/features/async-data-loader/feature.d.ts +1 -4
- package/lib/cjs/features/async-data-loader/feature.js +5 -7
- package/lib/cjs/features/async-data-loader/types.d.ts +2 -5
- package/lib/cjs/features/drag-and-drop/feature.d.ts +2 -3
- package/lib/cjs/features/drag-and-drop/feature.js +27 -24
- package/lib/cjs/features/drag-and-drop/types.d.ts +3 -3
- package/lib/cjs/features/drag-and-drop/utils.d.ts +1 -1
- package/lib/cjs/features/drag-and-drop/utils.js +4 -4
- package/lib/cjs/features/expand-all/feature.d.ts +1 -5
- package/lib/cjs/features/hotkeys-core/feature.d.ts +1 -3
- package/lib/cjs/features/prop-memoization/feature.d.ts +2 -0
- package/lib/cjs/features/prop-memoization/feature.js +48 -0
- package/lib/cjs/features/prop-memoization/types.d.ts +10 -0
- package/lib/cjs/features/prop-memoization/types.js +2 -0
- package/lib/cjs/features/renaming/feature.d.ts +1 -4
- package/lib/cjs/features/renaming/feature.js +8 -9
- package/lib/cjs/features/renaming/types.d.ts +1 -1
- package/lib/cjs/features/search/feature.d.ts +1 -4
- package/lib/cjs/features/selection/feature.d.ts +1 -4
- package/lib/cjs/features/selection/feature.js +35 -25
- package/lib/cjs/features/selection/types.d.ts +1 -1
- package/lib/cjs/features/sync-data-loader/feature.d.ts +1 -3
- package/lib/cjs/features/tree/feature.d.ts +1 -6
- package/lib/cjs/features/tree/feature.js +40 -57
- package/lib/cjs/features/tree/types.d.ts +0 -5
- package/lib/cjs/index.d.ts +2 -0
- package/lib/cjs/index.js +2 -0
- package/lib/cjs/mddocs-entry.d.ts +10 -0
- package/lib/cjs/test-utils/test-tree-do.d.ts +1 -1
- package/lib/cjs/test-utils/test-tree-expect.d.ts +1 -1
- package/lib/cjs/test-utils/test-tree-expect.js +1 -1
- package/lib/cjs/test-utils/test-tree.d.ts +1 -1
- package/lib/cjs/test-utils/test-tree.js +9 -1
- package/lib/cjs/types/core.d.ts +29 -30
- package/lib/esm/core/build-static-instance.js +1 -2
- package/lib/esm/core/create-tree.js +7 -4
- package/lib/esm/features/async-data-loader/feature.d.ts +1 -4
- package/lib/esm/features/async-data-loader/feature.js +5 -7
- package/lib/esm/features/async-data-loader/types.d.ts +2 -5
- package/lib/esm/features/drag-and-drop/feature.d.ts +2 -3
- package/lib/esm/features/drag-and-drop/feature.js +27 -24
- package/lib/esm/features/drag-and-drop/types.d.ts +3 -3
- package/lib/esm/features/drag-and-drop/utils.d.ts +1 -1
- package/lib/esm/features/drag-and-drop/utils.js +4 -4
- package/lib/esm/features/expand-all/feature.d.ts +1 -5
- package/lib/esm/features/hotkeys-core/feature.d.ts +1 -3
- package/lib/esm/features/prop-memoization/feature.d.ts +2 -0
- package/lib/esm/features/prop-memoization/feature.js +45 -0
- package/lib/esm/features/prop-memoization/types.d.ts +10 -0
- package/lib/esm/features/prop-memoization/types.js +1 -0
- package/lib/esm/features/renaming/feature.d.ts +1 -4
- package/lib/esm/features/renaming/feature.js +8 -9
- package/lib/esm/features/renaming/types.d.ts +1 -1
- package/lib/esm/features/search/feature.d.ts +1 -4
- package/lib/esm/features/selection/feature.d.ts +1 -4
- package/lib/esm/features/selection/feature.js +35 -25
- package/lib/esm/features/selection/types.d.ts +1 -1
- package/lib/esm/features/sync-data-loader/feature.d.ts +1 -3
- package/lib/esm/features/tree/feature.d.ts +1 -6
- package/lib/esm/features/tree/feature.js +40 -57
- package/lib/esm/features/tree/types.d.ts +0 -5
- package/lib/esm/index.d.ts +2 -0
- package/lib/esm/index.js +2 -0
- package/lib/esm/mddocs-entry.d.ts +10 -0
- package/lib/esm/test-utils/test-tree-do.d.ts +1 -1
- package/lib/esm/test-utils/test-tree-expect.d.ts +1 -1
- package/lib/esm/test-utils/test-tree-expect.js +1 -1
- package/lib/esm/test-utils/test-tree.d.ts +1 -1
- package/lib/esm/test-utils/test-tree.js +9 -1
- package/lib/esm/types/core.d.ts +29 -30
- package/package.json +1 -1
- package/src/core/build-proxified-instance.ts +5 -3
- package/src/core/build-static-instance.ts +1 -2
- package/src/core/core.spec.ts +210 -0
- package/src/core/create-tree.ts +13 -16
- package/src/features/async-data-loader/async-data-loader.spec.ts +12 -31
- package/src/features/async-data-loader/feature.ts +8 -20
- package/src/features/async-data-loader/types.ts +2 -6
- package/src/features/drag-and-drop/drag-and-drop.spec.ts +4 -3
- package/src/features/drag-and-drop/feature.ts +87 -86
- package/src/features/drag-and-drop/types.ts +4 -4
- package/src/features/drag-and-drop/utils.ts +4 -4
- package/src/features/expand-all/expand-all.spec.ts +5 -1
- package/src/features/expand-all/feature.ts +1 -12
- package/src/features/hotkeys-core/feature.ts +4 -13
- package/src/features/prop-memoization/feature.ts +51 -0
- package/src/features/prop-memoization/prop-memoization.spec.ts +68 -0
- package/src/features/prop-memoization/types.ts +11 -0
- package/src/features/renaming/feature.ts +11 -20
- package/src/features/renaming/renaming.spec.ts +11 -9
- package/src/features/renaming/types.ts +1 -1
- package/src/features/search/feature.ts +2 -8
- package/src/features/search/search.spec.ts +3 -1
- package/src/features/selection/feature.ts +45 -47
- package/src/features/selection/selection.spec.ts +13 -14
- package/src/features/selection/types.ts +0 -2
- package/src/features/sync-data-loader/feature.ts +1 -7
- package/src/features/tree/feature.ts +47 -85
- package/src/features/tree/tree.spec.ts +24 -64
- package/src/features/tree/types.ts +0 -6
- package/src/index.ts +2 -0
- package/src/mddocs-entry.ts +13 -0
- package/src/test-utils/test-tree-expect.ts +1 -1
- package/src/test-utils/test-tree.ts +11 -1
- package/src/types/core.ts +56 -147
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { TestTree } from "../test-utils/test-tree";
|
|
3
|
+
|
|
4
|
+
declare module "../types/core" {
|
|
5
|
+
export interface TreeInstance<T> {
|
|
6
|
+
customHandler: (param1: number, param2: number) => void;
|
|
7
|
+
}
|
|
8
|
+
export interface ItemInstance<T> {
|
|
9
|
+
customHandler: (param1: number, param2: number) => void;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const handler1 = vi.fn(({ prev }, ...params) => prev?.(...params));
|
|
14
|
+
const handler2 = vi.fn(({ prev }, ...params) => prev?.(...params));
|
|
15
|
+
|
|
16
|
+
const factory = TestTree.default({});
|
|
17
|
+
|
|
18
|
+
describe("core-feature/prop-memoization", () => {
|
|
19
|
+
factory.forSuits((tree) => {
|
|
20
|
+
describe("calls prev in correct order", () => {
|
|
21
|
+
it("tree instance with overwrite marks, order 1", async () => {
|
|
22
|
+
const testTree = await tree
|
|
23
|
+
.withFeatures(
|
|
24
|
+
{
|
|
25
|
+
key: "feature2",
|
|
26
|
+
overwrites: ["feature1"],
|
|
27
|
+
treeInstance: {
|
|
28
|
+
customHandler: handler1,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
key: "feature1",
|
|
33
|
+
treeInstance: {
|
|
34
|
+
customHandler: () => 123,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
key: "feature3",
|
|
39
|
+
overwrites: ["feature2"],
|
|
40
|
+
treeInstance: {
|
|
41
|
+
customHandler: handler2,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
)
|
|
45
|
+
.createTestCaseTree();
|
|
46
|
+
|
|
47
|
+
expect(testTree.instance.customHandler(1, 2)).toBe(123);
|
|
48
|
+
expect(handler2).toHaveBeenCalledBefore(handler1);
|
|
49
|
+
expect(handler1).toBeCalledWith(expect.anything(), 1, 2);
|
|
50
|
+
expect(handler2).toBeCalledWith(expect.anything(), 1, 2);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("tree instance with overwrite marks, order 2", async () => {
|
|
54
|
+
const testTree = await tree
|
|
55
|
+
.withFeatures(
|
|
56
|
+
{
|
|
57
|
+
key: "feature3",
|
|
58
|
+
overwrites: ["feature2"],
|
|
59
|
+
treeInstance: {
|
|
60
|
+
customHandler: handler2,
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
key: "feature2",
|
|
65
|
+
overwrites: ["feature1"],
|
|
66
|
+
treeInstance: {
|
|
67
|
+
customHandler: handler1,
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
key: "feature1",
|
|
72
|
+
treeInstance: {
|
|
73
|
+
customHandler: () => 123,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
)
|
|
77
|
+
.createTestCaseTree();
|
|
78
|
+
|
|
79
|
+
expect(testTree.instance.customHandler(1, 2)).toBe(123);
|
|
80
|
+
expect(handler2).toHaveBeenCalledBefore(handler1);
|
|
81
|
+
expect(handler1).toBeCalledWith(expect.anything(), 1, 2);
|
|
82
|
+
expect(handler2).toBeCalledWith(expect.anything(), 1, 2);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("tree instance with implicit order", async () => {
|
|
86
|
+
const testTree = await tree
|
|
87
|
+
.withFeatures(
|
|
88
|
+
{
|
|
89
|
+
key: "feature1",
|
|
90
|
+
treeInstance: {
|
|
91
|
+
customHandler: () => 123,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
key: "feature2",
|
|
96
|
+
treeInstance: {
|
|
97
|
+
customHandler: handler1,
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
key: "feature3",
|
|
102
|
+
treeInstance: {
|
|
103
|
+
customHandler: handler2,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
)
|
|
107
|
+
.createTestCaseTree();
|
|
108
|
+
|
|
109
|
+
expect(testTree.instance.customHandler(1, 2)).toBe(123);
|
|
110
|
+
expect(handler2).toHaveBeenCalledBefore(handler1);
|
|
111
|
+
expect(handler1).toBeCalledWith(expect.anything(), 1, 2);
|
|
112
|
+
expect(handler2).toBeCalledWith(expect.anything(), 1, 2);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("item instance with overwrite marks, order 1", async () => {
|
|
116
|
+
const testTree = await tree
|
|
117
|
+
.withFeatures(
|
|
118
|
+
{
|
|
119
|
+
key: "feature2",
|
|
120
|
+
overwrites: ["feature1"],
|
|
121
|
+
itemInstance: {
|
|
122
|
+
customHandler: handler1,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
key: "feature1",
|
|
127
|
+
itemInstance: {
|
|
128
|
+
customHandler: () => 123,
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
key: "feature3",
|
|
133
|
+
overwrites: ["feature2"],
|
|
134
|
+
itemInstance: {
|
|
135
|
+
customHandler: handler2,
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
)
|
|
139
|
+
.createTestCaseTree();
|
|
140
|
+
|
|
141
|
+
expect(testTree.item("x111").customHandler(1, 2)).toBe(123);
|
|
142
|
+
expect(handler2).toHaveBeenCalledBefore(handler1);
|
|
143
|
+
expect(handler1).toBeCalledWith(expect.anything(), 1, 2);
|
|
144
|
+
expect(handler2).toBeCalledWith(expect.anything(), 1, 2);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("item instance with overwrite marks, order 2", async () => {
|
|
148
|
+
const testTree = await tree
|
|
149
|
+
.withFeatures(
|
|
150
|
+
{
|
|
151
|
+
key: "feature3",
|
|
152
|
+
overwrites: ["feature2"],
|
|
153
|
+
itemInstance: {
|
|
154
|
+
customHandler: handler2,
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
key: "feature2",
|
|
159
|
+
overwrites: ["feature1"],
|
|
160
|
+
itemInstance: {
|
|
161
|
+
customHandler: handler1,
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
key: "feature1",
|
|
166
|
+
itemInstance: {
|
|
167
|
+
customHandler: () => 123,
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
)
|
|
171
|
+
.createTestCaseTree();
|
|
172
|
+
|
|
173
|
+
expect(testTree.item("x111").customHandler(1, 2)).toBe(123);
|
|
174
|
+
expect(handler2).toHaveBeenCalledBefore(handler1);
|
|
175
|
+
expect(handler1).toBeCalledWith(expect.anything(), 1, 2);
|
|
176
|
+
expect(handler2).toBeCalledWith(expect.anything(), 1, 2);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it("item instance with implicit order", async () => {
|
|
180
|
+
const testTree = await tree
|
|
181
|
+
.withFeatures(
|
|
182
|
+
{
|
|
183
|
+
key: "feature1",
|
|
184
|
+
itemInstance: {
|
|
185
|
+
customHandler: () => 123,
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
key: "feature2",
|
|
190
|
+
itemInstance: {
|
|
191
|
+
customHandler: handler1,
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
key: "feature3",
|
|
196
|
+
itemInstance: {
|
|
197
|
+
customHandler: handler2,
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
)
|
|
201
|
+
.createTestCaseTree();
|
|
202
|
+
|
|
203
|
+
expect(testTree.item("x111").customHandler(1, 2)).toBe(123);
|
|
204
|
+
expect(handler2).toHaveBeenCalledBefore(handler1);
|
|
205
|
+
expect(handler1).toBeCalledWith(expect.anything(), 1, 2);
|
|
206
|
+
expect(handler2).toBeCalledWith(expect.anything(), 1, 2);
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
});
|
package/src/core/create-tree.ts
CHANGED
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
TreeState,
|
|
8
8
|
Updater,
|
|
9
9
|
} from "../types/core";
|
|
10
|
-
import { MainFeatureDef } from "../features/main/types";
|
|
11
10
|
import { treeFeature } from "../features/tree/feature";
|
|
12
11
|
import { ItemMeta } from "../features/tree/types";
|
|
13
12
|
import { buildStaticInstance } from "./build-static-instance";
|
|
@@ -25,18 +24,20 @@ const verifyFeatures = (features: FeatureImplementation[] | undefined) => {
|
|
|
25
24
|
}
|
|
26
25
|
};
|
|
27
26
|
|
|
28
|
-
const compareFeatures =
|
|
29
|
-
|
|
30
|
-
feature2: FeatureImplementation
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
27
|
+
const compareFeatures =
|
|
28
|
+
(originalOrder: FeatureImplementation[]) =>
|
|
29
|
+
(feature1: FeatureImplementation, feature2: FeatureImplementation) => {
|
|
30
|
+
if (feature2.key && feature1.overwrites?.includes(feature2.key)) {
|
|
31
|
+
return 1;
|
|
32
|
+
}
|
|
33
|
+
if (feature1.key && feature2.overwrites?.includes(feature1.key)) {
|
|
34
|
+
return -1;
|
|
35
|
+
}
|
|
36
|
+
return originalOrder.indexOf(feature1) - originalOrder.indexOf(feature2);
|
|
37
|
+
};
|
|
37
38
|
|
|
38
39
|
const sortFeatures = (features: FeatureImplementation[] = []) =>
|
|
39
|
-
features.sort(compareFeatures);
|
|
40
|
+
features.sort(compareFeatures(features));
|
|
40
41
|
|
|
41
42
|
export const createTree = <T>(
|
|
42
43
|
initialConfig: TreeConfig<T>,
|
|
@@ -128,11 +129,7 @@ export const createTree = <T>(
|
|
|
128
129
|
}
|
|
129
130
|
};
|
|
130
131
|
|
|
131
|
-
const mainFeature: FeatureImplementation<
|
|
132
|
-
T,
|
|
133
|
-
MainFeatureDef<T>,
|
|
134
|
-
MainFeatureDef<T>
|
|
135
|
-
> = {
|
|
132
|
+
const mainFeature: FeatureImplementation<T> = {
|
|
136
133
|
key: "main",
|
|
137
134
|
treeInstance: {
|
|
138
135
|
getState: () => state,
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { describe, expect, it, vi } from "vitest";
|
|
2
2
|
import { TestTree } from "../../test-utils/test-tree";
|
|
3
3
|
import { asyncDataLoaderFeature } from "./feature";
|
|
4
|
+
import { propMemoizationFeature } from "../prop-memoization/feature";
|
|
4
5
|
|
|
5
|
-
const tree = TestTree.default({}).withFeatures(
|
|
6
|
+
const tree = TestTree.default({}).withFeatures(
|
|
7
|
+
asyncDataLoaderFeature,
|
|
8
|
+
propMemoizationFeature,
|
|
9
|
+
);
|
|
6
10
|
|
|
7
11
|
describe("core-feature/selections", () => {
|
|
8
12
|
tree.resetBeforeEach();
|
|
@@ -75,44 +79,21 @@ describe("core-feature/selections", () => {
|
|
|
75
79
|
const suiteTree = tree.with({ asyncDataLoader: { getItem, getChildren } });
|
|
76
80
|
suiteTree.resetBeforeEach();
|
|
77
81
|
|
|
78
|
-
it("invalidates item data on tree instance", async () => {
|
|
79
|
-
getItem.mockClear();
|
|
80
|
-
getItem.mockResolvedValueOnce("new");
|
|
81
|
-
suiteTree.instance.invalidateItemData("x1");
|
|
82
|
-
await suiteTree.resolveAsyncVisibleItems();
|
|
83
|
-
expect(getItem).toHaveBeenCalledWith("x1");
|
|
84
|
-
expect(suiteTree.instance.getItemInstance("x1").getItemData()).toBe(
|
|
85
|
-
"new",
|
|
86
|
-
);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
82
|
it("invalidates item data on item instance", async () => {
|
|
90
83
|
getItem.mockClear();
|
|
91
84
|
await suiteTree.resolveAsyncVisibleItems();
|
|
92
85
|
getItem.mockResolvedValueOnce("new");
|
|
93
|
-
suiteTree.
|
|
86
|
+
suiteTree.item("x1").invalidateItemData();
|
|
94
87
|
await suiteTree.resolveAsyncVisibleItems();
|
|
95
88
|
expect(getItem).toHaveBeenCalledWith("x1");
|
|
96
|
-
expect(suiteTree.
|
|
97
|
-
"new",
|
|
98
|
-
);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it("invalidates children ids on tree instance", async () => {
|
|
102
|
-
getChildren.mockClear();
|
|
103
|
-
await suiteTree.resolveAsyncVisibleItems();
|
|
104
|
-
getChildren.mockResolvedValueOnce(["new1", "new2"]);
|
|
105
|
-
suiteTree.instance.invalidateChildrenIds("x1");
|
|
106
|
-
await suiteTree.resolveAsyncVisibleItems();
|
|
107
|
-
expect(getChildren).toHaveBeenCalledWith("x1");
|
|
108
|
-
suiteTree.expect.hasChildren("x1", ["new1", "new2"]);
|
|
89
|
+
expect(suiteTree.item("x1").getItemData()).toBe("new");
|
|
109
90
|
});
|
|
110
91
|
|
|
111
92
|
it("invalidates children ids on item instance", async () => {
|
|
112
93
|
getChildren.mockClear();
|
|
113
94
|
await suiteTree.resolveAsyncVisibleItems();
|
|
114
95
|
getChildren.mockResolvedValueOnce(["new1", "new2"]);
|
|
115
|
-
suiteTree.
|
|
96
|
+
suiteTree.item("x1").invalidateChildrenIds();
|
|
116
97
|
await suiteTree.resolveAsyncVisibleItems();
|
|
117
98
|
expect(getChildren).toHaveBeenCalledWith("x1");
|
|
118
99
|
suiteTree.expect.hasChildren("x1", ["new1", "new2"]);
|
|
@@ -121,17 +102,17 @@ describe("core-feature/selections", () => {
|
|
|
121
102
|
it("doesnt call item data getter twice", async () => {
|
|
122
103
|
await suiteTree.resolveAsyncVisibleItems();
|
|
123
104
|
getItem.mockClear();
|
|
124
|
-
suiteTree.
|
|
105
|
+
suiteTree.item("x1").invalidateItemData();
|
|
125
106
|
await suiteTree.resolveAsyncVisibleItems();
|
|
126
|
-
expect(suiteTree.
|
|
127
|
-
expect(suiteTree.
|
|
107
|
+
expect(suiteTree.item("x1").getItemData()).toBe("x1");
|
|
108
|
+
expect(suiteTree.item("x1").getItemData()).toBe("x1");
|
|
128
109
|
expect(getItem).toHaveBeenCalledTimes(1);
|
|
129
110
|
});
|
|
130
111
|
|
|
131
112
|
it("doesnt call children getter twice", async () => {
|
|
132
113
|
await suiteTree.resolveAsyncVisibleItems();
|
|
133
114
|
getChildren.mockClear();
|
|
134
|
-
suiteTree.
|
|
115
|
+
suiteTree.item("x1").invalidateChildrenIds();
|
|
135
116
|
await suiteTree.resolveAsyncVisibleItems();
|
|
136
117
|
suiteTree.expect.hasChildren("x1", ["x11", "x12", "x13", "x14"]);
|
|
137
118
|
suiteTree.expect.hasChildren("x1", ["x11", "x12", "x13", "x14"]);
|
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
import { FeatureImplementation } from "../../types/core";
|
|
2
|
-
import {
|
|
3
|
-
import { MainFeatureDef } from "../main/types";
|
|
2
|
+
import { AsyncDataLoaderRef } from "./types";
|
|
4
3
|
import { makeStateUpdater } from "../../utils";
|
|
5
|
-
import { TreeFeatureDef } from "../tree/types";
|
|
6
4
|
|
|
7
|
-
export const asyncDataLoaderFeature: FeatureImplementation
|
|
8
|
-
any,
|
|
9
|
-
AsyncDataLoaderFeatureDef<any>,
|
|
10
|
-
MainFeatureDef | TreeFeatureDef<any> | AsyncDataLoaderFeatureDef<any>
|
|
11
|
-
> = {
|
|
5
|
+
export const asyncDataLoaderFeature: FeatureImplementation = {
|
|
12
6
|
key: "async-data-loader",
|
|
13
7
|
|
|
14
8
|
getInitialState: (initialState) => ({
|
|
@@ -98,27 +92,21 @@ export const asyncDataLoaderFeature: FeatureImplementation<
|
|
|
98
92
|
|
|
99
93
|
return [];
|
|
100
94
|
},
|
|
95
|
+
},
|
|
101
96
|
|
|
102
|
-
|
|
97
|
+
itemInstance: {
|
|
98
|
+
isLoading: ({ tree, item }) =>
|
|
99
|
+
tree.getState().loadingItems.includes(item.getItemMeta().itemId),
|
|
100
|
+
invalidateItemData: ({ tree, itemId }) => {
|
|
103
101
|
const dataRef = tree.getDataRef<AsyncDataLoaderRef>();
|
|
104
102
|
delete dataRef.current.itemData?.[itemId];
|
|
105
103
|
tree.retrieveItemData(itemId);
|
|
106
104
|
},
|
|
107
|
-
|
|
108
|
-
invalidateChildrenIds: ({ tree }, itemId) => {
|
|
105
|
+
invalidateChildrenIds: ({ tree, itemId }) => {
|
|
109
106
|
const dataRef = tree.getDataRef<AsyncDataLoaderRef>();
|
|
110
107
|
delete dataRef.current.childrenIds?.[itemId];
|
|
111
108
|
tree.retrieveChildrenIds(itemId);
|
|
112
109
|
},
|
|
113
|
-
},
|
|
114
|
-
|
|
115
|
-
itemInstance: {
|
|
116
|
-
isLoading: ({ tree, item }) =>
|
|
117
|
-
tree.getState().loadingItems.includes(item.getItemMeta().itemId),
|
|
118
|
-
invalidateItemData: ({ tree, item }) =>
|
|
119
|
-
tree.invalidateItemData(item.getItemMeta().itemId),
|
|
120
|
-
invalidateChildrenIds: ({ tree, item }) =>
|
|
121
|
-
tree.invalidateChildrenIds(item.getItemMeta().itemId),
|
|
122
110
|
updateCachedChildrenIds: ({ tree, itemId }, childrenIds) => {
|
|
123
111
|
const dataRef = tree.getDataRef<AsyncDataLoaderRef>();
|
|
124
112
|
dataRef.current.childrenIds[itemId] = childrenIds;
|
|
@@ -27,13 +27,9 @@ export type AsyncDataLoaderFeatureDef<T> = {
|
|
|
27
27
|
onLoadedChildren?: (itemId: string, childrenIds: string[]) => void;
|
|
28
28
|
asyncDataLoader?: AsyncTreeDataLoader<T>;
|
|
29
29
|
};
|
|
30
|
-
treeInstance: SyncDataLoaderFeatureDef<T>["treeInstance"]
|
|
31
|
-
/** Invalidate fetched data for item, and triggers a refetch and subsequent rerender if the item is visible */
|
|
32
|
-
invalidateItemData: (itemId: string) => void;
|
|
33
|
-
invalidateChildrenIds: (itemId: string) => void;
|
|
34
|
-
// TODO deprecate tree instance methods, move to item instance
|
|
35
|
-
};
|
|
30
|
+
treeInstance: SyncDataLoaderFeatureDef<T>["treeInstance"];
|
|
36
31
|
itemInstance: SyncDataLoaderFeatureDef<T>["itemInstance"] & {
|
|
32
|
+
/** Invalidate fetched data for item, and triggers a refetch and subsequent rerender if the item is visible */
|
|
37
33
|
invalidateItemData: () => void;
|
|
38
34
|
invalidateChildrenIds: () => void;
|
|
39
35
|
updateCachedChildrenIds: (childrenIds: string[]) => void;
|
|
@@ -4,6 +4,7 @@ import { dragAndDropFeature } from "./feature";
|
|
|
4
4
|
import { selectionFeature } from "../selection/feature";
|
|
5
5
|
import { ItemInstance } from "../../types/core";
|
|
6
6
|
import { createOnDropHandler } from "../../utilities/create-on-drop-handler";
|
|
7
|
+
import { propMemoizationFeature } from "../prop-memoization/feature";
|
|
7
8
|
|
|
8
9
|
const isItem = (item: unknown): item is ItemInstance<any> =>
|
|
9
10
|
!!item && typeof item === "object" && "getId" in item;
|
|
@@ -20,7 +21,7 @@ const factory = TestTree.default({
|
|
|
20
21
|
expandedItems: ["x1", "x11", "x2", "x21"],
|
|
21
22
|
},
|
|
22
23
|
onDrop: vi.fn(),
|
|
23
|
-
}).withFeatures(selectionFeature, dragAndDropFeature);
|
|
24
|
+
}).withFeatures(selectionFeature, dragAndDropFeature, propMemoizationFeature);
|
|
24
25
|
|
|
25
26
|
describe("core-feature/drag-and-drop", () => {
|
|
26
27
|
factory.forSuits((tree) => {
|
|
@@ -534,7 +535,7 @@ describe("core-feature/drag-and-drop", () => {
|
|
|
534
535
|
describe("drop redirection", () => {
|
|
535
536
|
it("redirects to parent folder without inbetween dropping", async () => {
|
|
536
537
|
const testTree = await tree
|
|
537
|
-
.with({
|
|
538
|
+
.with({ canReorder: false })
|
|
538
539
|
.createTestCaseTree();
|
|
539
540
|
testTree.do.startDrag("x111");
|
|
540
541
|
testTree.do.dragOverAndDrop("x212", testTree.createBottomDragEvent(2));
|
|
@@ -549,7 +550,7 @@ describe("core-feature/drag-and-drop", () => {
|
|
|
549
550
|
|
|
550
551
|
it("doesnt redirect to parent folder with inbetween dropping", async () => {
|
|
551
552
|
const testTree = await tree
|
|
552
|
-
.with({
|
|
553
|
+
.with({ canReorder: true })
|
|
553
554
|
.createTestCaseTree();
|
|
554
555
|
testTree.do.startDrag("x111");
|
|
555
556
|
testTree.do.dragOverAndDrop("x212", testTree.createBottomDragEvent(2));
|