@etsoo/react 1.4.19 → 1.4.23
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/lib/components/GridLoader.d.ts +6 -2
- package/lib/components/ScrollerGrid.d.ts +1 -1
- package/lib/components/ScrollerGrid.js +50 -43
- package/lib/components/ScrollerList.js +30 -32
- package/lib/mu/DataGridEx.d.ts +1 -1
- package/lib/mu/DataGridEx.js +23 -49
- package/lib/mu/DataGridRenderers.d.ts +4 -2
- package/lib/mu/DataGridRenderers.js +9 -7
- package/lib/mu/GridMethodRef.d.ts +2 -1
- package/lib/mu/ResponsibleContainer.d.ts +16 -0
- package/lib/mu/ResponsibleContainer.js +94 -40
- package/lib/mu/ScrollerListEx.js +1 -2
- package/lib/mu/SearchBar.js +3 -3
- package/lib/mu/TableEx.js +27 -25
- package/lib/mu/pages/CommonPage.d.ts +1 -2
- package/lib/uses/useDimensions.js +0 -8
- package/package.json +9 -9
- package/src/components/GridLoader.ts +7 -2
- package/src/components/ScrollerGrid.tsx +69 -63
- package/src/components/ScrollerList.tsx +44 -48
- package/src/mu/DataGridEx.tsx +51 -91
- package/src/mu/DataGridRenderers.tsx +14 -12
- package/src/mu/GridMethodRef.ts +3 -1
- package/src/mu/ResponsibleContainer.tsx +141 -47
- package/src/mu/ScrollerListEx.tsx +1 -2
- package/src/mu/SearchBar.tsx +3 -3
- package/src/mu/TableEx.tsx +40 -46
- package/src/uses/useDimensions.ts +0 -11
|
@@ -88,6 +88,10 @@ export interface GridLoaderStates<T> extends GridLoadDataProps {
|
|
|
88
88
|
* Last loaded items
|
|
89
89
|
*/
|
|
90
90
|
lastLoadedItems?: number;
|
|
91
|
+
/**
|
|
92
|
+
* All loaded items count
|
|
93
|
+
*/
|
|
94
|
+
loadedItems: number;
|
|
91
95
|
/**
|
|
92
96
|
* Has next page?
|
|
93
97
|
*/
|
|
@@ -97,9 +101,9 @@ export interface GridLoaderStates<T> extends GridLoadDataProps {
|
|
|
97
101
|
*/
|
|
98
102
|
isNextPageLoading: boolean;
|
|
99
103
|
/**
|
|
100
|
-
*
|
|
104
|
+
* Is mounted
|
|
101
105
|
*/
|
|
102
|
-
|
|
106
|
+
isMounted?: boolean;
|
|
103
107
|
/**
|
|
104
108
|
* Selected items of id
|
|
105
109
|
*/
|
|
@@ -24,7 +24,7 @@ export interface ScrollerGridProps<T> extends GridLoader<T>, Omit<VariableSizeGr
|
|
|
24
24
|
/**
|
|
25
25
|
* Footer renderer
|
|
26
26
|
*/
|
|
27
|
-
footerRenderer?: (states: GridLoaderStates<T>) => React.ReactNode;
|
|
27
|
+
footerRenderer?: (rows: T[], states: GridLoaderStates<T>) => React.ReactNode;
|
|
28
28
|
/**
|
|
29
29
|
* Header renderer
|
|
30
30
|
*/
|
|
@@ -8,22 +8,26 @@ import { VariableSizeGrid } from 'react-window';
|
|
|
8
8
|
export const ScrollerGrid = (props) => {
|
|
9
9
|
// Destruct
|
|
10
10
|
const { autoLoad = true, defaultOrderBy, defaultOrderByAsc, footerRenderer, headerRenderer, itemRenderer, idField = 'id', loadBatchSize, loadData, mRef, onItemsRendered, onSelectChange, rowHeight = 53, threshold = 6, width, ...rest } = props;
|
|
11
|
-
//
|
|
12
|
-
const [
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
// Rows
|
|
12
|
+
const [rows, updateRows] = React.useState([]);
|
|
13
|
+
const setRows = (rows) => {
|
|
14
|
+
state.loadedItems = rows.length;
|
|
15
|
+
updateRows(rows);
|
|
16
|
+
};
|
|
17
|
+
// Refs
|
|
18
|
+
const refs = React.useRef({
|
|
15
19
|
autoLoad,
|
|
16
20
|
currentPage: 0,
|
|
17
21
|
hasNextPage: true,
|
|
18
22
|
isNextPageLoading: false,
|
|
19
23
|
orderBy: defaultOrderBy,
|
|
20
24
|
orderByAsc: defaultOrderByAsc,
|
|
21
|
-
rows: [],
|
|
22
25
|
batchSize: 10,
|
|
26
|
+
loadedItems: 0,
|
|
23
27
|
selectedItems: []
|
|
24
28
|
});
|
|
25
|
-
const
|
|
26
|
-
const ref = React.
|
|
29
|
+
const state = refs.current;
|
|
30
|
+
const ref = React.useRef(null);
|
|
27
31
|
// Load data
|
|
28
32
|
const loadDataLocal = (pageAdd = 1) => {
|
|
29
33
|
// Prevent multiple loadings
|
|
@@ -31,9 +35,8 @@ export const ScrollerGrid = (props) => {
|
|
|
31
35
|
return;
|
|
32
36
|
// Update state
|
|
33
37
|
state.isNextPageLoading = true;
|
|
34
|
-
// stateUpdate({ isNextPageLoading: true });
|
|
35
38
|
// Parameters
|
|
36
|
-
const { currentPage, batchSize, orderBy, orderByAsc, data } = state;
|
|
39
|
+
const { currentPage, batchSize, orderBy, orderByAsc, data, isMounted } = state;
|
|
37
40
|
const loadProps = {
|
|
38
41
|
currentPage,
|
|
39
42
|
batchSize,
|
|
@@ -42,41 +45,37 @@ export const ScrollerGrid = (props) => {
|
|
|
42
45
|
data
|
|
43
46
|
};
|
|
44
47
|
loadData(loadProps).then((result) => {
|
|
45
|
-
|
|
48
|
+
state.isMounted = true;
|
|
49
|
+
if (result == null || isMounted === false) {
|
|
46
50
|
return;
|
|
47
51
|
}
|
|
48
52
|
const newItems = result.length;
|
|
53
|
+
state.lastLoadedItems = newItems;
|
|
54
|
+
state.isNextPageLoading = false;
|
|
55
|
+
state.hasNextPage = newItems >= batchSize;
|
|
49
56
|
if (pageAdd === 0) {
|
|
50
57
|
// New items
|
|
51
|
-
const
|
|
52
|
-
?
|
|
53
|
-
.splice(
|
|
58
|
+
const newRows = state.lastLoadedItems
|
|
59
|
+
? [...rows]
|
|
60
|
+
.splice(rows.length - state.lastLoadedItems, state.lastLoadedItems)
|
|
54
61
|
.concat(result)
|
|
55
62
|
: result;
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
rows,
|
|
59
|
-
lastLoadedItems: newItems,
|
|
60
|
-
isNextPageLoading: false,
|
|
61
|
-
hasNextPage: newItems >= batchSize
|
|
62
|
-
});
|
|
63
|
+
// Update rows
|
|
64
|
+
setRows(newRows);
|
|
63
65
|
}
|
|
64
66
|
else {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
currentPage: state.currentPage + pageAdd,
|
|
70
|
-
hasNextPage: newItems >= batchSize
|
|
71
|
-
});
|
|
67
|
+
// Set current page
|
|
68
|
+
state.currentPage = state.currentPage + pageAdd;
|
|
69
|
+
// Update rows
|
|
70
|
+
setRows([...rows, ...result]);
|
|
72
71
|
}
|
|
73
72
|
});
|
|
74
73
|
};
|
|
75
74
|
// Item renderer
|
|
76
75
|
const itemRendererLocal = (itemProps, state) => {
|
|
77
76
|
// Custom render
|
|
78
|
-
const data = itemProps.rowIndex <
|
|
79
|
-
?
|
|
77
|
+
const data = itemProps.rowIndex < rows.length
|
|
78
|
+
? rows[itemProps.rowIndex]
|
|
80
79
|
: undefined;
|
|
81
80
|
return itemRenderer({
|
|
82
81
|
...itemProps,
|
|
@@ -87,7 +86,7 @@ export const ScrollerGrid = (props) => {
|
|
|
87
86
|
// Local items renderer callback
|
|
88
87
|
const onItemsRenderedLocal = (props) => {
|
|
89
88
|
// No items, means no necessary to load more data during reset
|
|
90
|
-
const itemCount =
|
|
89
|
+
const itemCount = rows.length;
|
|
91
90
|
if (itemCount > 0 &&
|
|
92
91
|
props.visibleRowStopIndex + threshold > itemCount) {
|
|
93
92
|
// Auto load next page
|
|
@@ -99,16 +98,18 @@ export const ScrollerGrid = (props) => {
|
|
|
99
98
|
};
|
|
100
99
|
// Reset the state and load again
|
|
101
100
|
const reset = (add) => {
|
|
102
|
-
const
|
|
101
|
+
const resetState = {
|
|
103
102
|
autoLoad: true,
|
|
104
103
|
currentPage: 0,
|
|
104
|
+
loadedItems: 0,
|
|
105
105
|
hasNextPage: true,
|
|
106
106
|
isNextPageLoading: false,
|
|
107
107
|
lastLoadedItems: undefined,
|
|
108
|
-
rows: [],
|
|
109
108
|
...add
|
|
110
109
|
};
|
|
111
|
-
|
|
110
|
+
Object.assign(state, resetState);
|
|
111
|
+
// Reset items
|
|
112
|
+
setRows([]);
|
|
112
113
|
};
|
|
113
114
|
React.useImperativeHandle(mRef, () => ({
|
|
114
115
|
scrollTo(params) {
|
|
@@ -122,14 +123,13 @@ export const ScrollerGrid = (props) => {
|
|
|
122
123
|
select(rowIndex) {
|
|
123
124
|
// Select only one item
|
|
124
125
|
const selectedItems = state.selectedItems;
|
|
125
|
-
selectedItems[0] =
|
|
126
|
+
selectedItems[0] = rows[rowIndex];
|
|
126
127
|
if (onSelectChange)
|
|
127
128
|
onSelectChange(selectedItems);
|
|
128
|
-
stateUpdate({ selectedItems });
|
|
129
129
|
},
|
|
130
130
|
selectAll(checked) {
|
|
131
131
|
const selectedItems = state.selectedItems;
|
|
132
|
-
|
|
132
|
+
rows.forEach((row) => {
|
|
133
133
|
const index = selectedItems.findIndex((selectedItem) => selectedItem[idField] === row[idField]);
|
|
134
134
|
if (checked) {
|
|
135
135
|
if (index === -1)
|
|
@@ -141,7 +141,6 @@ export const ScrollerGrid = (props) => {
|
|
|
141
141
|
});
|
|
142
142
|
if (onSelectChange)
|
|
143
143
|
onSelectChange(selectedItems);
|
|
144
|
-
stateUpdate({ selectedItems });
|
|
145
144
|
},
|
|
146
145
|
selectItem(item, checked) {
|
|
147
146
|
const selectedItems = state.selectedItems;
|
|
@@ -156,7 +155,6 @@ export const ScrollerGrid = (props) => {
|
|
|
156
155
|
}
|
|
157
156
|
if (onSelectChange)
|
|
158
157
|
onSelectChange(selectedItems);
|
|
159
|
-
stateUpdate({ selectedItems });
|
|
160
158
|
},
|
|
161
159
|
reset,
|
|
162
160
|
resetAfterColumnIndex(index, shouldForceUpdate) {
|
|
@@ -171,14 +169,23 @@ export const ScrollerGrid = (props) => {
|
|
|
171
169
|
var _a;
|
|
172
170
|
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.resetAfterRowIndex(index, shouldForceUpdate);
|
|
173
171
|
}
|
|
174
|
-
}), [
|
|
172
|
+
}), [rows]);
|
|
175
173
|
React.useEffect(() => {
|
|
176
174
|
return () => {
|
|
177
|
-
isMounted
|
|
175
|
+
state.isMounted = false;
|
|
178
176
|
};
|
|
179
177
|
}, []);
|
|
178
|
+
// Force update to work with the new width
|
|
179
|
+
React.useEffect(() => {
|
|
180
|
+
var _a;
|
|
181
|
+
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.resetAfterIndices({
|
|
182
|
+
columnIndex: 0,
|
|
183
|
+
rowIndex: 0,
|
|
184
|
+
shouldForceUpdate: true
|
|
185
|
+
});
|
|
186
|
+
}, [width]);
|
|
180
187
|
// Destruct state
|
|
181
|
-
const { autoLoad: stateAutoLoad,
|
|
188
|
+
const { autoLoad: stateAutoLoad, hasNextPage, currentPage } = state;
|
|
182
189
|
const rowLength = rows.length;
|
|
183
190
|
// Row count
|
|
184
191
|
const rowCount = hasNextPage ? rowLength + 1 : rowLength;
|
|
@@ -189,12 +196,12 @@ export const ScrollerGrid = (props) => {
|
|
|
189
196
|
return (React.createElement(React.Fragment, null,
|
|
190
197
|
headerRenderer && headerRenderer(state),
|
|
191
198
|
React.createElement(VariableSizeGrid, { itemKey: ({ columnIndex, rowIndex }) => {
|
|
192
|
-
const data =
|
|
199
|
+
const data = rows[rowIndex];
|
|
193
200
|
if (data == null)
|
|
194
201
|
return [rowIndex, columnIndex].join(',');
|
|
195
202
|
return [data[idField], columnIndex].join(',');
|
|
196
203
|
}, onItemsRendered: onItemsRenderedLocal, ref: ref, rowCount: rowCount, rowHeight: typeof rowHeight === 'function'
|
|
197
204
|
? rowHeight
|
|
198
205
|
: () => rowHeight, style: { overflowX: 'hidden' }, width: width, ...rest }, (props) => itemRendererLocal(props, state)),
|
|
199
|
-
footerRenderer && footerRenderer(state)));
|
|
206
|
+
footerRenderer && footerRenderer(rows, state)));
|
|
200
207
|
};
|
|
@@ -26,21 +26,25 @@ export const ScrollerList = (props) => {
|
|
|
26
26
|
const listRef = React.useRef();
|
|
27
27
|
const outerRef = React.useRef();
|
|
28
28
|
const refs = useCombinedRefs(oRef, outerRef);
|
|
29
|
+
// Rows
|
|
30
|
+
const [rows, updateRows] = React.useState([]);
|
|
31
|
+
const setRows = (rows) => {
|
|
32
|
+
state.loadedItems = rows.length;
|
|
33
|
+
updateRows(rows);
|
|
34
|
+
};
|
|
29
35
|
// States
|
|
30
|
-
const
|
|
31
|
-
return { ...currentState, ...newState };
|
|
32
|
-
}, {
|
|
36
|
+
const stateRefs = React.useRef({
|
|
33
37
|
autoLoad,
|
|
34
38
|
currentPage: 0,
|
|
39
|
+
loadedItems: 0,
|
|
35
40
|
hasNextPage: true,
|
|
36
41
|
isNextPageLoading: false,
|
|
37
42
|
orderBy: defaultOrderBy,
|
|
38
43
|
orderByAsc: defaultOrderByAsc,
|
|
39
|
-
rows: [],
|
|
40
44
|
batchSize: GridSizeGet(loadBatchSize, height),
|
|
41
45
|
selectedItems: []
|
|
42
46
|
});
|
|
43
|
-
const
|
|
47
|
+
const state = stateRefs.current;
|
|
44
48
|
// Load data
|
|
45
49
|
const loadDataLocal = (pageAdd = 1) => {
|
|
46
50
|
// Prevent multiple loadings
|
|
@@ -48,9 +52,8 @@ export const ScrollerList = (props) => {
|
|
|
48
52
|
return;
|
|
49
53
|
// Update state
|
|
50
54
|
state.isNextPageLoading = true;
|
|
51
|
-
// stateUpdate({ isNextPageLoading: true });
|
|
52
55
|
// Parameters
|
|
53
|
-
const { currentPage, batchSize, orderBy, orderByAsc, data } = state;
|
|
56
|
+
const { currentPage, batchSize, orderBy, orderByAsc, data, isMounted } = state;
|
|
54
57
|
const loadProps = {
|
|
55
58
|
currentPage,
|
|
56
59
|
batchSize,
|
|
@@ -59,33 +62,28 @@ export const ScrollerList = (props) => {
|
|
|
59
62
|
data
|
|
60
63
|
};
|
|
61
64
|
loadData(loadProps).then((result) => {
|
|
62
|
-
|
|
65
|
+
state.isMounted = true;
|
|
66
|
+
if (result == null || isMounted === false) {
|
|
63
67
|
return;
|
|
64
68
|
}
|
|
65
69
|
const newItems = result.length;
|
|
70
|
+
state.lastLoadedItems = newItems;
|
|
71
|
+
state.hasNextPage = newItems >= loadBatchSize;
|
|
72
|
+
state.isNextPageLoading = false;
|
|
66
73
|
if (pageAdd === 0) {
|
|
67
74
|
// New items
|
|
68
|
-
const
|
|
69
|
-
?
|
|
70
|
-
.splice(
|
|
75
|
+
const newRows = state.lastLoadedItems
|
|
76
|
+
? [...rows]
|
|
77
|
+
.splice(rows.length - state.lastLoadedItems, state.lastLoadedItems)
|
|
71
78
|
.concat(result)
|
|
72
79
|
: result;
|
|
73
|
-
//
|
|
74
|
-
|
|
75
|
-
rows,
|
|
76
|
-
lastLoadedItems: newItems,
|
|
77
|
-
hasNextPage: newItems >= loadBatchSize,
|
|
78
|
-
isNextPageLoading: false
|
|
79
|
-
});
|
|
80
|
+
// Update rows
|
|
81
|
+
setRows(newRows);
|
|
80
82
|
}
|
|
81
83
|
else {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
currentPage: state.currentPage + pageAdd,
|
|
86
|
-
hasNextPage: newItems >= loadBatchSize,
|
|
87
|
-
isNextPageLoading: false
|
|
88
|
-
});
|
|
84
|
+
state.currentPage = state.currentPage + pageAdd;
|
|
85
|
+
// Update rows
|
|
86
|
+
setRows([...rows, ...result]);
|
|
89
87
|
}
|
|
90
88
|
});
|
|
91
89
|
};
|
|
@@ -93,7 +91,7 @@ export const ScrollerList = (props) => {
|
|
|
93
91
|
// Custom render
|
|
94
92
|
return itemRenderer({
|
|
95
93
|
...itemProps,
|
|
96
|
-
data:
|
|
94
|
+
data: rows[itemProps.index]
|
|
97
95
|
});
|
|
98
96
|
};
|
|
99
97
|
// Update scroll location
|
|
@@ -112,16 +110,16 @@ export const ScrollerList = (props) => {
|
|
|
112
110
|
loadDataLocal(0);
|
|
113
111
|
},
|
|
114
112
|
reset(add) {
|
|
115
|
-
|
|
116
|
-
stateUpdate({
|
|
113
|
+
const resetState = {
|
|
117
114
|
autoLoad: true,
|
|
118
|
-
rows: [],
|
|
119
115
|
lastLoadedItems: undefined,
|
|
116
|
+
loadedItems: 0,
|
|
120
117
|
currentPage: 0,
|
|
121
118
|
hasNextPage: true,
|
|
122
119
|
isNextPageLoading: false,
|
|
123
120
|
...add
|
|
124
|
-
}
|
|
121
|
+
};
|
|
122
|
+
Object.assign(state, resetState);
|
|
125
123
|
},
|
|
126
124
|
scrollTo(scrollOffset) {
|
|
127
125
|
refMethods.scrollTo(scrollOffset);
|
|
@@ -157,11 +155,11 @@ export const ScrollerList = (props) => {
|
|
|
157
155
|
window.cancelAnimationFrame(requestAnimationFrameSeed);
|
|
158
156
|
// Remove scroll event
|
|
159
157
|
window.removeEventListener('scroll', handleWindowScroll);
|
|
160
|
-
isMounted
|
|
158
|
+
state.isMounted = false;
|
|
161
159
|
};
|
|
162
160
|
}, []);
|
|
163
161
|
// Destruct state
|
|
164
|
-
const { autoLoad: stateAutoLoad,
|
|
162
|
+
const { autoLoad: stateAutoLoad, hasNextPage, currentPage } = state;
|
|
165
163
|
const rowCount = rows.length;
|
|
166
164
|
// Local items renderer callback
|
|
167
165
|
const onItemsRenderedLocal = (props) => {
|
package/lib/mu/DataGridEx.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ export interface DataGridExProps<T extends Record<string, any>> extends Omit<Scr
|
|
|
40
40
|
/**
|
|
41
41
|
* Footer item renderer
|
|
42
42
|
*/
|
|
43
|
-
footerItemRenderer?: (props: DataGridExFooterItemRendererProps<T>) => React.ReactNode;
|
|
43
|
+
footerItemRenderer?: (rows: T[], props: DataGridExFooterItemRendererProps<T>) => React.ReactNode;
|
|
44
44
|
/**
|
|
45
45
|
* Header height
|
|
46
46
|
* @default 56
|
package/lib/mu/DataGridEx.js
CHANGED
|
@@ -5,8 +5,6 @@ import React from 'react';
|
|
|
5
5
|
import { GridAlignGet } from '../components/GridColumn';
|
|
6
6
|
import { ScrollerGrid } from '../components/ScrollerGrid';
|
|
7
7
|
import useCombinedRefs from '../uses/useCombinedRefs';
|
|
8
|
-
import { useDimensions } from '../uses/useDimensions';
|
|
9
|
-
import { useWindowSize } from '../uses/useWindowSize';
|
|
10
8
|
import { DataGridRenderers } from './DataGridRenderers';
|
|
11
9
|
// Borders
|
|
12
10
|
const boldBorder = '2px solid rgba(224, 224, 224, 1)';
|
|
@@ -107,7 +105,7 @@ export function DataGridEx(props) {
|
|
|
107
105
|
React.createElement(Box, { className: "DataGridEx-Cell", onMouseEnter: handleMouseEnter, ...cellProps }, sortLabel)));
|
|
108
106
|
})));
|
|
109
107
|
};
|
|
110
|
-
function defaultFooterRenderer(states) {
|
|
108
|
+
function defaultFooterRenderer(rows, states) {
|
|
111
109
|
return (React.createElement(Box, { className: "DataGridEx-Footer", display: "flex", alignItems: "center", borderTop: thinBorder, marginTop: "1px", minWidth: widthCalculator.total, height: bottomHeight - 1 }, columns.map((column, index) => {
|
|
112
110
|
// Destruct
|
|
113
111
|
const { align, field, type } = column;
|
|
@@ -115,7 +113,7 @@ export function DataGridEx(props) {
|
|
|
115
113
|
const cellProps = {};
|
|
116
114
|
// Cell
|
|
117
115
|
const cell = footerItemRenderer
|
|
118
|
-
? footerItemRenderer({
|
|
116
|
+
? footerItemRenderer(rows, {
|
|
119
117
|
column,
|
|
120
118
|
index,
|
|
121
119
|
states,
|
|
@@ -141,7 +139,7 @@ export function DataGridEx(props) {
|
|
|
141
139
|
};
|
|
142
140
|
return (React.createElement(Checkbox, { color: "primary", checked: selected, onChange: (_event, checked) => {
|
|
143
141
|
var _a;
|
|
144
|
-
(_a =
|
|
142
|
+
(_a = refs.current.ref) === null || _a === void 0 ? void 0 : _a.selectItem(data, checked);
|
|
145
143
|
} }));
|
|
146
144
|
},
|
|
147
145
|
headerCellRenderer: ({ cellProps, states }) => {
|
|
@@ -151,7 +149,7 @@ export function DataGridEx(props) {
|
|
|
151
149
|
padding: `${hpad}px 4px ${hpad - 1}px 4px!important`
|
|
152
150
|
};
|
|
153
151
|
return (React.createElement(Checkbox, { color: "primary", indeterminate: states.selectedItems.length > 0 &&
|
|
154
|
-
states.selectedItems.length < states.
|
|
152
|
+
states.selectedItems.length < states.loadedItems, checked: states.selectedItems.length > 0, onChange: (_event, checked) => { var _a; return (_a = refs.current.ref) === null || _a === void 0 ? void 0 : _a.selectAll(checked); } }));
|
|
155
153
|
}
|
|
156
154
|
};
|
|
157
155
|
// Update to the latest version
|
|
@@ -162,24 +160,20 @@ export function DataGridEx(props) {
|
|
|
162
160
|
columns.unshift(cbColumn);
|
|
163
161
|
}
|
|
164
162
|
}
|
|
165
|
-
|
|
166
|
-
const
|
|
167
|
-
return { ...currentState, ...newState };
|
|
168
|
-
}, {
|
|
169
|
-
gridWidth: width
|
|
170
|
-
});
|
|
171
|
-
const refs = useCombinedRefs(mRef, (ref) => {
|
|
163
|
+
const refs = React.useRef({});
|
|
164
|
+
const mRefLocal = useCombinedRefs(mRef, (ref) => {
|
|
172
165
|
if (ref == null)
|
|
173
166
|
return;
|
|
174
|
-
|
|
167
|
+
refs.current.ref = ref;
|
|
175
168
|
});
|
|
176
169
|
// New sort
|
|
177
170
|
const handleSort = (field, asc) => {
|
|
178
171
|
reset({ orderBy: field, orderByAsc: asc });
|
|
179
172
|
};
|
|
173
|
+
// Reset
|
|
180
174
|
const reset = (add) => {
|
|
181
175
|
var _a;
|
|
182
|
-
(_a =
|
|
176
|
+
(_a = refs.current.ref) === null || _a === void 0 ? void 0 : _a.reset(add);
|
|
183
177
|
};
|
|
184
178
|
// Show hover tooltip for trucated text
|
|
185
179
|
const handleMouseEnter = (event) => {
|
|
@@ -272,55 +266,35 @@ export function DataGridEx(props) {
|
|
|
272
266
|
};
|
|
273
267
|
// Column width calculator
|
|
274
268
|
const widthCalculator = React.useMemo(() => DataGridExCalColumns(columns), [columns]);
|
|
275
|
-
// Grid width
|
|
276
|
-
const { gridWidth } = state;
|
|
277
269
|
// Column width
|
|
278
270
|
const columnWidth = React.useCallback((index) => {
|
|
279
271
|
// Ignore null case
|
|
280
|
-
if (
|
|
272
|
+
if (width == null)
|
|
281
273
|
return 0;
|
|
282
274
|
// Column
|
|
283
275
|
const column = columns[index];
|
|
284
276
|
if (column.width != null)
|
|
285
277
|
return column.width;
|
|
286
278
|
// More space
|
|
287
|
-
const leftWidth =
|
|
279
|
+
const leftWidth = width -
|
|
288
280
|
widthCalculator.total -
|
|
289
|
-
(
|
|
281
|
+
(width < 800 ? 0 : scrollbarSize);
|
|
290
282
|
// Shared width
|
|
291
283
|
const sharedWidth = leftWidth > 0 ? leftWidth / widthCalculator.unset : 0;
|
|
292
284
|
return (column.minWidth || minWidth) + sharedWidth;
|
|
293
|
-
}, [columns,
|
|
285
|
+
}, [columns, width]);
|
|
294
286
|
// Table
|
|
295
287
|
const table = React.useMemo(() => {
|
|
296
288
|
var _a;
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
}, [gridWidth]);
|
|
307
|
-
// Watch container
|
|
308
|
-
const { dimensions } = useDimensions(1, undefined, 50);
|
|
309
|
-
const gridRect = dimensions[0][2];
|
|
310
|
-
const windowSize = useWindowSize(50);
|
|
311
|
-
React.useEffect(() => {
|
|
312
|
-
if (gridRect == null || width != null)
|
|
313
|
-
return;
|
|
314
|
-
// Reset column widths
|
|
315
|
-
if (state.ref)
|
|
316
|
-
state.ref.resetAfterColumnIndex(0);
|
|
317
|
-
const body = window.document.body;
|
|
318
|
-
const scrollWidth = body.scrollWidth - body.clientWidth;
|
|
319
|
-
stateUpdate({
|
|
320
|
-
gridWidth: gridRect.width - scrollWidth
|
|
321
|
-
});
|
|
322
|
-
}, [gridRect, windowSize]);
|
|
323
|
-
return (React.createElement(Paper, { ref: dimensions[0][0], sx: {
|
|
289
|
+
const defaultOrderByAsc = defaultOrderBy
|
|
290
|
+
? (_a = columns.find((column) => column.field === defaultOrderBy)) === null || _a === void 0 ? void 0 : _a.sortAsc
|
|
291
|
+
: undefined;
|
|
292
|
+
return (React.createElement(ScrollerGrid, { className: Utils.mergeClasses('DataGridEx-Body', 'DataGridEx-CustomBar', className, createGridStyle(alternatingColors, selectedColor, hoverColor)), columnCount: columns.length, columnWidth: columnWidth, defaultOrderBy: defaultOrderBy, defaultOrderByAsc: defaultOrderByAsc, height: height -
|
|
293
|
+
headerHeight -
|
|
294
|
+
(hideFooter ? 0 : bottomHeight + 1) -
|
|
295
|
+
scrollbarSize, headerRenderer: headerRenderer, idField: idField, itemRenderer: itemRenderer, footerRenderer: hideFooter ? undefined : footerRenderer, width: Math.max(width !== null && width !== void 0 ? width : 0, widthCalculator.total), mRef: mRefLocal, ...rest }));
|
|
296
|
+
}, [width]);
|
|
297
|
+
return (React.createElement(Paper, { sx: {
|
|
324
298
|
fontSize: '0.875rem',
|
|
325
299
|
height,
|
|
326
300
|
'& .DataGridEx-Cell': {
|
|
@@ -350,7 +324,7 @@ export function DataGridEx(props) {
|
|
|
350
324
|
}
|
|
351
325
|
} },
|
|
352
326
|
React.createElement("div", { className: "DataGridEx-CustomBar", style: {
|
|
353
|
-
width
|
|
327
|
+
width,
|
|
354
328
|
overflowX: 'auto',
|
|
355
329
|
overflowY: 'hidden'
|
|
356
330
|
} }, table)));
|
|
@@ -13,8 +13,10 @@ export declare namespace DataGridRenderers {
|
|
|
13
13
|
function defaultCellRenderer<T extends Record<string, any>>({ cellProps, data, field, formattedValue, columnIndex, type, renderProps }: GridCellRendererProps<T>): React.ReactNode;
|
|
14
14
|
/**
|
|
15
15
|
* Default footer item renderer
|
|
16
|
-
* @param
|
|
16
|
+
* @param rows Rows
|
|
17
|
+
* @param props Renderer props
|
|
18
|
+
* @param location Renderer location (column index)
|
|
17
19
|
* @returns Component
|
|
18
20
|
*/
|
|
19
|
-
function defaultFooterItemRenderer<T>({ index, states, checkable }: DataGridExFooterItemRendererProps<T
|
|
21
|
+
function defaultFooterItemRenderer<T>(_rows: T[], { index, states, checkable }: DataGridExFooterItemRendererProps<T>, location?: number): string | undefined;
|
|
20
22
|
}
|
|
@@ -75,19 +75,21 @@ export var DataGridRenderers;
|
|
|
75
75
|
DataGridRenderers.defaultCellRenderer = defaultCellRenderer;
|
|
76
76
|
/**
|
|
77
77
|
* Default footer item renderer
|
|
78
|
-
* @param
|
|
78
|
+
* @param rows Rows
|
|
79
|
+
* @param props Renderer props
|
|
80
|
+
* @param location Renderer location (column index)
|
|
79
81
|
* @returns Component
|
|
80
82
|
*/
|
|
81
|
-
function defaultFooterItemRenderer({ index, states, checkable }) {
|
|
82
|
-
const { selectedItems,
|
|
83
|
-
if (checkable && index === 1) {
|
|
83
|
+
function defaultFooterItemRenderer(_rows, { index, states, checkable }, location = 1) {
|
|
84
|
+
const { selectedItems, loadedItems, hasNextPage } = states;
|
|
85
|
+
if (checkable && index === location + 1) {
|
|
84
86
|
return [
|
|
85
87
|
selectedItems.length,
|
|
86
|
-
|
|
88
|
+
loadedItems.toLocaleString() + (hasNextPage ? '+' : '')
|
|
87
89
|
].join(' / ');
|
|
88
90
|
}
|
|
89
|
-
if (!checkable && index ===
|
|
90
|
-
return
|
|
91
|
+
if (!checkable && index === location) {
|
|
92
|
+
return loadedItems.toLocaleString() + (hasNextPage ? '+' : '');
|
|
91
93
|
}
|
|
92
94
|
return undefined;
|
|
93
95
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { GridLoaderStates } from '../components/GridLoader';
|
|
1
2
|
/**
|
|
2
3
|
* Grid method ref
|
|
3
4
|
*/
|
|
@@ -6,5 +7,5 @@ export interface GridMethodRef {
|
|
|
6
7
|
* Reset
|
|
7
8
|
* @param add Additional data
|
|
8
9
|
*/
|
|
9
|
-
reset(add?:
|
|
10
|
+
reset(add?: Partial<GridLoaderStates<unknown>>): void;
|
|
10
11
|
}
|
|
@@ -7,6 +7,9 @@ import { GridJsonData } from '../components/GridLoader';
|
|
|
7
7
|
import { DataGridExProps } from './DataGridEx';
|
|
8
8
|
import { GridMethodRef } from './GridMethodRef';
|
|
9
9
|
import { ScrollerListExInnerItemRendererProps } from './ScrollerListEx';
|
|
10
|
+
/**
|
|
11
|
+
* ResponsibleContainer props
|
|
12
|
+
*/
|
|
10
13
|
export interface ResponsibleContainerProps<T extends {}, F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate> extends Omit<DataGridExProps<T>, 'height' | 'itemKey' | 'loadData' | 'mRef' | 'onScroll' | 'onItemsRendered'> {
|
|
11
14
|
/**
|
|
12
15
|
* Height will be deducted
|
|
@@ -57,6 +60,14 @@ export interface ResponsibleContainerProps<T extends {}, F extends DataTypes.Bas
|
|
|
57
60
|
* Methods
|
|
58
61
|
*/
|
|
59
62
|
mRef?: React.MutableRefObject<GridMethodRef | undefined>;
|
|
63
|
+
/**
|
|
64
|
+
* Paddings
|
|
65
|
+
*/
|
|
66
|
+
paddings?: {};
|
|
67
|
+
/**
|
|
68
|
+
* Pull to refresh data
|
|
69
|
+
*/
|
|
70
|
+
pullToRefresh?: boolean;
|
|
60
71
|
/**
|
|
61
72
|
* Searchbox SX
|
|
62
73
|
*/
|
|
@@ -66,4 +77,9 @@ export interface ResponsibleContainerProps<T extends {}, F extends DataTypes.Bas
|
|
|
66
77
|
*/
|
|
67
78
|
sizeReadyMiliseconds?: number;
|
|
68
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Responsible container
|
|
82
|
+
* @param props Props
|
|
83
|
+
* @returns Layout
|
|
84
|
+
*/
|
|
69
85
|
export declare function ResponsibleContainer<T extends {}, F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate>(props: ResponsibleContainerProps<T, F>): JSX.Element;
|