@mui/x-tree-view-pro 8.0.0-alpha.13 → 8.0.0-alpha.14

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.
Files changed (39) hide show
  1. package/CHANGELOG.md +131 -0
  2. package/RichTreeViewPro/RichTreeViewPro.js +19 -6
  3. package/RichTreeViewPro/RichTreeViewPro.plugins.d.ts +3 -3
  4. package/RichTreeViewPro/RichTreeViewPro.plugins.js +2 -1
  5. package/esm/RichTreeViewPro/RichTreeViewPro.js +19 -6
  6. package/esm/RichTreeViewPro/RichTreeViewPro.plugins.d.ts +3 -3
  7. package/esm/RichTreeViewPro/RichTreeViewPro.plugins.js +2 -1
  8. package/esm/index.js +1 -1
  9. package/esm/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.selectors.d.ts +4 -0
  10. package/esm/internals/plugins/useTreeViewLazyLoading/index.d.ts +1 -0
  11. package/esm/internals/plugins/useTreeViewLazyLoading/index.js +1 -0
  12. package/esm/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.d.ts +3 -0
  13. package/esm/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.js +288 -0
  14. package/esm/internals/plugins/useTreeViewLazyLoading/utils.d.ts +32 -0
  15. package/esm/internals/plugins/useTreeViewLazyLoading/utils.js +85 -0
  16. package/esm/internals/utils/releaseInfo.js +1 -1
  17. package/index.js +1 -1
  18. package/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.selectors.d.ts +4 -0
  19. package/internals/plugins/useTreeViewLazyLoading/index.d.ts +1 -0
  20. package/internals/plugins/useTreeViewLazyLoading/index.js +12 -0
  21. package/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.d.ts +3 -0
  22. package/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.js +297 -0
  23. package/internals/plugins/useTreeViewLazyLoading/utils.d.ts +32 -0
  24. package/internals/plugins/useTreeViewLazyLoading/utils.js +89 -0
  25. package/internals/utils/releaseInfo.js +1 -1
  26. package/modern/RichTreeViewPro/RichTreeViewPro.js +19 -6
  27. package/modern/RichTreeViewPro/RichTreeViewPro.plugins.d.ts +3 -3
  28. package/modern/RichTreeViewPro/RichTreeViewPro.plugins.js +2 -1
  29. package/modern/index.js +1 -1
  30. package/modern/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.selectors.d.ts +4 -0
  31. package/modern/internals/plugins/useTreeViewLazyLoading/index.d.ts +1 -0
  32. package/modern/internals/plugins/useTreeViewLazyLoading/index.js +1 -0
  33. package/modern/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.d.ts +3 -0
  34. package/modern/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.js +288 -0
  35. package/modern/internals/plugins/useTreeViewLazyLoading/utils.d.ts +32 -0
  36. package/modern/internals/plugins/useTreeViewLazyLoading/utils.js +85 -0
  37. package/modern/internals/utils/releaseInfo.js +1 -1
  38. package/package.json +3 -3
  39. package/tsconfig.build.tsbuildinfo +1 -1
