@infinite-table/infinite-react 0.2.0 → 0.2.1
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/index.d.ts +110 -101
- package/index.esm.js +190 -59
- package/index.js +171 -40
- package/package.json +2 -2
package/index.d.ts
CHANGED
|
@@ -199,6 +199,103 @@ declare module "components/types/SubscriptionCallback" {
|
|
|
199
199
|
onChange: (fn: SubscriptionCallbackOnChangeFn<T>) => VoidFn;
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
|
+
declare module "components/types/Size" {
|
|
203
|
+
export interface Size {
|
|
204
|
+
width: number;
|
|
205
|
+
height: number;
|
|
206
|
+
}
|
|
207
|
+
export type OnResizeFn = (size: {
|
|
208
|
+
width: number;
|
|
209
|
+
height: number;
|
|
210
|
+
}) => void;
|
|
211
|
+
}
|
|
212
|
+
declare module "components/VirtualBrain/index" {
|
|
213
|
+
import { Logger } from "utils/debug";
|
|
214
|
+
import { Size } from "components/types/Size";
|
|
215
|
+
import type { OnScrollFn, ScrollPosition } from "components/types/ScrollPosition";
|
|
216
|
+
type MainAxisOptions = 'vertical' | 'horizontal';
|
|
217
|
+
export type VirtualBrainOptions = {
|
|
218
|
+
mainAxis: MainAxisOptions;
|
|
219
|
+
itemSize: MainAxisSize;
|
|
220
|
+
itemSpan?: ({ itemIndex }: {
|
|
221
|
+
itemIndex: number;
|
|
222
|
+
}) => number;
|
|
223
|
+
count: number;
|
|
224
|
+
name?: string;
|
|
225
|
+
};
|
|
226
|
+
export type MainAxisSize = number | ((itemIndex: number) => number);
|
|
227
|
+
type OnRenderCountChangeFn = (renderCount: number) => void;
|
|
228
|
+
type OnSizeChangeFn = (size: number) => void;
|
|
229
|
+
type OnDestroyFn = () => void;
|
|
230
|
+
export type GetItemPositionFn = (itemIndex: number) => number;
|
|
231
|
+
export type RenderRange = {
|
|
232
|
+
renderStartIndex: number;
|
|
233
|
+
renderEndIndex: number;
|
|
234
|
+
};
|
|
235
|
+
export type OnRenderRangeChangeFn = (renderRange: RenderRange) => void;
|
|
236
|
+
export class VirtualBrain extends Logger {
|
|
237
|
+
private scrollPosition;
|
|
238
|
+
private scrollPositionOnMainAxis;
|
|
239
|
+
private itemSpanParent;
|
|
240
|
+
private itemSpanValue;
|
|
241
|
+
private itemSizeCache;
|
|
242
|
+
private itemOffsetCache;
|
|
243
|
+
private options;
|
|
244
|
+
private destroyed;
|
|
245
|
+
private totalSize;
|
|
246
|
+
private onScrollFns;
|
|
247
|
+
private onTotalSizeChangeFns;
|
|
248
|
+
private onRenderCountChangeFns;
|
|
249
|
+
private onRenderRangeChangeFns;
|
|
250
|
+
private onDestroyFns;
|
|
251
|
+
name: string | undefined;
|
|
252
|
+
private renderCount;
|
|
253
|
+
private renderRange;
|
|
254
|
+
private availableSize;
|
|
255
|
+
constructor(options: VirtualBrainOptions);
|
|
256
|
+
setAvailableSize: (size: Size) => void;
|
|
257
|
+
getOptions(): VirtualBrainOptions;
|
|
258
|
+
private updateRenderCount;
|
|
259
|
+
private computeRenderCount;
|
|
260
|
+
private setRenderCount;
|
|
261
|
+
private updateRenderRange;
|
|
262
|
+
getRenderStartIndex(): number;
|
|
263
|
+
getRenderCount: () => number;
|
|
264
|
+
setScrollPosition: (scrollPosition: ScrollPosition) => void;
|
|
265
|
+
private notifyScrollChange;
|
|
266
|
+
private notifyDestroy;
|
|
267
|
+
private notifyTotalSizeChange;
|
|
268
|
+
private notifyRenderCountChange;
|
|
269
|
+
private notifyRenderRangeChange;
|
|
270
|
+
getRenderRange: () => RenderRange;
|
|
271
|
+
private setRenderRange;
|
|
272
|
+
private computeRenderRange;
|
|
273
|
+
getScrollPosition: () => ScrollPosition;
|
|
274
|
+
onScroll: (fn: OnScrollFn) => () => void;
|
|
275
|
+
onTotalSizeChange: (fn: OnSizeChangeFn) => () => void;
|
|
276
|
+
onRenderCountChange: (fn: OnRenderCountChangeFn) => () => void;
|
|
277
|
+
onRenderRangeChange: (fn: OnRenderRangeChangeFn) => () => void;
|
|
278
|
+
onDestroy: (fn: OnDestroyFn) => () => void;
|
|
279
|
+
update: (newCount: VirtualBrainOptions['count'], newItemSize: VirtualBrainOptions['itemSize'], newItemSpan?: VirtualBrainOptions['itemSpan']) => void;
|
|
280
|
+
private reset;
|
|
281
|
+
private computeItemSpanUpTo;
|
|
282
|
+
private computeCacheFor;
|
|
283
|
+
private getItemSizeCacheFor;
|
|
284
|
+
getItemSpan: (itemIndex: number) => number;
|
|
285
|
+
getItemSpanParent: (itemIndex: number) => number;
|
|
286
|
+
getItemSizeWithSpan: (itemIndex: number, itemSpan: number) => number;
|
|
287
|
+
/**
|
|
288
|
+
* For now, this doesn't take into account the itemspan, and it's okay not to
|
|
289
|
+
* @param itemIndex
|
|
290
|
+
* @returns the size of the specified item
|
|
291
|
+
*/
|
|
292
|
+
getItemSize: (itemIndex: number) => number;
|
|
293
|
+
getTotalSize: () => number;
|
|
294
|
+
getItemAt: (scrollPos: number) => number;
|
|
295
|
+
getItemOffsetFor: (itemIndex: number) => number;
|
|
296
|
+
destroy: () => void;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
202
299
|
declare module "components/DataSource/types" {
|
|
203
300
|
import * as React from 'react';
|
|
204
301
|
import { MultisortInfo } from "utils/multisort/index";
|
|
@@ -211,6 +308,7 @@ declare module "components/DataSource/types" {
|
|
|
211
308
|
import { NonUndefined } from "components/types/NonUndefined";
|
|
212
309
|
import { SubscriptionCallback } from "components/types/SubscriptionCallback";
|
|
213
310
|
import { ScrollStopInfo } from "components/InfiniteTable/types/InfiniteTableProps";
|
|
311
|
+
import { RenderRange } from "components/VirtualBrain/index";
|
|
214
312
|
export interface DataSourceDataParams<T> {
|
|
215
313
|
originalDataArray: T[];
|
|
216
314
|
sortInfo?: DataSourceSortInfo<T>;
|
|
@@ -290,8 +388,11 @@ declare module "components/DataSource/types" {
|
|
|
290
388
|
showSeparatePivotColumnForSingleAggregation: boolean;
|
|
291
389
|
dataParams?: DataSourceDataParams<T>;
|
|
292
390
|
originalLazyGroupData: LazyGroupDataDeepMap<T>;
|
|
391
|
+
originalLazyGroupDataChangeDetect: number | string;
|
|
392
|
+
scrollStopDelayUpdatedByTable: number;
|
|
293
393
|
notifyScrollbarsChange: SubscriptionCallback<Scrollbars>;
|
|
294
394
|
notifyScrollStop: SubscriptionCallback<ScrollStopInfo>;
|
|
395
|
+
notifyRenderRangeChange: SubscriptionCallback<RenderRange>;
|
|
295
396
|
originalDataArray: T[];
|
|
296
397
|
lastSortDataArray?: T[];
|
|
297
398
|
lastGroupDataArray?: InfiniteTableRowInfo<T>[];
|
|
@@ -383,16 +484,24 @@ declare module "components/DataSource/publicHooks/useDataSource" {
|
|
|
383
484
|
export function useDataSource<T>(): DataSourceState<T>;
|
|
384
485
|
export function useDataSourceContextValue<T>(): DataSourceContextValue<T>;
|
|
385
486
|
}
|
|
487
|
+
declare module "utils/getGlobal" {
|
|
488
|
+
export function getGlobal<T extends Window>(): T;
|
|
489
|
+
}
|
|
386
490
|
declare module "components/hooks/useEffectWithChanges" {
|
|
387
491
|
import { EffectCallback } from 'react';
|
|
388
492
|
export function useEffectWithChanges(fn: (changes: Record<string, any>, prevValues: Record<string, any>) => void | (() => void), deps: Record<string, any>): void;
|
|
389
493
|
export function useEffectWithObject(fn: EffectCallback, deps: Record<string, any>): void;
|
|
390
494
|
}
|
|
495
|
+
declare module "components/utils/debounce" {
|
|
496
|
+
export function debounce(fn: Function, { wait }: {
|
|
497
|
+
wait: number;
|
|
498
|
+
}): (...args: any[]) => void;
|
|
499
|
+
}
|
|
391
500
|
declare module "components/DataSource/privateHooks/useLoadData" {
|
|
392
501
|
import { ComponentStateGeneratedActions } from "components/hooks/useComponentState";
|
|
393
502
|
import { DataSourceDataParams, DataSourceData, DataSourceState } from "components/DataSource/types";
|
|
394
503
|
export function buildDataSourceDataParams<T>(componentState: DataSourceState<T>, overrides?: Partial<DataSourceDataParams<T>>): DataSourceDataParams<T>;
|
|
395
|
-
export function loadData<T>(data: DataSourceData<T>, componentState: DataSourceState<T>, actions: ComponentStateGeneratedActions<DataSourceState<T>>, overrides?: Partial<DataSourceDataParams<T>>): void
|
|
504
|
+
export function loadData<T>(data: DataSourceData<T>, componentState: DataSourceState<T>, actions: ComponentStateGeneratedActions<DataSourceState<T>>, overrides?: Partial<DataSourceDataParams<T>>): Promise<void>;
|
|
396
505
|
export function useLoadData<T>(): void;
|
|
397
506
|
}
|
|
398
507
|
declare module "components/DataSource/state/normalizeSortInfo" {
|
|
@@ -1179,16 +1288,6 @@ declare module "components/InfiniteTable/types/InfiniteTableProps" {
|
|
|
1179
1288
|
horizontal: boolean;
|
|
1180
1289
|
};
|
|
1181
1290
|
}
|
|
1182
|
-
declare module "components/types/Size" {
|
|
1183
|
-
export interface Size {
|
|
1184
|
-
width: number;
|
|
1185
|
-
height: number;
|
|
1186
|
-
}
|
|
1187
|
-
export type OnResizeFn = (size: {
|
|
1188
|
-
width: number;
|
|
1189
|
-
height: number;
|
|
1190
|
-
}) => void;
|
|
1191
|
-
}
|
|
1192
1291
|
declare module "components/VirtualBrain/ScrollListener" {
|
|
1193
1292
|
import { OnScrollFn, ScrollPosition } from "components/types/ScrollPosition";
|
|
1194
1293
|
export class ScrollListener {
|
|
@@ -1535,9 +1634,6 @@ declare module "components/InfiniteTable/utils/adjustColumnOrderForPinning" {
|
|
|
1535
1634
|
import { InfiniteTablePropColumnOrderNormalized, InfiniteTablePropColumnPinningMap } from "components/InfiniteTable/types/InfiniteTableProps";
|
|
1536
1635
|
export const adjustColumnOrderForPinning: (columnOrder: InfiniteTablePropColumnOrderNormalized, columnPinning: InfiniteTablePropColumnPinningMap) => InfiniteTablePropColumnOrderNormalized;
|
|
1537
1636
|
}
|
|
1538
|
-
declare module "utils/getGlobal" {
|
|
1539
|
-
export function getGlobal<T extends Window>(): T;
|
|
1540
|
-
}
|
|
1541
1637
|
declare module "components/utils/getScrollbarWidth" {
|
|
1542
1638
|
export function getScrollbarWidth(): number;
|
|
1543
1639
|
}
|
|
@@ -1797,93 +1893,6 @@ declare module "components/InfiniteTable/components/InfiniteTableBody/InfiniteTa
|
|
|
1797
1893
|
declare module "components/InfiniteTable/components/InfiniteTableBody/index" {
|
|
1798
1894
|
export * from "components/InfiniteTable/components/InfiniteTableBody/InfiniteTableBody";
|
|
1799
1895
|
}
|
|
1800
|
-
declare module "components/VirtualBrain/index" {
|
|
1801
|
-
import { Logger } from "utils/debug";
|
|
1802
|
-
import { Size } from "components/types/Size";
|
|
1803
|
-
import type { OnScrollFn, ScrollPosition } from "components/types/ScrollPosition";
|
|
1804
|
-
type MainAxisOptions = 'vertical' | 'horizontal';
|
|
1805
|
-
export type VirtualBrainOptions = {
|
|
1806
|
-
mainAxis: MainAxisOptions;
|
|
1807
|
-
itemSize: MainAxisSize;
|
|
1808
|
-
itemSpan?: ({ itemIndex }: {
|
|
1809
|
-
itemIndex: number;
|
|
1810
|
-
}) => number;
|
|
1811
|
-
count: number;
|
|
1812
|
-
name?: string;
|
|
1813
|
-
};
|
|
1814
|
-
export type MainAxisSize = number | ((itemIndex: number) => number);
|
|
1815
|
-
type OnRenderCountChangeFn = (renderCount: number) => void;
|
|
1816
|
-
type OnSizeChangeFn = (size: number) => void;
|
|
1817
|
-
type OnDestroyFn = () => void;
|
|
1818
|
-
export type GetItemPositionFn = (itemIndex: number) => number;
|
|
1819
|
-
export type RenderRange = {
|
|
1820
|
-
renderStartIndex: number;
|
|
1821
|
-
renderEndIndex: number;
|
|
1822
|
-
};
|
|
1823
|
-
export type OnRenderRangeChangeFn = (renderRange: RenderRange) => void;
|
|
1824
|
-
export class VirtualBrain extends Logger {
|
|
1825
|
-
private scrollPosition;
|
|
1826
|
-
private scrollPositionOnMainAxis;
|
|
1827
|
-
private itemSpanParent;
|
|
1828
|
-
private itemSpanValue;
|
|
1829
|
-
private itemSizeCache;
|
|
1830
|
-
private itemOffsetCache;
|
|
1831
|
-
private options;
|
|
1832
|
-
private destroyed;
|
|
1833
|
-
private totalSize;
|
|
1834
|
-
private onScrollFns;
|
|
1835
|
-
private onTotalSizeChangeFns;
|
|
1836
|
-
private onRenderCountChangeFns;
|
|
1837
|
-
private onRenderRangeChangeFns;
|
|
1838
|
-
private onDestroyFns;
|
|
1839
|
-
name: string | undefined;
|
|
1840
|
-
private renderCount;
|
|
1841
|
-
private renderRange;
|
|
1842
|
-
private availableSize;
|
|
1843
|
-
constructor(options: VirtualBrainOptions);
|
|
1844
|
-
setAvailableSize: (size: Size) => void;
|
|
1845
|
-
getOptions(): VirtualBrainOptions;
|
|
1846
|
-
private updateRenderCount;
|
|
1847
|
-
private computeRenderCount;
|
|
1848
|
-
private setRenderCount;
|
|
1849
|
-
private updateRenderRange;
|
|
1850
|
-
getRenderStartIndex(): number;
|
|
1851
|
-
getRenderCount: () => number;
|
|
1852
|
-
setScrollPosition: (scrollPosition: ScrollPosition) => void;
|
|
1853
|
-
private notifyScrollChange;
|
|
1854
|
-
private notifyDestroy;
|
|
1855
|
-
private notifyTotalSizeChange;
|
|
1856
|
-
private notifyRenderCountChange;
|
|
1857
|
-
private notifyRenderRangeChange;
|
|
1858
|
-
getRenderRange: () => RenderRange;
|
|
1859
|
-
private setRenderRange;
|
|
1860
|
-
private computeRenderRange;
|
|
1861
|
-
getScrollPosition: () => ScrollPosition;
|
|
1862
|
-
onScroll: (fn: OnScrollFn) => () => void;
|
|
1863
|
-
onTotalSizeChange: (fn: OnSizeChangeFn) => () => void;
|
|
1864
|
-
onRenderCountChange: (fn: OnRenderCountChangeFn) => () => void;
|
|
1865
|
-
onRenderRangeChange: (fn: OnRenderRangeChangeFn) => () => void;
|
|
1866
|
-
onDestroy: (fn: OnDestroyFn) => () => void;
|
|
1867
|
-
update: (newCount: VirtualBrainOptions['count'], newItemSize: VirtualBrainOptions['itemSize'], newItemSpan?: VirtualBrainOptions['itemSpan']) => void;
|
|
1868
|
-
private reset;
|
|
1869
|
-
private computeItemSpanUpTo;
|
|
1870
|
-
private computeCacheFor;
|
|
1871
|
-
private getItemSizeCacheFor;
|
|
1872
|
-
getItemSpan: (itemIndex: number) => number;
|
|
1873
|
-
getItemSpanParent: (itemIndex: number) => number;
|
|
1874
|
-
getItemSizeWithSpan: (itemIndex: number, itemSpan: number) => number;
|
|
1875
|
-
/**
|
|
1876
|
-
* For now, this doesn't take into account the itemspan, and it's okay not to
|
|
1877
|
-
* @param itemIndex
|
|
1878
|
-
* @returns the size of the specified item
|
|
1879
|
-
*/
|
|
1880
|
-
getItemSize: (itemIndex: number) => number;
|
|
1881
|
-
getTotalSize: () => number;
|
|
1882
|
-
getItemAt: (scrollPos: number) => number;
|
|
1883
|
-
getItemOffsetFor: (itemIndex: number) => number;
|
|
1884
|
-
destroy: () => void;
|
|
1885
|
-
}
|
|
1886
|
-
}
|
|
1887
1896
|
declare module "components/InfiniteTable/components/ScrollbarPlaceholder" {
|
|
1888
1897
|
import * as React from 'react';
|
|
1889
1898
|
function HorizontalScrollbarPlaceholderFn(props: {
|
package/index.esm.js
CHANGED
|
@@ -2048,7 +2048,7 @@ function useColumnGroups() {
|
|
|
2048
2048
|
}
|
|
2049
2049
|
|
|
2050
2050
|
// src/components/InfiniteTable/hooks/useColumnsWhen.ts
|
|
2051
|
-
import { useEffect as useEffect9, useMemo as
|
|
2051
|
+
import { useEffect as useEffect9, useMemo as useMemo5 } from "react";
|
|
2052
2052
|
|
|
2053
2053
|
// src/components/InfiniteTable/state/getComputedPivotColumnsFromDataSourcePivotColumns.tsx
|
|
2054
2054
|
import {
|
|
@@ -2393,7 +2393,7 @@ var getMultisortFunction = (sortInfo, get) => {
|
|
|
2393
2393
|
};
|
|
2394
2394
|
|
|
2395
2395
|
// src/components/DataSource/privateHooks/useLoadData.ts
|
|
2396
|
-
import { useEffect as useEffect8, useRef as useRef6, useState as useState4 } from "react";
|
|
2396
|
+
import { useEffect as useEffect8, useMemo as useMemo4, useRef as useRef6, useState as useState4 } from "react";
|
|
2397
2397
|
|
|
2398
2398
|
// src/utils/DeepMap/once.ts
|
|
2399
2399
|
function once(fn) {
|
|
@@ -3029,11 +3029,33 @@ function useEffectWithChanges(fn, deps) {
|
|
|
3029
3029
|
}, useEffectDeps);
|
|
3030
3030
|
}
|
|
3031
3031
|
|
|
3032
|
+
// src/components/utils/debounce.ts
|
|
3033
|
+
function debounce(fn, { wait }) {
|
|
3034
|
+
let timeout = null;
|
|
3035
|
+
return function(...args) {
|
|
3036
|
+
const context = this;
|
|
3037
|
+
if (timeout !== null) {
|
|
3038
|
+
clearTimeout(timeout);
|
|
3039
|
+
}
|
|
3040
|
+
timeout = setTimeout(() => {
|
|
3041
|
+
fn.apply(context, args);
|
|
3042
|
+
}, wait);
|
|
3043
|
+
};
|
|
3044
|
+
}
|
|
3045
|
+
|
|
3032
3046
|
// src/components/DataSource/privateHooks/useLoadData.ts
|
|
3047
|
+
var getRafPromise = () => new Promise((resolve) => {
|
|
3048
|
+
requestAnimationFrame(resolve);
|
|
3049
|
+
});
|
|
3033
3050
|
var SKIP_DATA_CHANGES_KEYS = {
|
|
3034
3051
|
originalDataArray: true,
|
|
3035
3052
|
changes: true
|
|
3036
3053
|
};
|
|
3054
|
+
function getChangeDetect() {
|
|
3055
|
+
var _a;
|
|
3056
|
+
const perfNow = (_a = getGlobal().performance) == null ? void 0 : _a.now();
|
|
3057
|
+
return `${Date.now()}:${perfNow}`;
|
|
3058
|
+
}
|
|
3037
3059
|
function buildDataSourceDataParams(componentState, overrides) {
|
|
3038
3060
|
var _a, _b;
|
|
3039
3061
|
const sortInfo = componentState.multiSort ? componentState.sortInfo : (_b = (_a = componentState.sortInfo) == null ? void 0 : _a[0]) != null ? _b : null;
|
|
@@ -3077,10 +3099,10 @@ function loadData(data, componentState, actions, overrides) {
|
|
|
3077
3099
|
data = data(dataParams);
|
|
3078
3100
|
}
|
|
3079
3101
|
const dataIsPromise = typeof data === "object" && typeof data.then === "function";
|
|
3080
|
-
if (dataIsPromise) {
|
|
3102
|
+
if (dataIsPromise && !componentState.fullLazyLoad) {
|
|
3081
3103
|
actions.loading = true;
|
|
3082
3104
|
}
|
|
3083
|
-
Promise.resolve(data).then((dataParam) => {
|
|
3105
|
+
return Promise.resolve(data).then((dataParam) => {
|
|
3084
3106
|
var _a, _b, _c;
|
|
3085
3107
|
let dataArray = [];
|
|
3086
3108
|
let skipAssign = false;
|
|
@@ -3094,7 +3116,7 @@ function loadData(data, componentState, actions, overrides) {
|
|
|
3094
3116
|
actions.pivotMappings = remoteData.mappings;
|
|
3095
3117
|
}
|
|
3096
3118
|
if (componentState.fullLazyLoad && dataParams.groupKeys) {
|
|
3097
|
-
const lazyGroupData =
|
|
3119
|
+
const lazyGroupData = componentState.originalLazyGroupData;
|
|
3098
3120
|
const key = [LAZY_ROOT_KEY_FOR_GROUPS, ...dataParams.groupKeys];
|
|
3099
3121
|
const newGroupRowInfo = {
|
|
3100
3122
|
totalCount: (_a = remoteData.totalCount) != null ? _a : dataArray.length,
|
|
@@ -3108,7 +3130,7 @@ function loadData(data, componentState, actions, overrides) {
|
|
|
3108
3130
|
};
|
|
3109
3131
|
currentGroupRowInfo.items.length = currentGroupRowInfo.totalCount;
|
|
3110
3132
|
const start = (_b = dataParams.lazyLoadStartIndex) != null ? _b : 0;
|
|
3111
|
-
const end =
|
|
3133
|
+
const end = Math.min((_c = remoteData.totalCount) != null ? _c : start + dataParams.lazyLoadBatchSize);
|
|
3112
3134
|
for (let i = start; i < end; i++) {
|
|
3113
3135
|
currentGroupRowInfo.items[i] = newGroupRowInfo.items[i - start];
|
|
3114
3136
|
}
|
|
@@ -3119,7 +3141,7 @@ function loadData(data, componentState, actions, overrides) {
|
|
|
3119
3141
|
lazyGroupData.set(key, newGroupRowInfo);
|
|
3120
3142
|
}
|
|
3121
3143
|
skipAssign = true;
|
|
3122
|
-
actions.
|
|
3144
|
+
actions.originalLazyGroupDataChangeDetect = getChangeDetect();
|
|
3123
3145
|
}
|
|
3124
3146
|
} else {
|
|
3125
3147
|
dataArray = dataParam;
|
|
@@ -3127,7 +3149,7 @@ function loadData(data, componentState, actions, overrides) {
|
|
|
3127
3149
|
if (!skipAssign) {
|
|
3128
3150
|
actions.originalDataArray = dataArray;
|
|
3129
3151
|
}
|
|
3130
|
-
if (dataIsPromise) {
|
|
3152
|
+
if (dataIsPromise && !componentState.fullLazyLoad) {
|
|
3131
3153
|
actions.loading = false;
|
|
3132
3154
|
}
|
|
3133
3155
|
});
|
|
@@ -3146,9 +3168,7 @@ function useLoadData() {
|
|
|
3146
3168
|
pivotBy,
|
|
3147
3169
|
livePagination,
|
|
3148
3170
|
livePaginationCursor,
|
|
3149
|
-
cursorId: stateCursorId
|
|
3150
|
-
lazyLoadBatchSize,
|
|
3151
|
-
notifyScrollStop
|
|
3171
|
+
cursorId: stateCursorId
|
|
3152
3172
|
} = componentState;
|
|
3153
3173
|
const [scrollbars, setScrollbars] = useState4({
|
|
3154
3174
|
vertical: false,
|
|
@@ -3189,33 +3209,7 @@ function useLoadData() {
|
|
|
3189
3209
|
cursorId: livePagination ? stateCursorId : null
|
|
3190
3210
|
};
|
|
3191
3211
|
const initialRef = useRef6(true);
|
|
3192
|
-
|
|
3193
|
-
if (lazyLoadBatchSize && lazyLoadBatchSize > 0) {
|
|
3194
|
-
return notifyScrollStop.onChange((param) => {
|
|
3195
|
-
console.log("scroll stop", param);
|
|
3196
|
-
if (!param) {
|
|
3197
|
-
return;
|
|
3198
|
-
}
|
|
3199
|
-
const componentState2 = getComponentState();
|
|
3200
|
-
const {
|
|
3201
|
-
firstVisibleRowIndex: startIndex,
|
|
3202
|
-
lastVisibleRowIndex: endIndex
|
|
3203
|
-
} = param;
|
|
3204
|
-
const firstBatchStart = Math.floor(startIndex / lazyLoadBatchSize) * lazyLoadBatchSize;
|
|
3205
|
-
const lastBatchStart = Math.floor(endIndex / lazyLoadBatchSize) * lazyLoadBatchSize;
|
|
3206
|
-
const isRowLoaded = (index) => componentState2.dataArray[index].data != null;
|
|
3207
|
-
for (let batchStartIndex = firstBatchStart; batchStartIndex <= lastBatchStart; batchStartIndex = batchStartIndex + lazyLoadBatchSize) {
|
|
3208
|
-
if (!isRowLoaded(batchStartIndex)) {
|
|
3209
|
-
loadData(componentState2.data, componentState2, actions, {
|
|
3210
|
-
lazyLoadBatchSize,
|
|
3211
|
-
lazyLoadStartIndex: batchStartIndex
|
|
3212
|
-
});
|
|
3213
|
-
}
|
|
3214
|
-
}
|
|
3215
|
-
});
|
|
3216
|
-
}
|
|
3217
|
-
return;
|
|
3218
|
-
}, [lazyLoadBatchSize]);
|
|
3212
|
+
useLazyLoadRange();
|
|
3219
3213
|
useEffectWithChanges(() => {
|
|
3220
3214
|
const componentState2 = getComponentState();
|
|
3221
3215
|
if (typeof componentState2.data !== "function") {
|
|
@@ -3236,6 +3230,126 @@ function useLoadData() {
|
|
|
3236
3230
|
}
|
|
3237
3231
|
}, depsObject);
|
|
3238
3232
|
}
|
|
3233
|
+
function useLazyLoadRange() {
|
|
3234
|
+
const {
|
|
3235
|
+
getComponentState,
|
|
3236
|
+
componentActions: actions,
|
|
3237
|
+
componentState
|
|
3238
|
+
} = useComponentState();
|
|
3239
|
+
const loadingCache = useMemo4(() => {
|
|
3240
|
+
return new Map();
|
|
3241
|
+
}, [componentState.data]);
|
|
3242
|
+
globalThis.loadingCache = loadingCache;
|
|
3243
|
+
const {
|
|
3244
|
+
lazyLoadBatchSize,
|
|
3245
|
+
notifyRenderRangeChange,
|
|
3246
|
+
dataArray,
|
|
3247
|
+
scrollStopDelayUpdatedByTable
|
|
3248
|
+
} = componentState;
|
|
3249
|
+
const latestRenderRangeRef = useRef6(null);
|
|
3250
|
+
const loadRange = (param, cache = loadingCache) => {
|
|
3251
|
+
const componentState2 = getComponentState();
|
|
3252
|
+
param = param || latestRenderRangeRef.current;
|
|
3253
|
+
if (!param) {
|
|
3254
|
+
return;
|
|
3255
|
+
}
|
|
3256
|
+
const { renderStartIndex: startIndex, renderEndIndex: endIndex } = param;
|
|
3257
|
+
if (!lazyLoadBatchSize || lazyLoadBatchSize <= 0) {
|
|
3258
|
+
return;
|
|
3259
|
+
}
|
|
3260
|
+
lazyLoadRange({
|
|
3261
|
+
startIndex,
|
|
3262
|
+
endIndex,
|
|
3263
|
+
lazyLoadBatchSize,
|
|
3264
|
+
componentState: componentState2,
|
|
3265
|
+
componentActions: actions
|
|
3266
|
+
}, cache);
|
|
3267
|
+
};
|
|
3268
|
+
const debouncedLoadRange = useMemo4(() => debounce(loadRange, { wait: scrollStopDelayUpdatedByTable }), [scrollStopDelayUpdatedByTable]);
|
|
3269
|
+
useEffect8(() => {
|
|
3270
|
+
if (lazyLoadBatchSize && lazyLoadBatchSize > 0) {
|
|
3271
|
+
return notifyRenderRangeChange.onChange((param) => {
|
|
3272
|
+
latestRenderRangeRef.current = param;
|
|
3273
|
+
loadRange(param, loadingCache);
|
|
3274
|
+
});
|
|
3275
|
+
}
|
|
3276
|
+
return;
|
|
3277
|
+
}, [lazyLoadBatchSize, loadingCache]);
|
|
3278
|
+
useEffect8(() => {
|
|
3279
|
+
if (lazyLoadBatchSize && lazyLoadBatchSize > 0) {
|
|
3280
|
+
debouncedLoadRange();
|
|
3281
|
+
}
|
|
3282
|
+
return;
|
|
3283
|
+
}, [dataArray]);
|
|
3284
|
+
}
|
|
3285
|
+
function lazyLoadRange(options, cache) {
|
|
3286
|
+
const {
|
|
3287
|
+
startIndex,
|
|
3288
|
+
endIndex,
|
|
3289
|
+
lazyLoadBatchSize,
|
|
3290
|
+
componentState,
|
|
3291
|
+
componentActions
|
|
3292
|
+
} = options;
|
|
3293
|
+
const { dataArray } = componentState;
|
|
3294
|
+
const isRowLoaded = (index) => dataArray[index].data != null;
|
|
3295
|
+
const perGroupFnCalls = new DeepMap();
|
|
3296
|
+
const rootGroupKeys = ["_______xxx______"];
|
|
3297
|
+
for (let i = startIndex; i <= endIndex; i++) {
|
|
3298
|
+
const rowInfo = dataArray[i];
|
|
3299
|
+
if (!rowInfo) {
|
|
3300
|
+
continue;
|
|
3301
|
+
}
|
|
3302
|
+
const rowLoaded = rowInfo.data != null;
|
|
3303
|
+
const parentGroupKeys = rowInfo.groupKeys ? [...rowInfo.groupKeys] : [];
|
|
3304
|
+
if (rowInfo.groupKeys) {
|
|
3305
|
+
parentGroupKeys.pop();
|
|
3306
|
+
}
|
|
3307
|
+
const cacheKeys = parentGroupKeys.length ? parentGroupKeys : rootGroupKeys;
|
|
3308
|
+
const indexInGroup = rowInfo.indexInGroup;
|
|
3309
|
+
if (!rowLoaded) {
|
|
3310
|
+
let fnCalls = perGroupFnCalls.get(cacheKeys);
|
|
3311
|
+
const batchStartIndexInGroup = Math.floor(indexInGroup / lazyLoadBatchSize) * lazyLoadBatchSize;
|
|
3312
|
+
const offset = rowInfo.indexInGroup - batchStartIndexInGroup;
|
|
3313
|
+
const absoluteIndexOfBatchStart = dataArray[rowInfo.indexInAll - offset].indexInAll;
|
|
3314
|
+
const batchStartRowLoaded = isRowLoaded(absoluteIndexOfBatchStart);
|
|
3315
|
+
const batchStartRowId = dataArray[absoluteIndexOfBatchStart].id;
|
|
3316
|
+
if (batchStartRowLoaded || (fnCalls == null ? void 0 : fnCalls[batchStartRowId])) {
|
|
3317
|
+
continue;
|
|
3318
|
+
}
|
|
3319
|
+
const shouldSetFnCalls = !fnCalls;
|
|
3320
|
+
fnCalls = fnCalls || {};
|
|
3321
|
+
const currentFnCall = {
|
|
3322
|
+
lazyLoadStartIndex: batchStartIndexInGroup,
|
|
3323
|
+
lazyLoadBatchSize,
|
|
3324
|
+
groupKeys: parentGroupKeys
|
|
3325
|
+
};
|
|
3326
|
+
if (!fnCalls[batchStartRowId]) {
|
|
3327
|
+
fnCalls[batchStartRowId] = currentFnCall;
|
|
3328
|
+
}
|
|
3329
|
+
if (shouldSetFnCalls) {
|
|
3330
|
+
perGroupFnCalls.set(cacheKeys, fnCalls);
|
|
3331
|
+
}
|
|
3332
|
+
}
|
|
3333
|
+
}
|
|
3334
|
+
let initialPromise = Promise.resolve(true);
|
|
3335
|
+
const allFnCalls = [];
|
|
3336
|
+
perGroupFnCalls.topDownValues().forEach((record) => {
|
|
3337
|
+
allFnCalls.push(...Object.values(record));
|
|
3338
|
+
});
|
|
3339
|
+
allFnCalls.reduce((promise, fnCall) => {
|
|
3340
|
+
const cacheKey = `${fnCall.groupKeys.join("-")}:${fnCall.lazyLoadStartIndex}`;
|
|
3341
|
+
if (cache && cache.has(cacheKey)) {
|
|
3342
|
+
return promise;
|
|
3343
|
+
}
|
|
3344
|
+
cache == null ? void 0 : cache.set(cacheKey, true);
|
|
3345
|
+
const args = [componentState.data, componentState, componentActions, fnCall];
|
|
3346
|
+
return promise.then(() => getRafPromise()).then(() => loadData(...args)).then(() => {
|
|
3347
|
+
requestAnimationFrame(() => {
|
|
3348
|
+
cache == null ? void 0 : cache.delete(cacheKey);
|
|
3349
|
+
});
|
|
3350
|
+
});
|
|
3351
|
+
}, initialPromise);
|
|
3352
|
+
}
|
|
3239
3353
|
|
|
3240
3354
|
// src/components/DataSource/state/normalizeSortInfo.ts
|
|
3241
3355
|
var EMPTY_ARRAY = Object.freeze([]);
|
|
@@ -3435,8 +3549,11 @@ function initSetupState2() {
|
|
|
3435
3549
|
dataParams: void 0,
|
|
3436
3550
|
notifyScrollbarsChange: buildSubscriptionCallback(),
|
|
3437
3551
|
notifyScrollStop: buildSubscriptionCallback(),
|
|
3552
|
+
notifyRenderRangeChange: buildSubscriptionCallback(),
|
|
3438
3553
|
pivotTotalColumnPosition: "end",
|
|
3554
|
+
scrollStopDelayUpdatedByTable: 100,
|
|
3439
3555
|
originalLazyGroupData,
|
|
3556
|
+
originalLazyGroupDataChangeDetect: 0,
|
|
3440
3557
|
originalDataArray,
|
|
3441
3558
|
cursorId: defaultCursorId,
|
|
3442
3559
|
showSeparatePivotColumnForSingleAggregation: false,
|
|
@@ -3631,7 +3748,7 @@ function getPivotColumnsAndColumnGroups({
|
|
|
3631
3748
|
var _a;
|
|
3632
3749
|
const { rowInfo } = params;
|
|
3633
3750
|
if (!rowInfo.data) {
|
|
3634
|
-
return "Loading ...
|
|
3751
|
+
return "Loading ...";
|
|
3635
3752
|
}
|
|
3636
3753
|
return rowInfo.groupKeys ? rowInfo.groupKeys[((_a = rowInfo.groupKeys) == null ? void 0 : _a.length) - 1] : null;
|
|
3637
3754
|
}
|
|
@@ -3809,6 +3926,7 @@ function concludeReducer(params) {
|
|
|
3809
3926
|
"generateGroupRows",
|
|
3810
3927
|
"originalDataArray",
|
|
3811
3928
|
"originalLazyGroupData",
|
|
3929
|
+
"originalLazyGroupDataChangeDetect",
|
|
3812
3930
|
"groupBy",
|
|
3813
3931
|
"groupRowsState",
|
|
3814
3932
|
"pivotBy",
|
|
@@ -3953,7 +4071,7 @@ function useToggleGroupRow() {
|
|
|
3953
4071
|
|
|
3954
4072
|
// src/components/InfiniteTable/hooks/useColumnsWhen.ts
|
|
3955
4073
|
function useGroupByMap(groupBy) {
|
|
3956
|
-
const groupByMap =
|
|
4074
|
+
const groupByMap = useMemo5(() => {
|
|
3957
4075
|
return groupBy.reduce((acc, groupBy2, index) => {
|
|
3958
4076
|
acc.set(groupBy2.field, {
|
|
3959
4077
|
groupBy: groupBy2,
|
|
@@ -4505,7 +4623,7 @@ var InfiniteTableCell = memo3(InfiniteTableCellFn);
|
|
|
4505
4623
|
var import_binary_search = __toModule(require_binary_search());
|
|
4506
4624
|
import {
|
|
4507
4625
|
useCallback as useCallback6,
|
|
4508
|
-
useMemo as
|
|
4626
|
+
useMemo as useMemo6,
|
|
4509
4627
|
useRef as useRef7,
|
|
4510
4628
|
useState as useState6
|
|
4511
4629
|
} from "react";
|
|
@@ -4552,8 +4670,8 @@ var useColumnPointerEvents = ({
|
|
|
4552
4670
|
const dragging = draggingDiff != null;
|
|
4553
4671
|
const { componentActions, computed } = useInfiniteTable();
|
|
4554
4672
|
const { computedColumnOrder } = computed;
|
|
4555
|
-
const column =
|
|
4556
|
-
const { columnIndex, columnWidth, columnsArray } =
|
|
4673
|
+
const column = useMemo6(() => columns.get(columnId), [columnId, columns]);
|
|
4674
|
+
const { columnIndex, columnWidth, columnsArray } = useMemo6(() => {
|
|
4557
4675
|
const columnsArray2 = Array.from(columns.values());
|
|
4558
4676
|
return {
|
|
4559
4677
|
columnsArray: columnsArray2,
|
|
@@ -4890,7 +5008,7 @@ function AvoidReactDiffFn(props) {
|
|
|
4890
5008
|
var AvoidReactDiff = memo4(AvoidReactDiffFn);
|
|
4891
5009
|
|
|
4892
5010
|
// src/components/RawList/useVirtualRenderer.ts
|
|
4893
|
-
import { useMemo as
|
|
5011
|
+
import { useMemo as useMemo7 } from "react";
|
|
4894
5012
|
|
|
4895
5013
|
// src/components/RawList/ReactVirtualRenderer.tsx
|
|
4896
5014
|
import {
|
|
@@ -5206,7 +5324,7 @@ function createRenderer(brain) {
|
|
|
5206
5324
|
function useVirtualRenderer({
|
|
5207
5325
|
brain
|
|
5208
5326
|
}) {
|
|
5209
|
-
return
|
|
5327
|
+
return useMemo7(() => {
|
|
5210
5328
|
return createRenderer(brain);
|
|
5211
5329
|
}, [brain]);
|
|
5212
5330
|
}
|
|
@@ -5298,7 +5416,7 @@ var InfiniteTableHeader = memo6(InfiniteTableHeaderFn);
|
|
|
5298
5416
|
import {
|
|
5299
5417
|
createElement as createElement18,
|
|
5300
5418
|
memo as memo7,
|
|
5301
|
-
useMemo as
|
|
5419
|
+
useMemo as useMemo8,
|
|
5302
5420
|
useRef as useRef10
|
|
5303
5421
|
} from "react";
|
|
5304
5422
|
|
|
@@ -5512,7 +5630,7 @@ function InfiniteTableHeaderUnvirtualizedFn(props) {
|
|
|
5512
5630
|
} = useInfiniteTable();
|
|
5513
5631
|
const domRef = useRef10(null);
|
|
5514
5632
|
const hasColumnGroups = computedColumnGroups.size > 0;
|
|
5515
|
-
const columnHeaderGroups =
|
|
5633
|
+
const columnHeaderGroups = useMemo8(() => {
|
|
5516
5634
|
return hasColumnGroups ? renderColumnHeaderGroups({
|
|
5517
5635
|
columnGroups: computedColumnGroups,
|
|
5518
5636
|
columnGroupsDepthsMap,
|
|
@@ -5749,7 +5867,7 @@ function SpacePlaceholderFn(props) {
|
|
|
5749
5867
|
var SpacePlaceholder = memo8(SpacePlaceholderFn);
|
|
5750
5868
|
|
|
5751
5869
|
// src/components/InfiniteTable/hooks/useListRendering.tsx
|
|
5752
|
-
import { useCallback as useCallback17, useEffect as useEffect22, useMemo as
|
|
5870
|
+
import { useCallback as useCallback17, useEffect as useEffect22, useMemo as useMemo11, useRef as useRef17 } from "react";
|
|
5753
5871
|
|
|
5754
5872
|
// src/components/InfiniteTable/hooks/useUnpinnedRendering.tsx
|
|
5755
5873
|
import {
|
|
@@ -6435,7 +6553,7 @@ var useOnContainerScroll = ({
|
|
|
6435
6553
|
// src/components/InfiniteTable/hooks/usePinnedRendering.tsx
|
|
6436
6554
|
import {
|
|
6437
6555
|
createElement as createElement29,
|
|
6438
|
-
useMemo as
|
|
6556
|
+
useMemo as useMemo9
|
|
6439
6557
|
} from "react";
|
|
6440
6558
|
import { useCallback as useCallback15 } from "react";
|
|
6441
6559
|
|
|
@@ -6541,7 +6659,7 @@ function PinnedRowsContainer(props) {
|
|
|
6541
6659
|
brain,
|
|
6542
6660
|
renderRow
|
|
6543
6661
|
} = props;
|
|
6544
|
-
const style =
|
|
6662
|
+
const style = useMemo9(() => {
|
|
6545
6663
|
const result = pinning === "end" ? {
|
|
6546
6664
|
width: rowWidth,
|
|
6547
6665
|
height,
|
|
@@ -6715,9 +6833,9 @@ function usePinnedStartRendering(params) {
|
|
|
6715
6833
|
import { useEffect as useEffect21 } from "react";
|
|
6716
6834
|
|
|
6717
6835
|
// src/components/hooks/useOnce.ts
|
|
6718
|
-
import { useMemo as
|
|
6836
|
+
import { useMemo as useMemo10 } from "react";
|
|
6719
6837
|
function useOnce(fn) {
|
|
6720
|
-
const onceFn =
|
|
6838
|
+
const onceFn = useMemo10(() => {
|
|
6721
6839
|
return once(fn);
|
|
6722
6840
|
}, []);
|
|
6723
6841
|
return onceFn();
|
|
@@ -7257,7 +7375,7 @@ function useListRendering(param) {
|
|
|
7257
7375
|
repaintIdRef.current++;
|
|
7258
7376
|
}
|
|
7259
7377
|
const repaintId = repaintIdRef.current;
|
|
7260
|
-
const rowSpan =
|
|
7378
|
+
const rowSpan = useMemo11(() => {
|
|
7261
7379
|
const colsWithRowspan = computedVisibleColumns.filter((col) => typeof col.rowspan === "function");
|
|
7262
7380
|
return colsWithRowspan.length ? ({ itemIndex }) => {
|
|
7263
7381
|
let maxSpan = 1;
|
|
@@ -7295,7 +7413,7 @@ function useListRendering(param) {
|
|
|
7295
7413
|
const hasHorizontalScrollbar = computedUnpinnedColumnsWidth > bodySize.width - computedPinnedStartColumnsWidth - computedPinnedEndColumnsWidth;
|
|
7296
7414
|
const reservedContentHeight = verticalVirtualBrain.getTotalSize() + (hasHorizontalScrollbar ? getScrollbarWidth() : 0);
|
|
7297
7415
|
const hasVerticalScrollbar = bodySize.height > 0 && bodySize.height < reservedContentHeight;
|
|
7298
|
-
const scrollbars =
|
|
7416
|
+
const scrollbars = useMemo11(() => ({
|
|
7299
7417
|
vertical: hasVerticalScrollbar,
|
|
7300
7418
|
horizontal: hasHorizontalScrollbar
|
|
7301
7419
|
}), [hasVerticalScrollbar, hasHorizontalScrollbar]);
|
|
@@ -7465,7 +7583,7 @@ var InfiniteTableLicenseFooter = forwardRef3(function InfiniteTableLicenseFooter
|
|
|
7465
7583
|
});
|
|
7466
7584
|
|
|
7467
7585
|
// src/components/InfiniteTable/hooks/useLicense/useLicense.ts
|
|
7468
|
-
import { useMemo as
|
|
7586
|
+
import { useMemo as useMemo12 } from "react";
|
|
7469
7587
|
|
|
7470
7588
|
// src/components/InfiniteTable/hooks/useLicense/crc32.ts
|
|
7471
7589
|
var DEFAULT_ReversedPolynomial = 3988292384;
|
|
@@ -7615,10 +7733,10 @@ var origin = typeof window !== "undefined" ? window.location.origin : "";
|
|
|
7615
7733
|
var [_fullUrl, protocol, sandboxUrl] = Array.from(SANDBOX_REGEX.exec(origin) || []);
|
|
7616
7734
|
var isInsideSandbox = protocol === "https" && sandboxUrl === "sandpack.codesandbox.io";
|
|
7617
7735
|
var useLicense = (licenseKey = "") => {
|
|
7618
|
-
const valid =
|
|
7736
|
+
const valid = useMemo12(() => {
|
|
7619
7737
|
let valid2 = isValidLicense(licenseKey, {
|
|
7620
7738
|
publishedAt: 1624970570587,
|
|
7621
|
-
version: "0.2.
|
|
7739
|
+
version: "0.2.1"
|
|
7622
7740
|
});
|
|
7623
7741
|
if (!licenseKey && !valid2 && isInsideSandbox) {
|
|
7624
7742
|
return true;
|
|
@@ -7820,7 +7938,8 @@ var InfiniteTableComponent = memo13(function InfiniteTableComponent2() {
|
|
|
7820
7938
|
} = useInfiniteTable();
|
|
7821
7939
|
const {
|
|
7822
7940
|
componentState: { dataArray, loading },
|
|
7823
|
-
getState: getDataSourceState
|
|
7941
|
+
getState: getDataSourceState,
|
|
7942
|
+
componentActions: dataSourceActions
|
|
7824
7943
|
} = useDataSourceContextValue();
|
|
7825
7944
|
const {
|
|
7826
7945
|
domRef,
|
|
@@ -7833,7 +7952,8 @@ var InfiniteTableComponent = memo13(function InfiniteTableComponent2() {
|
|
|
7833
7952
|
onHeaderHeightCSSVarChange,
|
|
7834
7953
|
rowHeightCSSVar,
|
|
7835
7954
|
headerHeightCSSVar,
|
|
7836
|
-
components
|
|
7955
|
+
components,
|
|
7956
|
+
scrollStopDelay
|
|
7837
7957
|
} = componentState;
|
|
7838
7958
|
const { columnShifts, bodySize } = componentState;
|
|
7839
7959
|
const {
|
|
@@ -7846,6 +7966,7 @@ var InfiniteTableComponent = memo13(function InfiniteTableComponent2() {
|
|
|
7846
7966
|
scrollbars,
|
|
7847
7967
|
applyScrollVertical,
|
|
7848
7968
|
horizontalVirtualBrain,
|
|
7969
|
+
verticalVirtualBrain,
|
|
7849
7970
|
reservedContentHeight
|
|
7850
7971
|
} = useListRendering({
|
|
7851
7972
|
getComputed,
|
|
@@ -7854,6 +7975,13 @@ var InfiniteTableComponent = memo13(function InfiniteTableComponent2() {
|
|
|
7854
7975
|
bodySize,
|
|
7855
7976
|
computed
|
|
7856
7977
|
});
|
|
7978
|
+
useEffect24(() => {
|
|
7979
|
+
const dataSourceState = getDataSourceState();
|
|
7980
|
+
const onChange = debounce((renderRange) => {
|
|
7981
|
+
dataSourceState.notifyRenderRangeChange(renderRange);
|
|
7982
|
+
}, { wait: scrollStopDelay });
|
|
7983
|
+
return verticalVirtualBrain.onRenderRangeChange(onChange);
|
|
7984
|
+
}, [verticalVirtualBrain, scrollStopDelay]);
|
|
7857
7985
|
const licenseValid = useLicense(licenseKey);
|
|
7858
7986
|
const domProps = useDOMProps(componentState.domProps);
|
|
7859
7987
|
const LoadMaskCmp = (_a = components == null ? void 0 : components.LoadMask) != null ? _a : LoadMask;
|
|
@@ -7866,6 +7994,9 @@ var InfiniteTableComponent = memo13(function InfiniteTableComponent2() {
|
|
|
7866
7994
|
}
|
|
7867
7995
|
notifyScrollbarsChange(scrollbars);
|
|
7868
7996
|
}, [scrollbars]);
|
|
7997
|
+
useEffect24(() => {
|
|
7998
|
+
dataSourceActions.scrollStopDelayUpdatedByTable = scrollStopDelay;
|
|
7999
|
+
}, [scrollStopDelay]);
|
|
7869
8000
|
return /* @__PURE__ */ createElement33("div", __spreadValues({
|
|
7870
8001
|
ref: domRef
|
|
7871
8002
|
}, domProps), header ? /* @__PURE__ */ createElement33(TableHeaderWrapper, {
|
package/index.js
CHANGED
|
@@ -3013,11 +3013,33 @@ function useEffectWithChanges(fn, deps) {
|
|
|
3013
3013
|
}, useEffectDeps);
|
|
3014
3014
|
}
|
|
3015
3015
|
|
|
3016
|
+
// src/components/utils/debounce.ts
|
|
3017
|
+
function debounce(fn, { wait }) {
|
|
3018
|
+
let timeout = null;
|
|
3019
|
+
return function(...args) {
|
|
3020
|
+
const context = this;
|
|
3021
|
+
if (timeout !== null) {
|
|
3022
|
+
clearTimeout(timeout);
|
|
3023
|
+
}
|
|
3024
|
+
timeout = setTimeout(() => {
|
|
3025
|
+
fn.apply(context, args);
|
|
3026
|
+
}, wait);
|
|
3027
|
+
};
|
|
3028
|
+
}
|
|
3029
|
+
|
|
3016
3030
|
// src/components/DataSource/privateHooks/useLoadData.ts
|
|
3031
|
+
var getRafPromise = () => new Promise((resolve) => {
|
|
3032
|
+
requestAnimationFrame(resolve);
|
|
3033
|
+
});
|
|
3017
3034
|
var SKIP_DATA_CHANGES_KEYS = {
|
|
3018
3035
|
originalDataArray: true,
|
|
3019
3036
|
changes: true
|
|
3020
3037
|
};
|
|
3038
|
+
function getChangeDetect() {
|
|
3039
|
+
var _a;
|
|
3040
|
+
const perfNow = (_a = getGlobal().performance) == null ? void 0 : _a.now();
|
|
3041
|
+
return `${Date.now()}:${perfNow}`;
|
|
3042
|
+
}
|
|
3021
3043
|
function buildDataSourceDataParams(componentState, overrides) {
|
|
3022
3044
|
var _a, _b;
|
|
3023
3045
|
const sortInfo = componentState.multiSort ? componentState.sortInfo : (_b = (_a = componentState.sortInfo) == null ? void 0 : _a[0]) != null ? _b : null;
|
|
@@ -3061,10 +3083,10 @@ function loadData(data, componentState, actions, overrides) {
|
|
|
3061
3083
|
data = data(dataParams);
|
|
3062
3084
|
}
|
|
3063
3085
|
const dataIsPromise = typeof data === "object" && typeof data.then === "function";
|
|
3064
|
-
if (dataIsPromise) {
|
|
3086
|
+
if (dataIsPromise && !componentState.fullLazyLoad) {
|
|
3065
3087
|
actions.loading = true;
|
|
3066
3088
|
}
|
|
3067
|
-
Promise.resolve(data).then((dataParam) => {
|
|
3089
|
+
return Promise.resolve(data).then((dataParam) => {
|
|
3068
3090
|
var _a, _b, _c;
|
|
3069
3091
|
let dataArray = [];
|
|
3070
3092
|
let skipAssign = false;
|
|
@@ -3078,7 +3100,7 @@ function loadData(data, componentState, actions, overrides) {
|
|
|
3078
3100
|
actions.pivotMappings = remoteData.mappings;
|
|
3079
3101
|
}
|
|
3080
3102
|
if (componentState.fullLazyLoad && dataParams.groupKeys) {
|
|
3081
|
-
const lazyGroupData =
|
|
3103
|
+
const lazyGroupData = componentState.originalLazyGroupData;
|
|
3082
3104
|
const key = [LAZY_ROOT_KEY_FOR_GROUPS, ...dataParams.groupKeys];
|
|
3083
3105
|
const newGroupRowInfo = {
|
|
3084
3106
|
totalCount: (_a = remoteData.totalCount) != null ? _a : dataArray.length,
|
|
@@ -3092,7 +3114,7 @@ function loadData(data, componentState, actions, overrides) {
|
|
|
3092
3114
|
};
|
|
3093
3115
|
currentGroupRowInfo.items.length = currentGroupRowInfo.totalCount;
|
|
3094
3116
|
const start = (_b = dataParams.lazyLoadStartIndex) != null ? _b : 0;
|
|
3095
|
-
const end =
|
|
3117
|
+
const end = Math.min((_c = remoteData.totalCount) != null ? _c : start + dataParams.lazyLoadBatchSize);
|
|
3096
3118
|
for (let i = start; i < end; i++) {
|
|
3097
3119
|
currentGroupRowInfo.items[i] = newGroupRowInfo.items[i - start];
|
|
3098
3120
|
}
|
|
@@ -3103,7 +3125,7 @@ function loadData(data, componentState, actions, overrides) {
|
|
|
3103
3125
|
lazyGroupData.set(key, newGroupRowInfo);
|
|
3104
3126
|
}
|
|
3105
3127
|
skipAssign = true;
|
|
3106
|
-
actions.
|
|
3128
|
+
actions.originalLazyGroupDataChangeDetect = getChangeDetect();
|
|
3107
3129
|
}
|
|
3108
3130
|
} else {
|
|
3109
3131
|
dataArray = dataParam;
|
|
@@ -3111,7 +3133,7 @@ function loadData(data, componentState, actions, overrides) {
|
|
|
3111
3133
|
if (!skipAssign) {
|
|
3112
3134
|
actions.originalDataArray = dataArray;
|
|
3113
3135
|
}
|
|
3114
|
-
if (dataIsPromise) {
|
|
3136
|
+
if (dataIsPromise && !componentState.fullLazyLoad) {
|
|
3115
3137
|
actions.loading = false;
|
|
3116
3138
|
}
|
|
3117
3139
|
});
|
|
@@ -3130,9 +3152,7 @@ function useLoadData() {
|
|
|
3130
3152
|
pivotBy,
|
|
3131
3153
|
livePagination,
|
|
3132
3154
|
livePaginationCursor,
|
|
3133
|
-
cursorId: stateCursorId
|
|
3134
|
-
lazyLoadBatchSize,
|
|
3135
|
-
notifyScrollStop
|
|
3155
|
+
cursorId: stateCursorId
|
|
3136
3156
|
} = componentState;
|
|
3137
3157
|
const [scrollbars, setScrollbars] = (0, import_react15.useState)({
|
|
3138
3158
|
vertical: false,
|
|
@@ -3173,33 +3193,7 @@ function useLoadData() {
|
|
|
3173
3193
|
cursorId: livePagination ? stateCursorId : null
|
|
3174
3194
|
};
|
|
3175
3195
|
const initialRef = (0, import_react15.useRef)(true);
|
|
3176
|
-
(
|
|
3177
|
-
if (lazyLoadBatchSize && lazyLoadBatchSize > 0) {
|
|
3178
|
-
return notifyScrollStop.onChange((param) => {
|
|
3179
|
-
console.log("scroll stop", param);
|
|
3180
|
-
if (!param) {
|
|
3181
|
-
return;
|
|
3182
|
-
}
|
|
3183
|
-
const componentState2 = getComponentState();
|
|
3184
|
-
const {
|
|
3185
|
-
firstVisibleRowIndex: startIndex,
|
|
3186
|
-
lastVisibleRowIndex: endIndex
|
|
3187
|
-
} = param;
|
|
3188
|
-
const firstBatchStart = Math.floor(startIndex / lazyLoadBatchSize) * lazyLoadBatchSize;
|
|
3189
|
-
const lastBatchStart = Math.floor(endIndex / lazyLoadBatchSize) * lazyLoadBatchSize;
|
|
3190
|
-
const isRowLoaded = (index) => componentState2.dataArray[index].data != null;
|
|
3191
|
-
for (let batchStartIndex = firstBatchStart; batchStartIndex <= lastBatchStart; batchStartIndex = batchStartIndex + lazyLoadBatchSize) {
|
|
3192
|
-
if (!isRowLoaded(batchStartIndex)) {
|
|
3193
|
-
loadData(componentState2.data, componentState2, actions, {
|
|
3194
|
-
lazyLoadBatchSize,
|
|
3195
|
-
lazyLoadStartIndex: batchStartIndex
|
|
3196
|
-
});
|
|
3197
|
-
}
|
|
3198
|
-
}
|
|
3199
|
-
});
|
|
3200
|
-
}
|
|
3201
|
-
return;
|
|
3202
|
-
}, [lazyLoadBatchSize]);
|
|
3196
|
+
useLazyLoadRange();
|
|
3203
3197
|
useEffectWithChanges(() => {
|
|
3204
3198
|
const componentState2 = getComponentState();
|
|
3205
3199
|
if (typeof componentState2.data !== "function") {
|
|
@@ -3220,6 +3214,126 @@ function useLoadData() {
|
|
|
3220
3214
|
}
|
|
3221
3215
|
}, depsObject);
|
|
3222
3216
|
}
|
|
3217
|
+
function useLazyLoadRange() {
|
|
3218
|
+
const {
|
|
3219
|
+
getComponentState,
|
|
3220
|
+
componentActions: actions,
|
|
3221
|
+
componentState
|
|
3222
|
+
} = useComponentState();
|
|
3223
|
+
const loadingCache = (0, import_react15.useMemo)(() => {
|
|
3224
|
+
return new Map();
|
|
3225
|
+
}, [componentState.data]);
|
|
3226
|
+
globalThis.loadingCache = loadingCache;
|
|
3227
|
+
const {
|
|
3228
|
+
lazyLoadBatchSize,
|
|
3229
|
+
notifyRenderRangeChange,
|
|
3230
|
+
dataArray,
|
|
3231
|
+
scrollStopDelayUpdatedByTable
|
|
3232
|
+
} = componentState;
|
|
3233
|
+
const latestRenderRangeRef = (0, import_react15.useRef)(null);
|
|
3234
|
+
const loadRange = (param, cache = loadingCache) => {
|
|
3235
|
+
const componentState2 = getComponentState();
|
|
3236
|
+
param = param || latestRenderRangeRef.current;
|
|
3237
|
+
if (!param) {
|
|
3238
|
+
return;
|
|
3239
|
+
}
|
|
3240
|
+
const { renderStartIndex: startIndex, renderEndIndex: endIndex } = param;
|
|
3241
|
+
if (!lazyLoadBatchSize || lazyLoadBatchSize <= 0) {
|
|
3242
|
+
return;
|
|
3243
|
+
}
|
|
3244
|
+
lazyLoadRange({
|
|
3245
|
+
startIndex,
|
|
3246
|
+
endIndex,
|
|
3247
|
+
lazyLoadBatchSize,
|
|
3248
|
+
componentState: componentState2,
|
|
3249
|
+
componentActions: actions
|
|
3250
|
+
}, cache);
|
|
3251
|
+
};
|
|
3252
|
+
const debouncedLoadRange = (0, import_react15.useMemo)(() => debounce(loadRange, { wait: scrollStopDelayUpdatedByTable }), [scrollStopDelayUpdatedByTable]);
|
|
3253
|
+
(0, import_react15.useEffect)(() => {
|
|
3254
|
+
if (lazyLoadBatchSize && lazyLoadBatchSize > 0) {
|
|
3255
|
+
return notifyRenderRangeChange.onChange((param) => {
|
|
3256
|
+
latestRenderRangeRef.current = param;
|
|
3257
|
+
loadRange(param, loadingCache);
|
|
3258
|
+
});
|
|
3259
|
+
}
|
|
3260
|
+
return;
|
|
3261
|
+
}, [lazyLoadBatchSize, loadingCache]);
|
|
3262
|
+
(0, import_react15.useEffect)(() => {
|
|
3263
|
+
if (lazyLoadBatchSize && lazyLoadBatchSize > 0) {
|
|
3264
|
+
debouncedLoadRange();
|
|
3265
|
+
}
|
|
3266
|
+
return;
|
|
3267
|
+
}, [dataArray]);
|
|
3268
|
+
}
|
|
3269
|
+
function lazyLoadRange(options, cache) {
|
|
3270
|
+
const {
|
|
3271
|
+
startIndex,
|
|
3272
|
+
endIndex,
|
|
3273
|
+
lazyLoadBatchSize,
|
|
3274
|
+
componentState,
|
|
3275
|
+
componentActions
|
|
3276
|
+
} = options;
|
|
3277
|
+
const { dataArray } = componentState;
|
|
3278
|
+
const isRowLoaded = (index) => dataArray[index].data != null;
|
|
3279
|
+
const perGroupFnCalls = new DeepMap();
|
|
3280
|
+
const rootGroupKeys = ["_______xxx______"];
|
|
3281
|
+
for (let i = startIndex; i <= endIndex; i++) {
|
|
3282
|
+
const rowInfo = dataArray[i];
|
|
3283
|
+
if (!rowInfo) {
|
|
3284
|
+
continue;
|
|
3285
|
+
}
|
|
3286
|
+
const rowLoaded = rowInfo.data != null;
|
|
3287
|
+
const parentGroupKeys = rowInfo.groupKeys ? [...rowInfo.groupKeys] : [];
|
|
3288
|
+
if (rowInfo.groupKeys) {
|
|
3289
|
+
parentGroupKeys.pop();
|
|
3290
|
+
}
|
|
3291
|
+
const cacheKeys = parentGroupKeys.length ? parentGroupKeys : rootGroupKeys;
|
|
3292
|
+
const indexInGroup = rowInfo.indexInGroup;
|
|
3293
|
+
if (!rowLoaded) {
|
|
3294
|
+
let fnCalls = perGroupFnCalls.get(cacheKeys);
|
|
3295
|
+
const batchStartIndexInGroup = Math.floor(indexInGroup / lazyLoadBatchSize) * lazyLoadBatchSize;
|
|
3296
|
+
const offset = rowInfo.indexInGroup - batchStartIndexInGroup;
|
|
3297
|
+
const absoluteIndexOfBatchStart = dataArray[rowInfo.indexInAll - offset].indexInAll;
|
|
3298
|
+
const batchStartRowLoaded = isRowLoaded(absoluteIndexOfBatchStart);
|
|
3299
|
+
const batchStartRowId = dataArray[absoluteIndexOfBatchStart].id;
|
|
3300
|
+
if (batchStartRowLoaded || (fnCalls == null ? void 0 : fnCalls[batchStartRowId])) {
|
|
3301
|
+
continue;
|
|
3302
|
+
}
|
|
3303
|
+
const shouldSetFnCalls = !fnCalls;
|
|
3304
|
+
fnCalls = fnCalls || {};
|
|
3305
|
+
const currentFnCall = {
|
|
3306
|
+
lazyLoadStartIndex: batchStartIndexInGroup,
|
|
3307
|
+
lazyLoadBatchSize,
|
|
3308
|
+
groupKeys: parentGroupKeys
|
|
3309
|
+
};
|
|
3310
|
+
if (!fnCalls[batchStartRowId]) {
|
|
3311
|
+
fnCalls[batchStartRowId] = currentFnCall;
|
|
3312
|
+
}
|
|
3313
|
+
if (shouldSetFnCalls) {
|
|
3314
|
+
perGroupFnCalls.set(cacheKeys, fnCalls);
|
|
3315
|
+
}
|
|
3316
|
+
}
|
|
3317
|
+
}
|
|
3318
|
+
let initialPromise = Promise.resolve(true);
|
|
3319
|
+
const allFnCalls = [];
|
|
3320
|
+
perGroupFnCalls.topDownValues().forEach((record) => {
|
|
3321
|
+
allFnCalls.push(...Object.values(record));
|
|
3322
|
+
});
|
|
3323
|
+
allFnCalls.reduce((promise, fnCall) => {
|
|
3324
|
+
const cacheKey = `${fnCall.groupKeys.join("-")}:${fnCall.lazyLoadStartIndex}`;
|
|
3325
|
+
if (cache && cache.has(cacheKey)) {
|
|
3326
|
+
return promise;
|
|
3327
|
+
}
|
|
3328
|
+
cache == null ? void 0 : cache.set(cacheKey, true);
|
|
3329
|
+
const args = [componentState.data, componentState, componentActions, fnCall];
|
|
3330
|
+
return promise.then(() => getRafPromise()).then(() => loadData(...args)).then(() => {
|
|
3331
|
+
requestAnimationFrame(() => {
|
|
3332
|
+
cache == null ? void 0 : cache.delete(cacheKey);
|
|
3333
|
+
});
|
|
3334
|
+
});
|
|
3335
|
+
}, initialPromise);
|
|
3336
|
+
}
|
|
3223
3337
|
|
|
3224
3338
|
// src/components/DataSource/state/normalizeSortInfo.ts
|
|
3225
3339
|
var EMPTY_ARRAY = Object.freeze([]);
|
|
@@ -3419,8 +3533,11 @@ function initSetupState2() {
|
|
|
3419
3533
|
dataParams: void 0,
|
|
3420
3534
|
notifyScrollbarsChange: buildSubscriptionCallback(),
|
|
3421
3535
|
notifyScrollStop: buildSubscriptionCallback(),
|
|
3536
|
+
notifyRenderRangeChange: buildSubscriptionCallback(),
|
|
3422
3537
|
pivotTotalColumnPosition: "end",
|
|
3538
|
+
scrollStopDelayUpdatedByTable: 100,
|
|
3423
3539
|
originalLazyGroupData,
|
|
3540
|
+
originalLazyGroupDataChangeDetect: 0,
|
|
3424
3541
|
originalDataArray,
|
|
3425
3542
|
cursorId: defaultCursorId,
|
|
3426
3543
|
showSeparatePivotColumnForSingleAggregation: false,
|
|
@@ -3615,7 +3732,7 @@ function getPivotColumnsAndColumnGroups({
|
|
|
3615
3732
|
var _a;
|
|
3616
3733
|
const { rowInfo } = params;
|
|
3617
3734
|
if (!rowInfo.data) {
|
|
3618
|
-
return "Loading ...
|
|
3735
|
+
return "Loading ...";
|
|
3619
3736
|
}
|
|
3620
3737
|
return rowInfo.groupKeys ? rowInfo.groupKeys[((_a = rowInfo.groupKeys) == null ? void 0 : _a.length) - 1] : null;
|
|
3621
3738
|
}
|
|
@@ -3793,6 +3910,7 @@ function concludeReducer(params) {
|
|
|
3793
3910
|
"generateGroupRows",
|
|
3794
3911
|
"originalDataArray",
|
|
3795
3912
|
"originalLazyGroupData",
|
|
3913
|
+
"originalLazyGroupDataChangeDetect",
|
|
3796
3914
|
"groupBy",
|
|
3797
3915
|
"groupRowsState",
|
|
3798
3916
|
"pivotBy",
|
|
@@ -7523,7 +7641,7 @@ var useLicense = (licenseKey = "") => {
|
|
|
7523
7641
|
const valid = (0, import_react43.useMemo)(() => {
|
|
7524
7642
|
let valid2 = isValidLicense(licenseKey, {
|
|
7525
7643
|
publishedAt: 1624970570587,
|
|
7526
|
-
version: "0.2.
|
|
7644
|
+
version: "0.2.1"
|
|
7527
7645
|
});
|
|
7528
7646
|
if (!licenseKey && !valid2 && isInsideSandbox) {
|
|
7529
7647
|
return true;
|
|
@@ -7718,7 +7836,8 @@ var InfiniteTableComponent = React35.memo(function InfiniteTableComponent2() {
|
|
|
7718
7836
|
} = useInfiniteTable();
|
|
7719
7837
|
const {
|
|
7720
7838
|
componentState: { dataArray, loading },
|
|
7721
|
-
getState: getDataSourceState
|
|
7839
|
+
getState: getDataSourceState,
|
|
7840
|
+
componentActions: dataSourceActions
|
|
7722
7841
|
} = useDataSourceContextValue();
|
|
7723
7842
|
const {
|
|
7724
7843
|
domRef,
|
|
@@ -7731,7 +7850,8 @@ var InfiniteTableComponent = React35.memo(function InfiniteTableComponent2() {
|
|
|
7731
7850
|
onHeaderHeightCSSVarChange,
|
|
7732
7851
|
rowHeightCSSVar,
|
|
7733
7852
|
headerHeightCSSVar,
|
|
7734
|
-
components
|
|
7853
|
+
components,
|
|
7854
|
+
scrollStopDelay
|
|
7735
7855
|
} = componentState;
|
|
7736
7856
|
const { columnShifts, bodySize } = componentState;
|
|
7737
7857
|
const {
|
|
@@ -7744,6 +7864,7 @@ var InfiniteTableComponent = React35.memo(function InfiniteTableComponent2() {
|
|
|
7744
7864
|
scrollbars,
|
|
7745
7865
|
applyScrollVertical,
|
|
7746
7866
|
horizontalVirtualBrain,
|
|
7867
|
+
verticalVirtualBrain,
|
|
7747
7868
|
reservedContentHeight
|
|
7748
7869
|
} = useListRendering({
|
|
7749
7870
|
getComputed,
|
|
@@ -7752,6 +7873,13 @@ var InfiniteTableComponent = React35.memo(function InfiniteTableComponent2() {
|
|
|
7752
7873
|
bodySize,
|
|
7753
7874
|
computed
|
|
7754
7875
|
});
|
|
7876
|
+
React35.useEffect(() => {
|
|
7877
|
+
const dataSourceState = getDataSourceState();
|
|
7878
|
+
const onChange = debounce((renderRange) => {
|
|
7879
|
+
dataSourceState.notifyRenderRangeChange(renderRange);
|
|
7880
|
+
}, { wait: scrollStopDelay });
|
|
7881
|
+
return verticalVirtualBrain.onRenderRangeChange(onChange);
|
|
7882
|
+
}, [verticalVirtualBrain, scrollStopDelay]);
|
|
7755
7883
|
const licenseValid = useLicense(licenseKey);
|
|
7756
7884
|
const domProps = useDOMProps(componentState.domProps);
|
|
7757
7885
|
const LoadMaskCmp = (_a = components == null ? void 0 : components.LoadMask) != null ? _a : LoadMask;
|
|
@@ -7764,6 +7892,9 @@ var InfiniteTableComponent = React35.memo(function InfiniteTableComponent2() {
|
|
|
7764
7892
|
}
|
|
7765
7893
|
notifyScrollbarsChange(scrollbars);
|
|
7766
7894
|
}, [scrollbars]);
|
|
7895
|
+
React35.useEffect(() => {
|
|
7896
|
+
dataSourceActions.scrollStopDelayUpdatedByTable = scrollStopDelay;
|
|
7897
|
+
}, [scrollStopDelay]);
|
|
7767
7898
|
return /* @__PURE__ */ React35.createElement("div", __spreadValues({
|
|
7768
7899
|
ref: domRef
|
|
7769
7900
|
}, domProps), header ? /* @__PURE__ */ React35.createElement(TableHeaderWrapper, {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@infinite-table/infinite-react",
|
|
3
3
|
"description": "Infinite Table for React",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.1",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "index.esm.js",
|
|
7
7
|
"typings": "index.d.ts",
|
|
@@ -14,5 +14,5 @@
|
|
|
14
14
|
},
|
|
15
15
|
"license": "Commercial & Open Source",
|
|
16
16
|
"//": "will be updated at build time",
|
|
17
|
-
"publishedAt":
|
|
17
|
+
"publishedAt": 1643825063998
|
|
18
18
|
}
|