@etsoo/materialui 1.5.71 → 1.5.72
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/__tests__/ReactAppTests.tsx +12 -7
- package/__tests__/SelectEx.tsx +1 -1
- package/lib/cjs/DataGridEx.d.ts +8 -1
- package/lib/cjs/DataGridEx.js +71 -56
- package/lib/cjs/DataGridRenderers.d.ts +1 -1
- package/lib/cjs/DataGridRenderers.js +1 -1
- package/lib/cjs/MUUtils.d.ts +0 -9
- package/lib/cjs/MUUtils.js +0 -26
- package/lib/cjs/MobileListItemRenderer.d.ts +2 -2
- package/lib/cjs/ResponsibleContainer.d.ts +2 -7
- package/lib/cjs/ResponsibleContainer.js +8 -57
- package/lib/cjs/ScrollerListEx.d.ts +24 -9
- package/lib/cjs/ScrollerListEx.js +35 -38
- package/lib/cjs/TableEx.d.ts +7 -0
- package/lib/cjs/TableEx.js +6 -12
- package/lib/cjs/pages/DataGridPage.js +3 -32
- package/lib/cjs/pages/FixedListPage.js +5 -34
- package/lib/cjs/pages/ListPage.js +1 -29
- package/lib/cjs/pages/ResponsivePage.d.ts +2 -7
- package/lib/cjs/uses/useGridCacheInitLoad.d.ts +2 -0
- package/lib/cjs/uses/useGridCacheInitLoad.js +41 -0
- package/lib/cjs/uses/useListCacheInitLoad.d.ts +2 -0
- package/lib/cjs/uses/useListCacheInitLoad.js +38 -0
- package/lib/mjs/DataGridEx.d.ts +8 -1
- package/lib/mjs/DataGridEx.js +71 -56
- package/lib/mjs/DataGridRenderers.d.ts +1 -1
- package/lib/mjs/DataGridRenderers.js +1 -1
- package/lib/mjs/MUUtils.d.ts +0 -9
- package/lib/mjs/MUUtils.js +0 -26
- package/lib/mjs/MobileListItemRenderer.d.ts +2 -2
- package/lib/mjs/ResponsibleContainer.d.ts +2 -7
- package/lib/mjs/ResponsibleContainer.js +8 -57
- package/lib/mjs/ScrollerListEx.d.ts +24 -9
- package/lib/mjs/ScrollerListEx.js +35 -38
- package/lib/mjs/TableEx.d.ts +7 -0
- package/lib/mjs/TableEx.js +6 -12
- package/lib/mjs/pages/DataGridPage.js +3 -32
- package/lib/mjs/pages/FixedListPage.js +5 -34
- package/lib/mjs/pages/ListPage.js +1 -29
- package/lib/mjs/pages/ResponsivePage.d.ts +2 -7
- package/lib/mjs/uses/useGridCacheInitLoad.d.ts +2 -0
- package/lib/mjs/uses/useGridCacheInitLoad.js +35 -0
- package/lib/mjs/uses/useListCacheInitLoad.d.ts +2 -0
- package/lib/mjs/uses/useListCacheInitLoad.js +32 -0
- package/package.json +18 -19
- package/src/DataGridEx.tsx +151 -108
- package/src/DataGridRenderers.tsx +2 -1
- package/src/MUUtils.ts +0 -33
- package/src/MobileListItemRenderer.tsx +2 -2
- package/src/ResponsibleContainer.tsx +21 -94
- package/src/ScrollerListEx.tsx +109 -121
- package/src/TableEx.tsx +20 -12
- package/src/pages/DataGridPage.tsx +3 -49
- package/src/pages/FixedListPage.tsx +5 -49
- package/src/pages/ListPage.tsx +0 -43
- package/src/pages/ResponsivePage.tsx +3 -11
- package/src/uses/useGridCacheInitLoad.ts +55 -0
- package/src/uses/useListCacheInitLoad.ts +51 -0
|
@@ -36,6 +36,8 @@ export function ResponsibleContainer(props) {
|
|
|
36
36
|
if (ref == null)
|
|
37
37
|
return;
|
|
38
38
|
state.ref = ref;
|
|
39
|
+
if (ref.element && elementReady)
|
|
40
|
+
elementReady(ref.element, true);
|
|
39
41
|
});
|
|
40
42
|
// Screen size detection
|
|
41
43
|
const showDataGrid = useMediaQuery("(min-width:600px)");
|
|
@@ -77,44 +79,6 @@ export function ResponsibleContainer(props) {
|
|
|
77
79
|
state.rect = rect;
|
|
78
80
|
return false;
|
|
79
81
|
});
|
|
80
|
-
const onInitLoad = (ref) => {
|
|
81
|
-
// Avoid repeatedly load from cache
|
|
82
|
-
if (refs.current.initLoaded || !cacheKey)
|
|
83
|
-
return undefined;
|
|
84
|
-
// Cache data
|
|
85
|
-
const cacheData = GridUtils.getCacheData(cacheKey, cacheMinutes);
|
|
86
|
-
if (cacheData) {
|
|
87
|
-
const { rows, state } = cacheData;
|
|
88
|
-
GridUtils.mergeSearchData(state, searchData);
|
|
89
|
-
// Scroll position
|
|
90
|
-
const scrollData = sessionStorage.getItem(`${cacheKey}-scroll`);
|
|
91
|
-
if (scrollData) {
|
|
92
|
-
if ("resetAfterColumnIndex" in ref) {
|
|
93
|
-
const { scrollLeft, scrollTop } = JSON.parse(scrollData);
|
|
94
|
-
globalThis.setTimeout(() => ref.scrollTo({ scrollLeft, scrollTop }), 0);
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
const { scrollOffset } = JSON.parse(scrollData);
|
|
98
|
-
globalThis.setTimeout(() => ref.scrollTo(scrollOffset), 0);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
// Update flag value
|
|
102
|
-
refs.current.initLoaded = true;
|
|
103
|
-
// Return cached rows and state
|
|
104
|
-
return [rows, state];
|
|
105
|
-
}
|
|
106
|
-
return undefined;
|
|
107
|
-
};
|
|
108
|
-
const onListScroll = (props) => {
|
|
109
|
-
if (!cacheKey || !refs.current.initLoaded)
|
|
110
|
-
return;
|
|
111
|
-
sessionStorage.setItem(`${cacheKey}-scroll`, JSON.stringify(props));
|
|
112
|
-
};
|
|
113
|
-
const onGridScroll = (props) => {
|
|
114
|
-
if (!cacheKey || !refs.current.initLoaded)
|
|
115
|
-
return;
|
|
116
|
-
sessionStorage.setItem(`${cacheKey}-scroll`, JSON.stringify(props));
|
|
117
|
-
};
|
|
118
82
|
// Rect
|
|
119
83
|
const rect = dimensions[0][2];
|
|
120
84
|
// Create list
|
|
@@ -144,26 +108,13 @@ export function ResponsibleContainer(props) {
|
|
|
144
108
|
if (adjustFabHeight)
|
|
145
109
|
heightLocal = adjustFabHeight(heightLocal, showDataGrid);
|
|
146
110
|
if (showDataGrid) {
|
|
147
|
-
//
|
|
148
|
-
|
|
149
|
-
return (_jsx(Box, { className: "DataGridBox", children: _jsx(DataGridEx, { autoLoad: !hasFields, height: heightLocal, width: rect.width, loadData: localLoadData, mRef: mRefs, onDoubleClick: (_, data) => quickAction && quickAction(data),
|
|
150
|
-
if (element != null && elementReady)
|
|
151
|
-
elementReady(element, true);
|
|
152
|
-
}, onScroll: onGridScroll, columns: columns, onUpdateRows: GridUtils.getUpdateRowsHandler(cacheKey), onInitLoad: onInitLoad, ...rest }) }));
|
|
111
|
+
// Remove useless props
|
|
112
|
+
const { itemRenderer, ...gridProps } = rest;
|
|
113
|
+
return (_jsx(Box, { className: "DataGridBox", children: _jsx(DataGridEx, { autoLoad: !hasFields, height: heightLocal, width: rect.width, loadData: localLoadData, mRef: mRefs, onDoubleClick: (_, data) => quickAction && quickAction(data), columns: columns, ...gridProps }) }));
|
|
153
114
|
}
|
|
154
|
-
//
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
delete rest.bottomHeight;
|
|
158
|
-
delete rest.footerItemRenderer;
|
|
159
|
-
delete rest.headerHeight;
|
|
160
|
-
delete rest.hideFooter;
|
|
161
|
-
delete rest.hoverColor;
|
|
162
|
-
delete rest.selectable;
|
|
163
|
-
return (_jsx(Box, { className: "ListBox", sx: { height: heightLocal }, children: _jsx(ScrollerListEx, { autoLoad: !hasFields, height: heightLocal, loadData: localLoadData, onUpdateRows: GridUtils.getUpdateRowsHandler(cacheKey), onInitLoad: onInitLoad, mRef: mRefs, onClick: (event, data) => quickAction && ReactUtils.isSafeClick(event) && quickAction(data), oRef: (element) => {
|
|
164
|
-
if (element != null && elementReady)
|
|
165
|
-
elementReady(element, false);
|
|
166
|
-
}, onScroll: onListScroll, ...rest }) }));
|
|
115
|
+
// Remove useless props
|
|
116
|
+
const { checkable, borderRowsCount, bottomHeight, footerItemRenderer, headerHeight, hideFooter, hoverColor, selectable, ...listProps } = rest;
|
|
117
|
+
return (_jsx(Box, { className: "ListBox", sx: { height: heightLocal }, children: _jsx(ScrollerListEx, { autoLoad: !hasFields, height: heightLocal, loadData: localLoadData, mRef: mRefs, onClick: (event, data) => quickAction && ReactUtils.isSafeClick(event) && quickAction(data), ...listProps }) }));
|
|
167
118
|
})();
|
|
168
119
|
const searchBar = React.useMemo(() => {
|
|
169
120
|
if (!hasFields ||
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import { ScrollerListProps } from "@etsoo/react";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import { ListChildComponentProps } from "react-window";
|
|
4
3
|
import { MouseEventWithDataHandler } from "./MUGlobal";
|
|
5
4
|
/**
|
|
6
5
|
* Extended ScrollerList inner item renderer props
|
|
7
6
|
*/
|
|
8
|
-
export
|
|
7
|
+
export type ScrollerListExItemRendererProps<T> = {
|
|
9
8
|
/**
|
|
10
|
-
*
|
|
9
|
+
* Row index
|
|
11
10
|
*/
|
|
12
|
-
|
|
11
|
+
index: number;
|
|
12
|
+
/**
|
|
13
|
+
* Row data
|
|
14
|
+
*/
|
|
15
|
+
data: T;
|
|
16
|
+
/**
|
|
17
|
+
* Style
|
|
18
|
+
*/
|
|
19
|
+
style: React.CSSProperties;
|
|
13
20
|
/**
|
|
14
21
|
* Item height
|
|
15
22
|
*/
|
|
@@ -22,7 +29,11 @@ export interface ScrollerListExInnerItemRendererProps<T> extends ListChildCompon
|
|
|
22
29
|
* Default margins
|
|
23
30
|
*/
|
|
24
31
|
margins: object;
|
|
25
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Item selected
|
|
34
|
+
*/
|
|
35
|
+
selected: boolean;
|
|
36
|
+
};
|
|
26
37
|
/**
|
|
27
38
|
* Extended ScrollerList ItemSize type
|
|
28
39
|
* 1. Callback function
|
|
@@ -33,19 +44,23 @@ export type ScrollerListExItemSize = ((index: number) => [number, number] | [num
|
|
|
33
44
|
/**
|
|
34
45
|
* Extended ScrollerList Props
|
|
35
46
|
*/
|
|
36
|
-
export type ScrollerListExProps<T extends object> = Omit<ScrollerListProps<T>, "
|
|
47
|
+
export type ScrollerListExProps<T extends object> = Omit<ScrollerListProps<T>, "rowComponent" | "rowHeight" | "onClick" | "onDoubleClick" | "onInitLoad"> & {
|
|
37
48
|
/**
|
|
38
49
|
* Alternating colors for odd/even rows
|
|
39
50
|
*/
|
|
40
51
|
alternatingColors?: [string?, string?];
|
|
41
52
|
/**
|
|
42
|
-
*
|
|
53
|
+
* Cache key
|
|
54
|
+
*/
|
|
55
|
+
cacheKey?: string;
|
|
56
|
+
/**
|
|
57
|
+
* Cache minutes
|
|
43
58
|
*/
|
|
44
|
-
|
|
59
|
+
cacheMinutes?: number;
|
|
45
60
|
/**
|
|
46
61
|
* Item renderer
|
|
47
62
|
*/
|
|
48
|
-
itemRenderer?: (props:
|
|
63
|
+
itemRenderer?: (props: ScrollerListExItemRendererProps<T>) => React.ReactNode;
|
|
49
64
|
/**
|
|
50
65
|
* Item size, a function indicates its a variable size list
|
|
51
66
|
*/
|
|
@@ -5,6 +5,9 @@ import { Utils } from "@etsoo/shared";
|
|
|
5
5
|
import React from "react";
|
|
6
6
|
import { MUGlobal } from "./MUGlobal";
|
|
7
7
|
import { useTheme } from "@mui/material/styles";
|
|
8
|
+
import { GridUtils } from "./GridUtils";
|
|
9
|
+
import { useListCacheInitLoad } from "./uses/useListCacheInitLoad";
|
|
10
|
+
import Box from "@mui/material/Box";
|
|
8
11
|
// Scroll bar size
|
|
9
12
|
const scrollbarSize = 16;
|
|
10
13
|
// Selected class name
|
|
@@ -68,24 +71,6 @@ const defaultMargin = (margin, horizon) => {
|
|
|
68
71
|
marginBottom: half
|
|
69
72
|
};
|
|
70
73
|
};
|
|
71
|
-
// Default itemRenderer
|
|
72
|
-
function defaultItemRenderer({ index, innerItemRenderer, data, onMouseDown, selected, style, itemHeight, onClick, onDoubleClick, space, margins }) {
|
|
73
|
-
// Child
|
|
74
|
-
const child = innerItemRenderer({
|
|
75
|
-
index,
|
|
76
|
-
data,
|
|
77
|
-
style,
|
|
78
|
-
selected,
|
|
79
|
-
itemHeight,
|
|
80
|
-
space,
|
|
81
|
-
margins
|
|
82
|
-
});
|
|
83
|
-
let rowClass = `ScrollerListEx-Row${index % 2}`;
|
|
84
|
-
if (selected)
|
|
85
|
-
rowClass += ` ${selectedClassName}`;
|
|
86
|
-
// Layout
|
|
87
|
-
return (_jsx("div", { className: rowClass, style: style, onMouseDown: (event) => onMouseDown(event.currentTarget, data), onClick: (event) => onClick && onClick(event, data), onDoubleClick: (event) => onDoubleClick && onDoubleClick(event, data), children: child }));
|
|
88
|
-
}
|
|
89
74
|
/**
|
|
90
75
|
* Extended ScrollerList
|
|
91
76
|
* @param props Props
|
|
@@ -113,20 +98,12 @@ export function ScrollerListEx(props) {
|
|
|
113
98
|
return selected;
|
|
114
99
|
};
|
|
115
100
|
// Destruct
|
|
116
|
-
const { alternatingColors = [undefined, undefined], className, idField = "id",
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
onClick,
|
|
123
|
-
onDoubleClick,
|
|
124
|
-
space,
|
|
125
|
-
margins,
|
|
126
|
-
selected: isSelected(itemProps.data),
|
|
127
|
-
...itemProps
|
|
128
|
-
});
|
|
129
|
-
}, onClick, onDoubleClick, onSelectChange, selectedColor = "#edf4fb", ...rest } = props;
|
|
101
|
+
const { alternatingColors = [undefined, undefined], className, cacheKey, cacheMinutes = 15, idField = "id", itemSize, itemRenderer = ({ data, itemHeight, margins }) => (_jsx(Box, { component: "pre", sx: {
|
|
102
|
+
height: itemHeight,
|
|
103
|
+
...margins
|
|
104
|
+
}, children: JSON.stringify(data) })), onClick, onDoubleClick, onUpdateRows, onSelectChange, selectedColor = "#edf4fb", ...rest } = props;
|
|
105
|
+
// Init handler
|
|
106
|
+
const initHandler = useListCacheInitLoad(cacheKey, cacheMinutes);
|
|
130
107
|
// Theme
|
|
131
108
|
const theme = useTheme();
|
|
132
109
|
// Cache calculation
|
|
@@ -150,11 +127,31 @@ export function ScrollerListEx(props) {
|
|
|
150
127
|
// Calculation
|
|
151
128
|
return itemSizeResult;
|
|
152
129
|
};
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
};
|
|
130
|
+
const onUpdateRowsHandler = React.useCallback((rows, state) => {
|
|
131
|
+
GridUtils.getUpdateRowsHandler(cacheKey)?.(rows, state);
|
|
132
|
+
onUpdateRows?.(rows, state);
|
|
133
|
+
}, [onUpdateRows, cacheKey]);
|
|
158
134
|
// Layout
|
|
159
|
-
return (_jsx(ScrollerList, { className: Utils.mergeClasses("ScrollerListEx-Body", className, createGridStyle(alternatingColors, selectedColor)), idField: idField,
|
|
135
|
+
return (_jsx(ScrollerList, { className: Utils.mergeClasses("ScrollerListEx-Body", className, createGridStyle(alternatingColors, selectedColor)), idField: idField, onRowsRendered: cacheKey
|
|
136
|
+
? (visibleRows) => sessionStorage.setItem(`${cacheKey}-scroll`, JSON.stringify(visibleRows))
|
|
137
|
+
: undefined, onInitLoad: initHandler, onUpdateRows: onUpdateRowsHandler, rowComponent: ({ index, items, style }) => {
|
|
138
|
+
const data = items[index];
|
|
139
|
+
const selected = isSelected(data);
|
|
140
|
+
const rowClass = `ScrollerListEx-Row${index % 2}${selected ? ` ${selectedClassName}` : ""}`;
|
|
141
|
+
const [itemHeight, space, margins] = calculateItemSize(index);
|
|
142
|
+
// Child
|
|
143
|
+
const child = itemRenderer({
|
|
144
|
+
index,
|
|
145
|
+
data,
|
|
146
|
+
style,
|
|
147
|
+
selected,
|
|
148
|
+
itemHeight,
|
|
149
|
+
space,
|
|
150
|
+
margins
|
|
151
|
+
});
|
|
152
|
+
return (_jsx("div", { className: rowClass, style: style, onMouseDown: (event) => onMouseDown(event.currentTarget, data), onClick: (event) => onClick && onClick(event, data), onDoubleClick: (event) => onDoubleClick && onDoubleClick(event, data), children: child }));
|
|
153
|
+
}, rowHeight: (index) => {
|
|
154
|
+
const [size, space] = calculateItemSize(index);
|
|
155
|
+
return size + space;
|
|
156
|
+
}, ...rest }));
|
|
160
157
|
}
|
package/lib/mjs/TableEx.d.ts
CHANGED
|
@@ -43,6 +43,13 @@ export type TableExProps<T extends object, D extends DataTypes.Keys<T>> = TableP
|
|
|
43
43
|
* Methods
|
|
44
44
|
*/
|
|
45
45
|
mRef?: React.Ref<TableExMethodRef<T>>;
|
|
46
|
+
/**
|
|
47
|
+
* Data change handler
|
|
48
|
+
* @param rows Rows
|
|
49
|
+
* @param rowIndex Row index
|
|
50
|
+
* @param columnIndex Column index
|
|
51
|
+
*/
|
|
52
|
+
onDataChange?: (rows: T[], rowIndex: number, columnIndex: number) => void;
|
|
46
53
|
/**
|
|
47
54
|
* On items select change
|
|
48
55
|
*/
|
package/lib/mjs/TableEx.js
CHANGED
|
@@ -27,7 +27,7 @@ export function TableEx(props) {
|
|
|
27
27
|
// Theme
|
|
28
28
|
const theme = useTheme();
|
|
29
29
|
// Destruct
|
|
30
|
-
const { alternatingColors = [theme.palette.action.hover, undefined], autoLoad = true, columns, defaultOrderBy, headerColors = [undefined, undefined], idField = "id", loadBatchSize, loadData, maxHeight, mRef, onSelectChange, rowHeight = 53, otherHeight = 110, threshold, ...rest } = props;
|
|
30
|
+
const { alternatingColors = [theme.palette.action.hover, undefined], autoLoad = true, columns, defaultOrderBy, headerColors = [undefined, undefined], idField = "id", loadBatchSize, loadData, maxHeight, mRef, onDataChange, onSelectChange, rowHeight = 53, otherHeight = 110, threshold, ...rest } = props;
|
|
31
31
|
const selectable = onSelectChange != null;
|
|
32
32
|
// Rows per page
|
|
33
33
|
let rowsPerPageLocal;
|
|
@@ -83,6 +83,9 @@ export function TableEx(props) {
|
|
|
83
83
|
});
|
|
84
84
|
};
|
|
85
85
|
React.useImperativeHandle(mRef, () => ({
|
|
86
|
+
get element() {
|
|
87
|
+
return null;
|
|
88
|
+
},
|
|
86
89
|
delete(index) {
|
|
87
90
|
const item = rows.at(index);
|
|
88
91
|
if (item) {
|
|
@@ -97,20 +100,11 @@ export function TableEx(props) {
|
|
|
97
100
|
newRows.splice(start, 0, item);
|
|
98
101
|
setRows(newRows);
|
|
99
102
|
},
|
|
100
|
-
/**
|
|
101
|
-
* Refresh data
|
|
102
|
-
*/
|
|
103
103
|
refresh() {
|
|
104
104
|
loadDataLocal();
|
|
105
105
|
},
|
|
106
|
-
/**
|
|
107
|
-
* Reset
|
|
108
|
-
*/
|
|
109
106
|
reset,
|
|
110
|
-
|
|
111
|
-
// Not implemented
|
|
112
|
-
},
|
|
113
|
-
scrollToItemRef(index) {
|
|
107
|
+
scrollToRow(param) {
|
|
114
108
|
// Not implemented
|
|
115
109
|
}
|
|
116
110
|
}), []);
|
|
@@ -284,7 +278,7 @@ export function TableEx(props) {
|
|
|
284
278
|
rowIndex,
|
|
285
279
|
columnIndex,
|
|
286
280
|
cellProps,
|
|
287
|
-
|
|
281
|
+
triggerChange: () => onDataChange?.(rows, rowIndex, columnIndex)
|
|
288
282
|
})) : (_jsx(React.Fragment, { children: "\u00A0" }));
|
|
289
283
|
return (_jsx(TableCell, { ...cellProps, children: child }, `${rowId}${columnIndex}`));
|
|
290
284
|
})] }, rowId));
|
|
@@ -27,9 +27,10 @@ export function DataGridPage(props) {
|
|
|
27
27
|
if (ref == null)
|
|
28
28
|
return;
|
|
29
29
|
states.ref = ref;
|
|
30
|
+
if (ref.element)
|
|
31
|
+
setStates({ element: ref.element });
|
|
30
32
|
//setStates({ ref });
|
|
31
33
|
});
|
|
32
|
-
const initLoadedRef = React.useRef(null);
|
|
33
34
|
// On submit callback
|
|
34
35
|
const onSubmit = (data, _reset) => {
|
|
35
36
|
setStates({ data });
|
|
@@ -39,33 +40,6 @@ export function DataGridPage(props) {
|
|
|
39
40
|
};
|
|
40
41
|
// Search data
|
|
41
42
|
const searchData = useSearchParamsWithCache(cacheKey);
|
|
42
|
-
const onInitLoad = (ref) => {
|
|
43
|
-
// Avoid repeatedly load from cache
|
|
44
|
-
if (initLoadedRef.current || !cacheKey)
|
|
45
|
-
return undefined;
|
|
46
|
-
// Cache data
|
|
47
|
-
const cacheData = GridUtils.getCacheData(cacheKey, cacheMinutes);
|
|
48
|
-
if (cacheData) {
|
|
49
|
-
const { rows, state } = cacheData;
|
|
50
|
-
GridUtils.mergeSearchData(state, searchData);
|
|
51
|
-
// Scroll position
|
|
52
|
-
const scrollData = sessionStorage.getItem(`${cacheKey}-scroll`);
|
|
53
|
-
if (scrollData) {
|
|
54
|
-
const { scrollLeft, scrollTop } = JSON.parse(scrollData);
|
|
55
|
-
globalThis.setTimeout(() => ref.scrollTo({ scrollLeft, scrollTop }), 0);
|
|
56
|
-
}
|
|
57
|
-
// Update flag value
|
|
58
|
-
initLoadedRef.current = true;
|
|
59
|
-
// Return cached rows and state
|
|
60
|
-
return [rows, state];
|
|
61
|
-
}
|
|
62
|
-
return undefined;
|
|
63
|
-
};
|
|
64
|
-
const onGridScroll = (props) => {
|
|
65
|
-
if (!cacheKey || !initLoadedRef.current)
|
|
66
|
-
return;
|
|
67
|
-
sessionStorage.setItem(`${cacheKey}-scroll`, JSON.stringify(props));
|
|
68
|
-
};
|
|
69
43
|
// Watch container
|
|
70
44
|
const { dimensions } = useDimensions(1, undefined, sizeReadyMiliseconds);
|
|
71
45
|
const rect = dimensions[0][2];
|
|
@@ -90,10 +64,7 @@ export function DataGridPage(props) {
|
|
|
90
64
|
const gridHeight = states.height;
|
|
91
65
|
if (gridHeight == null)
|
|
92
66
|
return;
|
|
93
|
-
return (_jsx(DataGridEx, { autoLoad: false, height: gridHeight, loadData: localLoadData, mRef: refs,
|
|
94
|
-
if (element != null)
|
|
95
|
-
setStates({ element });
|
|
96
|
-
}, ...rest }));
|
|
67
|
+
return (_jsx(DataGridEx, { autoLoad: false, height: gridHeight, loadData: localLoadData, mRef: refs, ...rest }));
|
|
97
68
|
}, [states.height]);
|
|
98
69
|
const { ref, data } = states;
|
|
99
70
|
React.useEffect(() => {
|
|
@@ -19,7 +19,6 @@ export function FixedListPage(props) {
|
|
|
19
19
|
pageProps.paddings ??= MUGlobal.pagePaddings;
|
|
20
20
|
// States
|
|
21
21
|
const [states] = React.useState({});
|
|
22
|
-
const initLoadedRef = React.useRef(null);
|
|
23
22
|
// Scroll container
|
|
24
23
|
const [scrollContainer, updateScrollContainer] = React.useState();
|
|
25
24
|
const refs = useCombinedRefs(mRef, (ref) => {
|
|
@@ -27,6 +26,8 @@ export function FixedListPage(props) {
|
|
|
27
26
|
return;
|
|
28
27
|
const first = states.ref == null;
|
|
29
28
|
states.ref = ref;
|
|
29
|
+
if (ref.element)
|
|
30
|
+
updateScrollContainer(ref.element);
|
|
30
31
|
if (first)
|
|
31
32
|
reset();
|
|
32
33
|
});
|
|
@@ -43,35 +44,6 @@ export function FixedListPage(props) {
|
|
|
43
44
|
const localLoadData = (props, lastItem) => {
|
|
44
45
|
return loadData(GridUtils.createLoader(props, fieldTemplate, cacheKey, false), lastItem);
|
|
45
46
|
};
|
|
46
|
-
// Search data
|
|
47
|
-
const searchData = useSearchParamsWithCache(cacheKey);
|
|
48
|
-
const onInitLoad = (ref) => {
|
|
49
|
-
// Avoid repeatedly load from cache
|
|
50
|
-
if (initLoadedRef.current || !cacheKey)
|
|
51
|
-
return undefined;
|
|
52
|
-
// Cache data
|
|
53
|
-
const cacheData = GridUtils.getCacheData(cacheKey, cacheMinutes);
|
|
54
|
-
if (cacheData) {
|
|
55
|
-
const { rows, state } = cacheData;
|
|
56
|
-
GridUtils.mergeSearchData(state, searchData);
|
|
57
|
-
// Scroll position
|
|
58
|
-
const scrollData = sessionStorage.getItem(`${cacheKey}-scroll`);
|
|
59
|
-
if (scrollData) {
|
|
60
|
-
const { scrollOffset } = JSON.parse(scrollData);
|
|
61
|
-
globalThis.setTimeout(() => ref.scrollTo(scrollOffset), 0);
|
|
62
|
-
}
|
|
63
|
-
// Update flag value
|
|
64
|
-
initLoadedRef.current = true;
|
|
65
|
-
// Return cached rows and state
|
|
66
|
-
return [rows, state];
|
|
67
|
-
}
|
|
68
|
-
return undefined;
|
|
69
|
-
};
|
|
70
|
-
const onListScroll = (props) => {
|
|
71
|
-
if (!cacheKey || !initLoadedRef.current)
|
|
72
|
-
return;
|
|
73
|
-
sessionStorage.setItem(`${cacheKey}-scroll`, JSON.stringify(props));
|
|
74
|
-
};
|
|
75
47
|
// Watch container
|
|
76
48
|
const { dimensions } = useDimensions(1, undefined, sizeReadyMiliseconds);
|
|
77
49
|
const rect = dimensions[0][2];
|
|
@@ -86,12 +58,11 @@ export function FixedListPage(props) {
|
|
|
86
58
|
: adjustHeight(height, rect);
|
|
87
59
|
return (_jsx(Box, { id: "list-container", sx: {
|
|
88
60
|
height: height + "px"
|
|
89
|
-
}, children: _jsx(ScrollerListEx, { autoLoad: false, height: height, loadData: localLoadData, mRef: refs,
|
|
90
|
-
if (element != null)
|
|
91
|
-
updateScrollContainer(element);
|
|
92
|
-
}, ...rest }) }));
|
|
61
|
+
}, children: _jsx(ScrollerListEx, { autoLoad: false, height: height, loadData: localLoadData, mRef: refs, ...rest }) }));
|
|
93
62
|
}
|
|
94
63
|
}, [rect]);
|
|
64
|
+
// Search data
|
|
65
|
+
const searchData = useSearchParamsWithCache(cacheKey);
|
|
95
66
|
const f = typeof fields == "function" ? fields(searchData ?? {}) : fields;
|
|
96
67
|
const { paddings, ...pageRest } = pageProps;
|
|
97
68
|
// Layout
|
|
@@ -27,7 +27,6 @@ export function ListPage(props) {
|
|
|
27
27
|
if (first)
|
|
28
28
|
reset();
|
|
29
29
|
});
|
|
30
|
-
const initLoadedRef = React.useRef(null);
|
|
31
30
|
const reset = () => {
|
|
32
31
|
if (states.data == null || states.ref == null)
|
|
33
32
|
return;
|
|
@@ -46,36 +45,9 @@ export function ListPage(props) {
|
|
|
46
45
|
const rect = dimensions[0][2];
|
|
47
46
|
// Search data
|
|
48
47
|
const searchData = useSearchParamsWithCache(cacheKey);
|
|
49
|
-
const onInitLoad = (ref) => {
|
|
50
|
-
// Avoid repeatedly load from cache
|
|
51
|
-
if (initLoadedRef.current || !cacheKey)
|
|
52
|
-
return undefined;
|
|
53
|
-
// Cache data
|
|
54
|
-
const cacheData = GridUtils.getCacheData(cacheKey, cacheMinutes);
|
|
55
|
-
if (cacheData) {
|
|
56
|
-
const { rows, state } = cacheData;
|
|
57
|
-
GridUtils.mergeSearchData(state, searchData);
|
|
58
|
-
// Scroll position
|
|
59
|
-
const scrollData = sessionStorage.getItem(`${cacheKey}-scroll`);
|
|
60
|
-
if (scrollData) {
|
|
61
|
-
const { scrollOffset } = JSON.parse(scrollData);
|
|
62
|
-
globalThis.setTimeout(() => ref.scrollTo(scrollOffset), 0);
|
|
63
|
-
}
|
|
64
|
-
// Update flag value
|
|
65
|
-
initLoadedRef.current = true;
|
|
66
|
-
// Return cached rows and state
|
|
67
|
-
return [rows, state];
|
|
68
|
-
}
|
|
69
|
-
return undefined;
|
|
70
|
-
};
|
|
71
|
-
const onListScroll = (props) => {
|
|
72
|
-
if (!cacheKey || !initLoadedRef.current)
|
|
73
|
-
return;
|
|
74
|
-
sessionStorage.setItem(`${cacheKey}-scroll`, JSON.stringify(props));
|
|
75
|
-
};
|
|
76
48
|
const f = typeof fields == "function" ? fields(searchData ?? {}) : fields;
|
|
77
49
|
// Layout
|
|
78
50
|
return (_jsx(CommonPage, { ...pageProps, scrollContainer: globalThis, children: _jsxs(Stack, { children: [_jsx(Box, { ref: dimensions[0][0], sx: {
|
|
79
51
|
paddingBottom: pageProps.paddings
|
|
80
|
-
}, children: rect && rect.width > 100 && (_jsx(SearchBar, { fields: f, onSubmit: onSubmit, top: searchBarTop, width: rect.width })) }), _jsx(ScrollerListEx, { autoLoad: false, loadData: localLoadData,
|
|
52
|
+
}, children: rect && rect.width > 100 && (_jsx(SearchBar, { fields: f, onSubmit: onSubmit, top: searchBarTop, width: rect.width })) }), _jsx(ScrollerListEx, { autoLoad: false, loadData: localLoadData, mRef: refs, ...rest })] }) }));
|
|
81
53
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { DataGridPageProps } from "./DataGridPageProps";
|
|
3
|
-
import type {
|
|
4
|
-
import { ListChildComponentProps } from "react-window";
|
|
3
|
+
import type { ScrollerListExItemSize, ScrollerListExProps } from "../ScrollerListEx";
|
|
5
4
|
import { GridMethodRef } from "@etsoo/react";
|
|
6
5
|
import type { OperationMessageHandlerAll } from "../messages/OperationMessageHandler";
|
|
7
6
|
/**
|
|
@@ -19,14 +18,10 @@ export type ResponsePageProps<T extends object, F> = DataGridPageProps<T, F> & {
|
|
|
19
18
|
* Min width to show Datagrid
|
|
20
19
|
*/
|
|
21
20
|
dataGridMinWidth?: number;
|
|
22
|
-
/**
|
|
23
|
-
* Inner item renderer
|
|
24
|
-
*/
|
|
25
|
-
innerItemRenderer: (props: ScrollerListExInnerItemRendererProps<T>) => React.ReactNode;
|
|
26
21
|
/**
|
|
27
22
|
* Item renderer
|
|
28
23
|
*/
|
|
29
|
-
itemRenderer?:
|
|
24
|
+
itemRenderer?: ScrollerListExProps<T>["itemRenderer"];
|
|
30
25
|
/**
|
|
31
26
|
* Item size, a function indicates its a variable size list
|
|
32
27
|
*/
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useSearchParamsWithCache } from "@etsoo/react";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { GridUtils } from "../GridUtils";
|
|
4
|
+
import { ExtendUtils } from "@etsoo/shared";
|
|
5
|
+
export function useGridCacheInitLoad(cacheKey, cacheMinutes) {
|
|
6
|
+
// Reference
|
|
7
|
+
const ref = React.useRef(null);
|
|
8
|
+
// Search data
|
|
9
|
+
const searchData = useSearchParamsWithCache(cacheKey);
|
|
10
|
+
// Avoid repeatedly load from cache
|
|
11
|
+
if (ref.current || !cacheKey)
|
|
12
|
+
return undefined;
|
|
13
|
+
// Cache data
|
|
14
|
+
const cacheData = GridUtils.getCacheData(cacheKey, cacheMinutes);
|
|
15
|
+
if (cacheData) {
|
|
16
|
+
const { rows, state } = cacheData;
|
|
17
|
+
GridUtils.mergeSearchData(state, searchData);
|
|
18
|
+
// Update flag value
|
|
19
|
+
ref.current = true;
|
|
20
|
+
return (ref) => {
|
|
21
|
+
// Scroll position
|
|
22
|
+
const scrollData = sessionStorage.getItem(`${cacheKey}-scroll`);
|
|
23
|
+
if (scrollData) {
|
|
24
|
+
const data = JSON.parse(scrollData);
|
|
25
|
+
ExtendUtils.waitFor(() => ref.scrollToCell({
|
|
26
|
+
rowIndex: data.rowStartIndex,
|
|
27
|
+
columnIndex: data.columnStartIndex
|
|
28
|
+
}), 100);
|
|
29
|
+
}
|
|
30
|
+
// Return cached rows and state
|
|
31
|
+
return [rows, state];
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useSearchParamsWithCache } from "@etsoo/react";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { GridUtils } from "../GridUtils";
|
|
4
|
+
import { ExtendUtils } from "@etsoo/shared";
|
|
5
|
+
export function useListCacheInitLoad(cacheKey, cacheMinutes) {
|
|
6
|
+
// Reference
|
|
7
|
+
const ref = React.useRef(null);
|
|
8
|
+
// Search data
|
|
9
|
+
const searchData = useSearchParamsWithCache(cacheKey);
|
|
10
|
+
// Avoid repeatedly load from cache
|
|
11
|
+
if (ref.current || !cacheKey)
|
|
12
|
+
return undefined;
|
|
13
|
+
// Cache data
|
|
14
|
+
const cacheData = GridUtils.getCacheData(cacheKey, cacheMinutes);
|
|
15
|
+
if (cacheData) {
|
|
16
|
+
const { rows, state } = cacheData;
|
|
17
|
+
GridUtils.mergeSearchData(state, searchData);
|
|
18
|
+
// Update flag value
|
|
19
|
+
ref.current = true;
|
|
20
|
+
return (ref) => {
|
|
21
|
+
// Scroll position
|
|
22
|
+
const scrollData = sessionStorage.getItem(`${cacheKey}-scroll`);
|
|
23
|
+
if (scrollData) {
|
|
24
|
+
const data = JSON.parse(scrollData);
|
|
25
|
+
ExtendUtils.waitFor(() => ref.scrollToRow({ index: data.startIndex }), 100);
|
|
26
|
+
}
|
|
27
|
+
// Return cached rows and state
|
|
28
|
+
return [rows, state];
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|