@@ -0,0 +1,32 @@
1
+ import { TreeViewInstance, UseTreeViewLazyLoadingSignature } from '@mui/x-tree-view/internals';
2
+ import { TreeViewItemId } from '@mui/x-tree-view/models';
3
+ export declare enum RequestStatus {
4
+ QUEUED = 0,
5
+ PENDING = 1,
6
+ SETTLED = 2,
7
+ UNKNOWN = 3,
8
+ }
9
+ /**
10
+ * Plugins that the `NestedDataManager` class can use if they are present, but are not required.
11
+ */
12
+ export type NestedDataManagerOptionalPlugins = readonly [];
13
+ /**
14
+ * Fetches row children from the server with option to limit the number of concurrent requests
15
+ * Determines the status of a request based on the enum `RequestStatus`
16
+ * Uses `ParentId` to uniquely identify a request
17
+ */
18
+ export declare class NestedDataManager {
19
+ private pendingRequests;
20
+ private queuedRequests;
21
+ private settledRequests;
22
+ private instance;
23
+ private maxConcurrentRequests;
24
+ constructor(instance: TreeViewInstance<[UseTreeViewLazyLoadingSignature]>, maxConcurrentRequests?: number);
25
+ private processQueue;
26
+ queue: (ids: TreeViewItemId[]) => Promise<void>;
27
+ setRequestSettled: (id: TreeViewItemId) => Promise<void>;
28
+ clear: () => void;
29
+ clearPendingRequest: (id: TreeViewItemId) => Promise<void>;
30
+ getRequestStatus: (id: TreeViewItemId) => RequestStatus;
31
+ getActiveRequestsCount: () => number;
32
+ }
@@ -0,0 +1,85 @@
1
+ const MAX_CONCURRENT_REQUESTS = Infinity;
2
+ export let RequestStatus = /*#__PURE__*/function (RequestStatus) {
3
+ RequestStatus[RequestStatus["QUEUED"] = 0] = "QUEUED";
4
+ RequestStatus[RequestStatus["PENDING"] = 1] = "PENDING";
5
+ RequestStatus[RequestStatus["SETTLED"] = 2] = "SETTLED";
6
+ RequestStatus[RequestStatus["UNKNOWN"] = 3] = "UNKNOWN";
7
+ return RequestStatus;
8
+ }({});
9
+
10
+ /**
11
+ * Plugins that need to be present in the Tree View in order for the `NestedDataManager` class to work correctly.
12
+ */
13
+
14
+ /**
15
+ * Plugins that the `NestedDataManager` class can use if they are present, but are not required.
16
+ */
17
+
18
+ /**
19
+ * Fetches row children from the server with option to limit the number of concurrent requests
20
+ * Determines the status of a request based on the enum `RequestStatus`
21
+ * Uses `ParentId` to uniquely identify a request
22
+ */
23
+ export class NestedDataManager {
24
+ constructor(instance, maxConcurrentRequests = MAX_CONCURRENT_REQUESTS) {
25
+ this.pendingRequests = new Set();
26
+ this.queuedRequests = new Set();
27
+ this.settledRequests = new Set();
28
+ this.instance = void 0;
29
+ this.maxConcurrentRequests = void 0;
30
+ this.processQueue = async () => {
31
+ if (this.queuedRequests.size === 0 || this.pendingRequests.size >= this.maxConcurrentRequests) {
32
+ return;
33
+ }
34
+ const loopLength = Math.min(this.maxConcurrentRequests - this.pendingRequests.size, this.queuedRequests.size);
35
+ if (loopLength === 0) {
36
+ return;
37
+ }
38
+ const fetchQueue = Array.from(this.queuedRequests);
39
+ const fetchPromises = [];
40
+ for (let i = 0; i < loopLength; i += 1) {
41
+ const id = fetchQueue[i];
42
+ this.queuedRequests.delete(id);
43
+ this.pendingRequests.add(id);
44
+ fetchPromises.push(this.instance.fetchItemChildren(id));
45
+ }
46
+ await Promise.all(fetchPromises);
47
+ };
48
+ this.queue = async ids => {
49
+ const loadingIds = {};
50
+ ids.forEach(id => {
51
+ this.queuedRequests.add(id);
52
+ loadingIds[id] = true;
53
+ });
54
+ await this.processQueue();
55
+ };
56
+ this.setRequestSettled = async id => {
57
+ this.pendingRequests.delete(id);
58
+ this.settledRequests.add(id);
59
+ await this.processQueue();
60
+ };
61
+ this.clear = () => {
62
+ this.queuedRequests.clear();
63
+ Array.from(this.pendingRequests).forEach(id => this.clearPendingRequest(id));
64
+ };
65
+ this.clearPendingRequest = async id => {
66
+ this.pendingRequests.delete(id);
67
+ await this.processQueue();
68
+ };
69
+ this.getRequestStatus = id => {
70
+ if (this.pendingRequests.has(id)) {
71
+ return RequestStatus.PENDING;
72
+ }
73
+ if (this.queuedRequests.has(id)) {
74
+ return RequestStatus.QUEUED;
75
+ }
76
+ if (this.settledRequests.has(id)) {
77
+ return RequestStatus.SETTLED;
78
+ }
79
+ return RequestStatus.UNKNOWN;
80
+ };
81
+ this.getActiveRequestsCount = () => this.pendingRequests.size + this.queuedRequests.size;
82
+ this.instance = instance;
83
+ this.maxConcurrentRequests = maxConcurrentRequests;
84
+ }
85
+ }
@@ -1,6 +1,6 @@
1
1
  import ponyfillGlobal from '@mui/utils/ponyfillGlobal';
2
2
  export const getReleaseInfo = () => {
3
- const releaseInfo = "MTc0MDY5NzIwMDAwMA==";
3
+ const releaseInfo = "MTc0MTMwMjAwMDAwMA==";
4
4
  if (process.env.NODE_ENV !== 'production') {
5
5
  // A simple hack to set the value in the test environment (has no build step).
6
6
  // eslint-disable-next-line no-useless-concat
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-tree-view-pro v8.0.0-alpha.13
2
+ * @mui/x-tree-view-pro v8.0.0-alpha.14
3
3
  *
4
4
  * @license MUI X Commercial
5
5
  * This source code is licensed under the commercial license found in the
@@ -89,6 +89,8 @@ export declare const selectorItemsReorderingDraggedItemProperties: ((state: any,
89
89
  [itemId: string]: number;
90
90
  };
91
91
  };
92
+ loading: boolean;
93
+ error: Error | null;
92
94
  }) => {
93
95
  [itemId: string]: import("@mui/x-tree-view/internals").TreeViewItemMeta;
94
96
  };
@@ -108,6 +110,8 @@ export declare const selectorItemsReorderingDraggedItemProperties: ((state: any,
108
110
  [itemId: string]: number;
109
111
  };
110
112
  };
113
+ loading: boolean;
114
+ error: Error | null;
111
115
  }) => {
112
116
  [itemId: string]: import("@mui/x-tree-view/internals").TreeViewItemMeta;
113
117
  }) & {
@@ -0,0 +1 @@
1
+ export { useTreeViewLazyLoading } from "./useTreeViewLazyLoading.js";
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "useTreeViewLazyLoading", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _useTreeViewLazyLoading.useTreeViewLazyLoading;
10
+ }
11
+ });
12
+ var _useTreeViewLazyLoading = require("./useTreeViewLazyLoading");
@@ -0,0 +1,3 @@
1
+ import { TreeViewPlugin } from '@mui/x-tree-view/internals';
2
+ import type { UseTreeViewLazyLoadingSignature } from '@mui/x-tree-view/internals';
3
+ export declare const useTreeViewLazyLoading: TreeViewPlugin<UseTreeViewLazyLoadingSignature>;
@@ -0,0 +1,297 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.useTreeViewLazyLoading = void 0;
9
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
+ var React = _interopRequireWildcard(require("react"));
11
+ var _useLazyRef = _interopRequireDefault(require("@mui/utils/useLazyRef"));
12
+ var _warning = require("@mui/x-internals/warning");
13
+ var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
14
+ var _internals = require("@mui/x-tree-view/internals");
15
+ var _utils = require("@mui/x-tree-view/utils");
16
+ var _utils2 = require("./utils");
17
+ const INITIAL_STATE = {
18
+ loading: {},
19
+ errors: {}
20
+ };
21
+ const noopCache = {
22
+ clear: () => {},
23
+ get: () => undefined,
24
+ set: () => {}
25
+ };
26
+ function getCache(cacheProp) {
27
+ if (cacheProp === null) {
28
+ return noopCache;
29
+ }
30
+ return cacheProp ?? new _utils.DataSourceCacheDefault({});
31
+ }
32
+ const useTreeViewLazyLoading = ({
33
+ instance,
34
+ params,
35
+ store
36
+ }) => {
37
+ const isLazyLoadingEnabled = params.dataSource?.getChildrenCount !== undefined;
38
+ const firstRenderRef = React.useRef(true);
39
+ const nestedDataManager = (0, _useLazyRef.default)(() => new _utils2.NestedDataManager(instance)).current;
40
+ const cacheRef = (0, _useLazyRef.default)(() => getCache(params.dataSourceCache));
41
+ const setDataSourceLoading = (0, _useEventCallback.default)((itemId, isLoading) => {
42
+ if (!isLazyLoadingEnabled) {
43
+ return;
44
+ }
45
+ store.update(prevState => {
46
+ if (!prevState.lazyLoading.dataSource.loading[itemId] && !isLoading) {
47
+ return prevState;
48
+ }
49
+ const loading = (0, _extends2.default)({}, prevState.lazyLoading.dataSource.loading);
50
+ if (isLoading === false) {
51
+ delete loading[itemId];
52
+ } else {
53
+ loading[itemId] = isLoading;
54
+ }
55
+ return (0, _extends2.default)({}, prevState, {
56
+ lazyLoading: (0, _extends2.default)({}, prevState.lazyLoading, {
57
+ dataSource: (0, _extends2.default)({}, prevState.lazyLoading.dataSource, {
58
+ loading
59
+ })
60
+ })
61
+ });
62
+ });
63
+ });
64
+ const setDataSourceError = (itemId, error) => {
65
+ if (!isLazyLoadingEnabled) {
66
+ return;
67
+ }
68
+ store.update(prevState => {
69
+ const errors = (0, _extends2.default)({}, prevState.lazyLoading.dataSource.errors);
70
+ if (error === null && errors[itemId] !== undefined) {
71
+ delete errors[itemId];
72
+ } else {
73
+ errors[itemId] = error;
74
+ }
75
+ errors[itemId] = error;
76
+ return (0, _extends2.default)({}, prevState, {
77
+ lazyLoading: (0, _extends2.default)({}, prevState.lazyLoading, {
78
+ dataSource: (0, _extends2.default)({}, prevState.lazyLoading.dataSource, {
79
+ errors
80
+ })
81
+ })
82
+ });
83
+ });
84
+ };
85
+ const resetDataSourceState = (0, _useEventCallback.default)(() => {
86
+ if (!isLazyLoadingEnabled) {
87
+ return;
88
+ }
89
+ store.update(prevState => (0, _extends2.default)({}, prevState, {
90
+ lazyLoading: (0, _extends2.default)({}, prevState.lazyLoading, {
91
+ dataSource: INITIAL_STATE
92
+ })
93
+ }));
94
+ });
95
+ const fetchItems = (0, _useEventCallback.default)(async parentIds => {
96
+ if (!isLazyLoadingEnabled) {
97
+ return;
98
+ }
99
+ const getChildrenCount = params.dataSource?.getChildrenCount || (() => 0);
100
+ const getTreeItems = params.dataSource?.getTreeItems;
101
+ if (!getTreeItems) {
102
+ return;
103
+ }
104
+ if (parentIds) {
105
+ await nestedDataManager.queue(parentIds);
106
+ return;
107
+ }
108
+ nestedDataManager.clear();
109
+
110
+ // reset the state if we are refetching the first visible items
111
+ if ((0, _internals.selectorDataSourceState)(store.value) !== INITIAL_STATE) {
112
+ resetDataSourceState();
113
+ }
114
+ // handle caching here
115
+ const cachedData = cacheRef.current.get('root');
116
+ if (cachedData !== undefined) {
117
+ return;
118
+ }
119
+
120
+ // handle loading here
121
+ instance.setTreeViewLoading(true);
122
+ try {
123
+ const getTreeItemsResponse = await getTreeItems();
124
+
125
+ // set caching
126
+ cacheRef.current.set('root', getTreeItemsResponse);
127
+
128
+ // update the items in the state
129
+ instance.addItems({
130
+ items: getTreeItemsResponse,
131
+ depth: 0,
132
+ getChildrenCount
133
+ });
134
+ } catch (error) {
135
+ // set the items to empty
136
+ instance.addItems({
137
+ items: [],
138
+ depth: 0,
139
+ getChildrenCount
140
+ });
141
+ // set error state
142
+ instance.setTreeViewError(error);
143
+ } finally {
144
+ // set loading state
145
+ instance.setTreeViewLoading(false);
146
+ }
147
+ });
148
+ const fetchItemChildren = (0, _useEventCallback.default)(async id => {
149
+ if (!isLazyLoadingEnabled) {
150
+ return;
151
+ }
152
+ const getChildrenCount = params.dataSource?.getChildrenCount || (() => 0);
153
+ const getTreeItems = params.dataSource?.getTreeItems;
154
+ if (!getTreeItems) {
155
+ nestedDataManager.clearPendingRequest(id);
156
+ return;
157
+ }
158
+ const parent = (0, _internals.selectorItemMeta)(store.value, id);
159
+ if (!parent) {
160
+ nestedDataManager.clearPendingRequest(id);
161
+ return;
162
+ }
163
+ const depth = parent.depth ? parent.depth + 1 : 1;
164
+
165
+ // handle loading here
166
+ instance.setDataSourceLoading(id, true);
167
+
168
+ // handle caching here
169
+ const cachedData = cacheRef.current.get(id);
170
+ if (cachedData !== undefined && cachedData !== -1) {
171
+ nestedDataManager.setRequestSettled(id);
172
+ instance.addItems({
173
+ items: cachedData,
174
+ depth,
175
+ parentId: id,
176
+ getChildrenCount
177
+ });
178
+ instance.setDataSourceLoading(id, false);
179
+ return;
180
+ }
181
+ if (cachedData === -1) {
182
+ instance.removeChildren(id);
183
+ }
184
+ const existingError = (0, _internals.selectorGetTreeItemError)(store.value, id) ?? null;
185
+ if (existingError) {
186
+ instance.setDataSourceError(id, null);
187
+ }
188
+ try {
189
+ const getTreeItemsResponse = await getTreeItems(id);
190
+ nestedDataManager.setRequestSettled(id);
191
+
192
+ // set caching
193
+ cacheRef.current.set(id, getTreeItemsResponse);
194
+ // update the items in the state
195
+ instance.addItems({
196
+ items: getTreeItemsResponse,
197
+ depth,
198
+ parentId: id,
199
+ getChildrenCount
200
+ });
201
+ } catch (error) {
202
+ const childrenFetchError = error;
203
+ // handle errors here
204
+ instance.setDataSourceError(id, childrenFetchError);
205
+ instance.removeChildren(id);
206
+ } finally {
207
+ // unset loading
208
+ instance.setDataSourceLoading(id, false);
209
+ nestedDataManager.setRequestSettled(id);
210
+ }
211
+ });
212
+ (0, _internals.useInstanceEventHandler)(instance, 'beforeItemToggleExpansion', async eventParameters => {
213
+ if (!isLazyLoadingEnabled || !eventParameters.shouldBeExpanded) {
214
+ return;
215
+ }
216
+ eventParameters.isExpansionPrevented = true;
217
+ await instance.fetchItems([eventParameters.itemId]);
218
+ const fetchErrors = Boolean((0, _internals.selectorGetTreeItemError)(store.value, eventParameters.itemId));
219
+ if (!fetchErrors) {
220
+ instance.applyItemExpansion({
221
+ itemId: eventParameters.itemId,
222
+ shouldBeExpanded: true,
223
+ event: eventParameters.event
224
+ });
225
+ if ((0, _internals.selectorIsItemSelected)(store.value, eventParameters.itemId)) {
226
+ // make sure selection propagation works correctly
227
+ instance.setItemSelection({
228
+ event: eventParameters.event,
229
+ itemId: eventParameters.itemId,
230
+ keepExistingSelection: true,
231
+ shouldBeSelected: true
232
+ });
233
+ }
234
+ }
235
+ });
236
+ React.useEffect(() => {
237
+ if (isLazyLoadingEnabled && firstRenderRef.current) {
238
+ store.update(prevState => (0, _extends2.default)({}, prevState, {
239
+ lazyLoading: (0, _extends2.default)({}, prevState.lazyLoading, {
240
+ enabled: true
241
+ })
242
+ }));
243
+ if (params.items.length) {
244
+ const getChildrenCount = params.dataSource?.getChildrenCount || (() => 0);
245
+ instance.addItems({
246
+ items: params.items,
247
+ depth: 0,
248
+ getChildrenCount
249
+ });
250
+ } else {
251
+ instance.fetchItems();
252
+ }
253
+ firstRenderRef.current = false;
254
+ }
255
+ }, [instance, params.items, params.dataSource, isLazyLoadingEnabled, store]);
256
+ if (isLazyLoadingEnabled) {
257
+ instance.preventItemUpdates();
258
+ }
259
+ return {
260
+ instance: {
261
+ fetchItemChildren,
262
+ fetchItems,
263
+ setDataSourceLoading,
264
+ setDataSourceError
265
+ },
266
+ publicAPI: {}
267
+ };
268
+ };
269
+ exports.useTreeViewLazyLoading = useTreeViewLazyLoading;
270
+ useTreeViewLazyLoading.getDefaultizedParams = ({
271
+ params,
272
+ experimentalFeatures
273
+ }) => {
274
+ const canUseFeature = experimentalFeatures?.lazyLoading;
275
+ if (process.env.NODE_ENV !== 'production') {
276
+ if (params.dataSource && !canUseFeature) {
277
+ (0, _warning.warnOnce)(['MUI X: The label editing feature requires the `lazyLoading` experimental feature to be enabled.', 'You can do it by passing `experimentalFeatures={{ lazyLoading: true}}` to the Rich Tree View Pro component.', 'Check the documentation for more details: https://mui.com/x/react-tree-view/rich-tree-view/lazy-loading/']);
278
+ }
279
+ }
280
+ const defaultDataSource = params?.dataSource ?? {
281
+ getChildrenCount: () => 0,
282
+ getTreeItems: () => Promise.resolve([])
283
+ };
284
+ return (0, _extends2.default)({}, params, {
285
+ dataSource: canUseFeature ? defaultDataSource : {}
286
+ });
287
+ };
288
+ useTreeViewLazyLoading.getInitialState = () => ({
289
+ lazyLoading: {
290
+ enabled: false,
291
+ dataSource: INITIAL_STATE
292
+ }
293
+ });
294
+ useTreeViewLazyLoading.params = {
295
+ dataSource: true,
296
+ dataSourceCache: true
297
+ };
@@ -0,0 +1,32 @@
1
+ import { TreeViewInstance, UseTreeViewLazyLoadingSignature } from '@mui/x-tree-view/internals';
2
+ import { TreeViewItemId } from '@mui/x-tree-view/models';
3
+ export declare enum RequestStatus {
4
+ QUEUED = 0,
5
+ PENDING = 1,
6
+ SETTLED = 2,
7
+ UNKNOWN = 3,
8
+ }
9
+ /**
10
+ * Plugins that the `NestedDataManager` class can use if they are present, but are not required.
11
+ */
12
+ export type NestedDataManagerOptionalPlugins = readonly [];
13
+ /**
14
+ * Fetches row children from the server with option to limit the number of concurrent requests
15
+ * Determines the status of a request based on the enum `RequestStatus`
16
+ * Uses `ParentId` to uniquely identify a request
17
+ */
18
+ export declare class NestedDataManager {
19
+ private pendingRequests;
20
+ private queuedRequests;
21
+ private settledRequests;
22
+ private instance;
23
+ private maxConcurrentRequests;
24
+ constructor(instance: TreeViewInstance<[UseTreeViewLazyLoadingSignature]>, maxConcurrentRequests?: number);
25
+ private processQueue;
26
+ queue: (ids: TreeViewItemId[]) => Promise<void>;
27
+ setRequestSettled: (id: TreeViewItemId) => Promise<void>;
28
+ clear: () => void;
29
+ clearPendingRequest: (id: TreeViewItemId) => Promise<void>;
30
+ getRequestStatus: (id: TreeViewItemId) => RequestStatus;
31
+ getActiveRequestsCount: () => number;
32
+ }
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.RequestStatus = exports.NestedDataManager = void 0;
7
+ const MAX_CONCURRENT_REQUESTS = Infinity;
8
+ let RequestStatus = exports.RequestStatus = /*#__PURE__*/function (RequestStatus) {
9
+ RequestStatus[RequestStatus["QUEUED"] = 0] = "QUEUED";
10
+ RequestStatus[RequestStatus["PENDING"] = 1] = "PENDING";
11
+ RequestStatus[RequestStatus["SETTLED"] = 2] = "SETTLED";
12
+ RequestStatus[RequestStatus["UNKNOWN"] = 3] = "UNKNOWN";
13
+ return RequestStatus;
14
+ }({});
15
+ /**
16
+ * Plugins that need to be present in the Tree View in order for the `NestedDataManager` class to work correctly.
17
+ */
18
+ /**
19
+ * Plugins that the `NestedDataManager` class can use if they are present, but are not required.
20
+ */
21
+ /**
22
+ * Fetches row children from the server with option to limit the number of concurrent requests
23
+ * Determines the status of a request based on the enum `RequestStatus`
24
+ * Uses `ParentId` to uniquely identify a request
25
+ */
26
+ class NestedDataManager {
27
+ constructor(instance, maxConcurrentRequests = MAX_CONCURRENT_REQUESTS) {
28
+ this.pendingRequests = new Set();
29
+ this.queuedRequests = new Set();
30
+ this.settledRequests = new Set();
31
+ this.instance = void 0;
32
+ this.maxConcurrentRequests = void 0;
33
+ this.processQueue = async () => {
34
+ if (this.queuedRequests.size === 0 || this.pendingRequests.size >= this.maxConcurrentRequests) {
35
+ return;
36
+ }
37
+ const loopLength = Math.min(this.maxConcurrentRequests - this.pendingRequests.size, this.queuedRequests.size);
38
+ if (loopLength === 0) {
39
+ return;
40
+ }
41
+ const fetchQueue = Array.from(this.queuedRequests);
42
+ const fetchPromises = [];
43
+ for (let i = 0; i < loopLength; i += 1) {
44
+ const id = fetchQueue[i];
45
+ this.queuedRequests.delete(id);
46
+ this.pendingRequests.add(id);
47
+ fetchPromises.push(this.instance.fetchItemChildren(id));
48
+ }
49
+ await Promise.all(fetchPromises);
50
+ };
51
+ this.queue = async ids => {
52
+ const loadingIds = {};
53
+ ids.forEach(id => {
54
+ this.queuedRequests.add(id);
55
+ loadingIds[id] = true;
56
+ });
57
+ await this.processQueue();
58
+ };
59
+ this.setRequestSettled = async id => {
60
+ this.pendingRequests.delete(id);
61
+ this.settledRequests.add(id);
62
+ await this.processQueue();
63
+ };
64
+ this.clear = () => {
65
+ this.queuedRequests.clear();
66
+ Array.from(this.pendingRequests).forEach(id => this.clearPendingRequest(id));
67
+ };
68
+ this.clearPendingRequest = async id => {
69
+ this.pendingRequests.delete(id);
70
+ await this.processQueue();
71
+ };
72
+ this.getRequestStatus = id => {
73
+ if (this.pendingRequests.has(id)) {
74
+ return RequestStatus.PENDING;
75
+ }
76
+ if (this.queuedRequests.has(id)) {
77
+ return RequestStatus.QUEUED;
78
+ }
79
+ if (this.settledRequests.has(id)) {
80
+ return RequestStatus.SETTLED;
81
+ }
82
+ return RequestStatus.UNKNOWN;
83
+ };
84
+ this.getActiveRequestsCount = () => this.pendingRequests.size + this.queuedRequests.size;
85
+ this.instance = instance;
86
+ this.maxConcurrentRequests = maxConcurrentRequests;
87
+ }
88
+ }
89
+ exports.NestedDataManager = NestedDataManager;
@@ -7,7 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.getReleaseInfo = void 0;
8
8
  var _ponyfillGlobal = _interopRequireDefault(require("@mui/utils/ponyfillGlobal"));
9
9
  const getReleaseInfo = () => {
10
- const releaseInfo = "MTc0MDY5NzIwMDAwMA==";
10
+ const releaseInfo = "MTc0MTMwMjAwMDAwMA==";
11
11
  if (process.env.NODE_ENV !== 'production') {
12
12
  // A simple hack to set the value in the test environment (has no build step).
13
13
  // eslint-disable-next-line no-useless-concat
@@ -106,8 +106,10 @@ process.env.NODE_ENV !== "production" ? RichTreeViewPro.propTypes = {
106
106
  getItemDOMElement: PropTypes.func.isRequired,
107
107
  getItemOrderedChildrenIds: PropTypes.func.isRequired,
108
108
  getItemTree: PropTypes.func.isRequired,
109
- selectItem: PropTypes.func.isRequired,
109
+ getParentId: PropTypes.func.isRequired,
110
+ setIsItemDisabled: PropTypes.func.isRequired,
110
111
  setItemExpansion: PropTypes.func.isRequired,
112
+ setItemSelection: PropTypes.func.isRequired,
111
113
  updateItemLabel: PropTypes.func.isRequired
112
114
  })
113
115
  }),
@@ -130,6 +132,15 @@ process.env.NODE_ENV !== "production" ? RichTreeViewPro.propTypes = {
130
132
  */
131
133
  classes: PropTypes.object,
132
134
  className: PropTypes.string,
135
+ dataSource: PropTypes.shape({
136
+ getChildrenCount: PropTypes.func,
137
+ getTreeItems: PropTypes.func
138
+ }),
139
+ dataSourceCache: PropTypes.shape({
140
+ clear: PropTypes.func.isRequired,
141
+ get: PropTypes.func.isRequired,
142
+ set: PropTypes.func.isRequired
143
+ }),
133
144
  /**
134
145
  * Expanded item ids.
135
146
  * Used when the item's expansion is not controlled.
@@ -167,7 +178,9 @@ process.env.NODE_ENV !== "production" ? RichTreeViewPro.propTypes = {
167
178
  * For each feature, if the flag is not explicitly set to `true`,
168
179
  * the feature will be fully disabled and any property / method call will not have any effect.
169
180
  */
170
- experimentalFeatures: PropTypes.object,
181
+ experimentalFeatures: PropTypes.shape({
182
+ lazyLoading: PropTypes.bool
183
+ }),
171
184
  /**
172
185
  * Used to determine the id of a given item.
173
186
  *
@@ -232,7 +245,7 @@ process.env.NODE_ENV !== "production" ? RichTreeViewPro.propTypes = {
232
245
  multiSelect: PropTypes.bool,
233
246
  /**
234
247
  * Callback fired when Tree Items are expanded/collapsed.
235
- * @param {React.SyntheticEvent} event The DOM event that triggered the change.
248
+ * @param {React.SyntheticEvent} event The DOM event that triggered the change. Can be null when the change is caused by the `publicAPI.setItemExpansion()` method.
236
249
  * @param {array} itemIds The ids of the expanded items.
237
250
  */
238
251
  onExpandedItemsChange: PropTypes.func,
@@ -244,7 +257,7 @@ process.env.NODE_ENV !== "production" ? RichTreeViewPro.propTypes = {
244
257
  onItemClick: PropTypes.func,
245
258
  /**
246
259
  * Callback fired when a Tree Item is expanded or collapsed.
247
- * @param {React.SyntheticEvent} event The DOM event that triggered the change.
260
+ * @param {React.SyntheticEvent | null} event The DOM event that triggered the change. Can be null when the change is caused by the `publicAPI.setItemExpansion()` method.
248
261
  * @param {array} itemId The itemId of the modified item.
249
262
  * @param {array} isExpanded `true` if the item has just been expanded, `false` if it has just been collapsed.
250
263
  */
@@ -271,14 +284,14 @@ process.env.NODE_ENV !== "production" ? RichTreeViewPro.propTypes = {
271
284
  onItemPositionChange: PropTypes.func,
272
285
  /**
273
286
  * Callback fired when a Tree Item is selected or deselected.
274
- * @param {React.SyntheticEvent} event The DOM event that triggered the change.
287
+ * @param {React.SyntheticEvent} event The DOM event that triggered the change. Can be null when the change is caused by the `publicAPI.setItemSelection()` method.
275
288
  * @param {array} itemId The itemId of the modified item.
276
289
  * @param {array} isSelected `true` if the item has just been selected, `false` if it has just been deselected.
277
290
  */
278
291
  onItemSelectionToggle: PropTypes.func,
279
292
  /**
280
293
  * Callback fired when Tree Items are selected/deselected.
281
- * @param {React.SyntheticEvent} event The DOM event that triggered the change.
294
+ * @param {React.SyntheticEvent} event The DOM event that triggered the change. Can be null when the change is caused by the `publicAPI.setItemSelection()` method.
282
295
  * @param {string[] | string} itemIds The ids of the selected items.
283
296
  * When `multiSelect` is `true`, this is an array of strings; when false (default) a string.
284
297
  */