@azrico/reactgrid 1.0.19 → 1.0.21
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/dist/src/example.js +12 -8
- package/dist/src/views/DataGrid.d.ts +2 -4
- package/dist/src/views/DataGrid.js +135 -145
- package/package.json +1 -1
- package/src/example.tsx +25 -9
- package/src/views/DataGrid.tsx +174 -159
package/dist/src/example.js
CHANGED
|
@@ -84,16 +84,16 @@ function ExampleGrid() {
|
|
|
84
84
|
return _react.default.createElement("div", null, _react.default.createElement("div", null, 'Test'));
|
|
85
85
|
};
|
|
86
86
|
const [selected, setSelected] = _react.default.useState(null);
|
|
87
|
-
const [rows, set_rows] = _react.default.useState([]);
|
|
88
87
|
const onSelectionChange = _react.default.useCallback(({
|
|
89
88
|
selected
|
|
90
89
|
}) => {
|
|
91
90
|
setSelected(selected);
|
|
92
91
|
}, []);
|
|
93
|
-
_react.default.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
const dataSource = _react.default.useCallback(async dt => {
|
|
93
|
+
return {
|
|
94
|
+
data: getData(),
|
|
95
|
+
count: 999
|
|
96
|
+
};
|
|
97
97
|
}, []);
|
|
98
98
|
return _react.default.createElement(_DataGrid.default, {
|
|
99
99
|
dark: true,
|
|
@@ -103,12 +103,16 @@ function ExampleGrid() {
|
|
|
103
103
|
contextMenuItems: contextMenuItems,
|
|
104
104
|
customColumns: customColumns,
|
|
105
105
|
columns: columns,
|
|
106
|
-
rows: rows,
|
|
107
|
-
leftColumns: leftColumns,
|
|
108
106
|
gridOptions: {
|
|
107
|
+
pagination: 'remote',
|
|
108
|
+
defaultLimit: 100,
|
|
109
|
+
limit: 100,
|
|
110
|
+
pageSizes: [100],
|
|
109
111
|
rowIndexColumn: true,
|
|
110
112
|
checkboxColumn: true
|
|
111
|
-
}
|
|
113
|
+
},
|
|
114
|
+
dataSource: dataSource,
|
|
115
|
+
leftColumns: leftColumns
|
|
112
116
|
});
|
|
113
117
|
}
|
|
114
118
|
var _default = ExampleGrid;
|
|
@@ -33,11 +33,10 @@ type customColumnData = {
|
|
|
33
33
|
type GridOptions = Partial<TypeDataGridProps>;
|
|
34
34
|
export type AzGridProps = {
|
|
35
35
|
columns?: columnOrString[];
|
|
36
|
-
|
|
37
|
-
get_rows?: () => any[];
|
|
36
|
+
dataSource?: any[] | ((args: any) => any[] | Promise<any[] | any>);
|
|
38
37
|
licenseKey?: string;
|
|
39
38
|
gridOptions?: GridOptions;
|
|
40
|
-
|
|
39
|
+
columnExtensions?: Array<{
|
|
41
40
|
name: string;
|
|
42
41
|
} & Partial<ColumnDefinition>>;
|
|
43
42
|
editableColumns?: string[];
|
|
@@ -49,7 +48,6 @@ export type AzGridProps = {
|
|
|
49
48
|
RowDetail?: RowDetailsFunc;
|
|
50
49
|
selected?: RowSelectionValue;
|
|
51
50
|
onSelectionChange?: OnSelectionChangeFunc;
|
|
52
|
-
onRowsChange?: (rows: any[], options: any) => void;
|
|
53
51
|
onRowClick?: (rowIndex: number, row: any) => void;
|
|
54
52
|
onRowDoubleClick?: (rowIndex: number, row: any) => void;
|
|
55
53
|
onLimitChange?: (v: number) => void;
|
|
@@ -33,139 +33,40 @@ const defaultColumnOptions = {
|
|
|
33
33
|
const dynamic_option_names = ['selected', 'loading', 'limit', 'skip'];
|
|
34
34
|
/* -------------------------------------------------------------------------- */
|
|
35
35
|
function AzGrid(props) {
|
|
36
|
-
const [pendingChanges, set_pendingChanges] = _react.default.useState(1);
|
|
37
|
-
const [cached_rows, set_cached_rows] = _react.default.useState([]);
|
|
38
36
|
/* -------------------------------------------------------------------------- */
|
|
39
37
|
/* Columns */
|
|
40
38
|
/* -------------------------------------------------------------------------- */
|
|
41
39
|
const cached_columns = _react.default.useMemo(() => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
let mcolExts = props.tableColumnExtensions || [];
|
|
45
|
-
let rightColumns = props.rightColumns || [];
|
|
46
|
-
let leftColumns = props.leftColumns || [];
|
|
47
|
-
let editableColumns = props.editableColumns || [];
|
|
48
|
-
let customColumns = props.customColumns || [];
|
|
49
|
-
if (!Array.isArray(mcols)) return [];
|
|
50
|
-
/* ------------------------------- fix columns ------------------------------ */
|
|
51
|
-
mcols.map(r => {
|
|
52
|
-
if (r == null) return null;
|
|
53
|
-
if (typeof r === 'string') return {
|
|
54
|
-
field: r,
|
|
55
|
-
header: r
|
|
56
|
-
};
|
|
57
|
-
if (typeof r === 'object') {
|
|
58
|
-
let final_cl = {
|
|
59
|
-
name: get_col_name(r),
|
|
60
|
-
header: r.header || r.title || r.name || '-',
|
|
61
|
-
width: r.width || undefined
|
|
62
|
-
};
|
|
63
|
-
delete r.field;
|
|
64
|
-
delete r.key;
|
|
65
|
-
delete r.columnName;
|
|
66
|
-
final_cl = {
|
|
67
|
-
...defaultColumnOptions,
|
|
68
|
-
...r,
|
|
69
|
-
...final_cl
|
|
70
|
-
};
|
|
71
|
-
return final_cl;
|
|
72
|
-
}
|
|
73
|
-
return null;
|
|
74
|
-
}).forEach(r => {
|
|
75
|
-
if (r != null) final_columns.push(r);
|
|
76
|
-
});
|
|
77
|
-
/* ---------------------------- apply extensions ---------------------------- */
|
|
78
|
-
if (mcolExts && Array.isArray(mcolExts)) for (let index = 0; index < mcolExts.length; index++) {
|
|
79
|
-
const ext = mcolExts[index];
|
|
80
|
-
const ext_cl = get_col_name(ext);
|
|
81
|
-
const mcol = final_columns.find(s => s.name === ext_cl);
|
|
82
|
-
if (mcol) {
|
|
83
|
-
for (const key in ext) {
|
|
84
|
-
if (!mcol[key] && key != 'name') mcol[key] = ext[key];
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
// if (ext.widthGrow) mcol.widthGrow = ext.widthGrow;
|
|
88
|
-
}
|
|
89
|
-
/* ------------------------------- frozen cols ------------------------------ */
|
|
90
|
-
if (Array.isArray(leftColumns)) {
|
|
91
|
-
for (let index = 0; index < leftColumns.length; index++) {
|
|
92
|
-
const r = get_col_name(leftColumns[index]);
|
|
93
|
-
const mcol = final_columns.find(s => s.name === r);
|
|
94
|
-
if (mcol) {
|
|
95
|
-
mcol.locked = 'start';
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
if (Array.isArray(rightColumns)) {
|
|
100
|
-
for (let index = 0; index < rightColumns.length; index++) {
|
|
101
|
-
const r = get_col_name(rightColumns[index]);
|
|
102
|
-
const mcol = final_columns.find(s => s.name === r);
|
|
103
|
-
if (mcol) {
|
|
104
|
-
mcol.locked = 'end';
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
/* -------------------------------- ediatable ------------------------------- */
|
|
109
|
-
if (Array.isArray(editableColumns)) {
|
|
110
|
-
for (let index = 0; index < editableColumns.length; index++) {
|
|
111
|
-
const r = get_col_name(editableColumns[index]);
|
|
112
|
-
const mcol = final_columns.find(s => s.name === r);
|
|
113
|
-
if (mcol) {
|
|
114
|
-
// mcol.editor = editorWrapper;
|
|
115
|
-
// mcol.editorOptions = {
|
|
116
|
-
// editOnClick: true,
|
|
117
|
-
// };
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
if (Array.isArray(customColumns)) {
|
|
122
|
-
for (let index = 0; index < customColumns.length; index++) {
|
|
123
|
-
const r = customColumns[index];
|
|
124
|
-
const rn = get_col_name(r);
|
|
125
|
-
const mcol = final_columns.find(s => s.name === rn);
|
|
126
|
-
if (mcol) {
|
|
127
|
-
//@ts-ignore
|
|
128
|
-
mcol.render = r.render;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return final_columns;
|
|
133
|
-
}, [props.columns, props.leftColumns, props.editableColumns, props.tableColumnExtensions]);
|
|
134
|
-
/* -------------------------------------------------------------------------- */
|
|
40
|
+
return ApplyColumnData(props);
|
|
41
|
+
}, [props.columns, props.leftColumns, props.rightColumns, props.editableColumns, props.columnExtensions, props.customColumns]);
|
|
135
42
|
/* -------------------------------------------------------------------------- */
|
|
136
43
|
/* Row changes */
|
|
137
44
|
/* -------------------------------------------------------------------------- */
|
|
138
|
-
_react.default.
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
if (props.onRowsChange) props.onRowsChange(rows, options);
|
|
160
|
-
set_pendingChanges(r => r + 1); //notify the cache to update rows after we made changes to them
|
|
161
|
-
}
|
|
162
|
-
/* -------------------------------------------------------------------------- */
|
|
163
|
-
/* -------------------------------------------------------------------------- */
|
|
45
|
+
const dataSource = _react.default.useCallback(async dt => {
|
|
46
|
+
let result_rows = [];
|
|
47
|
+
let result_data = undefined;
|
|
48
|
+
if (typeof props.dataSource === 'function') {
|
|
49
|
+
result_data = await props.dataSource(dt);
|
|
50
|
+
if (typeof result_data === 'object') {
|
|
51
|
+
result_rows = result_data.data;
|
|
52
|
+
} else result_rows = result_data;
|
|
53
|
+
} else {
|
|
54
|
+
result_rows = props.dataSource || [];
|
|
55
|
+
}
|
|
56
|
+
if (!Array.isArray(result_rows)) result_rows = [result_rows];
|
|
57
|
+
if (props.allowChildRows) result_rows = (0, _helpers.fix_parent_child_relations)(result_rows);
|
|
58
|
+
if (result_data && typeof result_data === 'object') {
|
|
59
|
+
return {
|
|
60
|
+
...result_data,
|
|
61
|
+
data: result_rows
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return result_rows;
|
|
65
|
+
}, [props.dataSource]);
|
|
164
66
|
return _react.default.createElement(DataGrid, {
|
|
165
67
|
...props,
|
|
166
68
|
columns: cached_columns,
|
|
167
|
-
|
|
168
|
-
onRowsChange: onRowsChange,
|
|
69
|
+
dataSource: dataSource,
|
|
169
70
|
highlightedRow: props.highlightedRow
|
|
170
71
|
});
|
|
171
72
|
}
|
|
@@ -173,14 +74,11 @@ function AzGrid(props) {
|
|
|
173
74
|
function DataGrid(props) {
|
|
174
75
|
const {
|
|
175
76
|
columns,
|
|
176
|
-
|
|
177
|
-
highlightedRow,
|
|
77
|
+
dataSource,
|
|
178
78
|
dark,
|
|
179
|
-
contextMenuItems
|
|
180
|
-
onRowsChange
|
|
79
|
+
contextMenuItems
|
|
181
80
|
} = props;
|
|
182
81
|
/* -------------------------------------------------------------------------- */
|
|
183
|
-
const gridRef = _react.default.useRef(null);
|
|
184
82
|
const [menuAnchorEl, set_menuAnchorEl] = _react.default.useState(null);
|
|
185
83
|
const [menuRow, set_menuRow] = _react.default.useState(null);
|
|
186
84
|
/* -------------------------------------------------------------------------- */
|
|
@@ -208,7 +106,7 @@ function DataGrid(props) {
|
|
|
208
106
|
...events,
|
|
209
107
|
...extra_ops
|
|
210
108
|
};
|
|
211
|
-
}, [
|
|
109
|
+
}, []);
|
|
212
110
|
const static_gridOptions = _react.default.useMemo(() => {
|
|
213
111
|
return {
|
|
214
112
|
...base_gridOptions,
|
|
@@ -236,10 +134,6 @@ function DataGrid(props) {
|
|
|
236
134
|
function onRowDoubleClick(event, row) {
|
|
237
135
|
props.onRowDoubleClick && props.onRowDoubleClick(row.rowIndex, row.data);
|
|
238
136
|
}
|
|
239
|
-
/* ------------------------- update the selected row ------------------------ */
|
|
240
|
-
_react.default.useEffect(() => {
|
|
241
|
-
if (highlightedRow) gridRef.current.scrollToRow(getRowIndex(highlightedRow, rows));
|
|
242
|
-
}, [highlightedRow]);
|
|
243
137
|
/* ------------------------------- ContextMenu ------------------------------ */
|
|
244
138
|
function update_menuAnchorEl(el) {
|
|
245
139
|
if (!el) {
|
|
@@ -260,7 +154,7 @@ function DataGrid(props) {
|
|
|
260
154
|
...dynamic_gridOptions,
|
|
261
155
|
className: 'azgrid-filler',
|
|
262
156
|
columns: columns,
|
|
263
|
-
dataSource:
|
|
157
|
+
dataSource: dataSource
|
|
264
158
|
}), _react.default.createElement(_controls.ContextMenu, {
|
|
265
159
|
menuAnchorEl: menuAnchorEl,
|
|
266
160
|
set_menuAnchorEl: update_menuAnchorEl,
|
|
@@ -269,26 +163,122 @@ function DataGrid(props) {
|
|
|
269
163
|
}));
|
|
270
164
|
}
|
|
271
165
|
/* -------------------------------------------------------------------------- */
|
|
166
|
+
/**
|
|
167
|
+
* Gets name of a column from its column object
|
|
168
|
+
* @param obj
|
|
169
|
+
* @returns
|
|
170
|
+
*/
|
|
272
171
|
function get_col_name(obj) {
|
|
273
172
|
if (!obj) return 'default';
|
|
274
173
|
if (typeof obj == 'string') return obj;
|
|
275
174
|
if (typeof obj != 'object') return 'default';
|
|
276
175
|
return obj.name || obj.field || obj.key || obj.columnName || 'default';
|
|
277
176
|
}
|
|
177
|
+
/**
|
|
178
|
+
* Gets default activation key for grid plugin
|
|
179
|
+
* @returns
|
|
180
|
+
*/
|
|
278
181
|
function get_default_key() {
|
|
279
182
|
return 'ExpiryDate=2999-01-01,Z=1040577552';
|
|
280
183
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
184
|
+
/**
|
|
185
|
+
* merges together all different props for columns
|
|
186
|
+
* to build a single final column data array
|
|
187
|
+
* @param props
|
|
188
|
+
* @returns
|
|
189
|
+
*/
|
|
190
|
+
function ApplyColumnData(props) {
|
|
191
|
+
const final_columns = [];
|
|
192
|
+
let mcols = props.columns || [];
|
|
193
|
+
let mcolExts = props.columnExtensions || [];
|
|
194
|
+
let rightColumns = props.rightColumns || [];
|
|
195
|
+
let leftColumns = props.leftColumns || [];
|
|
196
|
+
let editableColumns = props.editableColumns || [];
|
|
197
|
+
let customColumns = props.customColumns || [];
|
|
198
|
+
if (!Array.isArray(mcols)) return [];
|
|
199
|
+
/* ------------------------------- fix columns ------------------------------ */
|
|
200
|
+
mcols.map(r => {
|
|
201
|
+
if (r == null) return null;
|
|
202
|
+
if (typeof r === 'string') return {
|
|
203
|
+
field: r,
|
|
204
|
+
header: r
|
|
205
|
+
};
|
|
206
|
+
if (typeof r === 'object') {
|
|
207
|
+
let final_cl = {
|
|
208
|
+
name: get_col_name(r),
|
|
209
|
+
header: r.header || r.title || r.name || '-',
|
|
210
|
+
width: r.width || undefined
|
|
211
|
+
};
|
|
212
|
+
delete r.field;
|
|
213
|
+
delete r.key;
|
|
214
|
+
delete r.columnName;
|
|
215
|
+
final_cl = {
|
|
216
|
+
...defaultColumnOptions,
|
|
217
|
+
...r,
|
|
218
|
+
...final_cl
|
|
219
|
+
};
|
|
220
|
+
return final_cl;
|
|
221
|
+
}
|
|
222
|
+
return null;
|
|
223
|
+
}).forEach(r => {
|
|
224
|
+
if (r != null) final_columns.push(r);
|
|
225
|
+
});
|
|
226
|
+
/* ---------------------------- apply extensions ---------------------------- */
|
|
227
|
+
if (mcolExts && Array.isArray(mcolExts)) for (let index = 0; index < mcolExts.length; index++) {
|
|
228
|
+
const ext = mcolExts[index];
|
|
229
|
+
const ext_cl = get_col_name(ext);
|
|
230
|
+
const mcol = final_columns.find(s => s.name === ext_cl);
|
|
231
|
+
if (mcol) {
|
|
232
|
+
for (const key in ext) {
|
|
233
|
+
if (!mcol[key] && key != 'name') mcol[key] = ext[key];
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// if (ext.widthGrow) mcol.widthGrow = ext.widthGrow;
|
|
237
|
+
}
|
|
238
|
+
/* ------------------------------- frozen cols ------------------------------ */
|
|
239
|
+
if (Array.isArray(leftColumns)) {
|
|
240
|
+
for (let index = 0; index < leftColumns.length; index++) {
|
|
241
|
+
const r = get_col_name(leftColumns[index]);
|
|
242
|
+
const mcol = final_columns.find(s => s.name === r);
|
|
243
|
+
if (mcol) {
|
|
244
|
+
mcol.locked = 'start';
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (Array.isArray(rightColumns)) {
|
|
249
|
+
for (let index = 0; index < rightColumns.length; index++) {
|
|
250
|
+
const r = get_col_name(rightColumns[index]);
|
|
251
|
+
const mcol = final_columns.find(s => s.name === r);
|
|
252
|
+
if (mcol) {
|
|
253
|
+
mcol.locked = 'end';
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/* -------------------------------- ediatable ------------------------------- */
|
|
258
|
+
if (Array.isArray(editableColumns)) {
|
|
259
|
+
for (let index = 0; index < editableColumns.length; index++) {
|
|
260
|
+
const r = get_col_name(editableColumns[index]);
|
|
261
|
+
const mcol = final_columns.find(s => s.name === r);
|
|
262
|
+
if (mcol) {
|
|
263
|
+
// mcol.editor = editorWrapper;
|
|
264
|
+
// mcol.editorOptions = {
|
|
265
|
+
// editOnClick: true,
|
|
266
|
+
// };
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
if (Array.isArray(customColumns)) {
|
|
271
|
+
for (let index = 0; index < customColumns.length; index++) {
|
|
272
|
+
const r = customColumns[index];
|
|
273
|
+
const rn = get_col_name(r);
|
|
274
|
+
const mcol = final_columns.find(s => s.name === rn);
|
|
275
|
+
if (mcol) {
|
|
276
|
+
//@ts-ignore
|
|
277
|
+
mcol.render = r.render;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return final_columns;
|
|
292
282
|
}
|
|
293
283
|
/* -------------------------------------------------------------------------- */
|
|
294
284
|
var _default = AzGrid;
|
package/package.json
CHANGED
package/src/example.tsx
CHANGED
|
@@ -28,10 +28,20 @@ function getData() {
|
|
|
28
28
|
fd.push({ __table_id: String(index), username: 'user-' + index, age: 20 });
|
|
29
29
|
if (index % 5 == 0) {
|
|
30
30
|
const sub_selfid = 's' + index;
|
|
31
|
-
fd.push({
|
|
31
|
+
fd.push({
|
|
32
|
+
__table_id: sub_selfid,
|
|
33
|
+
__parent__table_id: String(index),
|
|
34
|
+
username: 'sub-' + index,
|
|
35
|
+
age: 20,
|
|
36
|
+
});
|
|
32
37
|
if (index % 2 == 0) {
|
|
33
38
|
const sub2_selfid = 'ss' + index;
|
|
34
|
-
fd.push({
|
|
39
|
+
fd.push({
|
|
40
|
+
__table_id: sub2_selfid,
|
|
41
|
+
__parent__table_id: sub_selfid,
|
|
42
|
+
username: 'sub2-' + index,
|
|
43
|
+
age: 20,
|
|
44
|
+
});
|
|
35
45
|
}
|
|
36
46
|
}
|
|
37
47
|
}
|
|
@@ -47,16 +57,15 @@ export function ExampleGrid() {
|
|
|
47
57
|
);
|
|
48
58
|
};
|
|
49
59
|
const [selected, setSelected] = React.useState(null);
|
|
50
|
-
|
|
60
|
+
|
|
51
61
|
const onSelectionChange = React.useCallback(({ selected }) => {
|
|
52
62
|
setSelected(selected);
|
|
53
63
|
}, []);
|
|
54
64
|
|
|
55
|
-
React.
|
|
56
|
-
|
|
57
|
-
set_rows(getData());
|
|
58
|
-
}, 1000);
|
|
65
|
+
const dataSource = React.useCallback(async (dt) => {
|
|
66
|
+
return { data: getData(), count: 999 };
|
|
59
67
|
}, []);
|
|
68
|
+
|
|
60
69
|
return (
|
|
61
70
|
<AzGrid
|
|
62
71
|
dark
|
|
@@ -66,9 +75,16 @@ export function ExampleGrid() {
|
|
|
66
75
|
contextMenuItems={contextMenuItems}
|
|
67
76
|
customColumns={customColumns}
|
|
68
77
|
columns={columns}
|
|
69
|
-
|
|
78
|
+
gridOptions={{
|
|
79
|
+
pagination: 'remote',
|
|
80
|
+
defaultLimit: 100,
|
|
81
|
+
limit: 100,
|
|
82
|
+
pageSizes: [100],
|
|
83
|
+
rowIndexColumn: true,
|
|
84
|
+
checkboxColumn: true,
|
|
85
|
+
}}
|
|
86
|
+
dataSource={dataSource}
|
|
70
87
|
leftColumns={leftColumns}
|
|
71
|
-
gridOptions={{ rowIndexColumn: true, checkboxColumn: true }}
|
|
72
88
|
/>
|
|
73
89
|
);
|
|
74
90
|
}
|
package/src/views/DataGrid.tsx
CHANGED
|
@@ -37,7 +37,12 @@ export type DataSourceDefinition = TypeDataSource;
|
|
|
37
37
|
export type OnSelectionChangeFunc = (config: TypeOnSelectionChangeArg) => void;
|
|
38
38
|
export type RowDetailsFunc = (rowDetailsInfo: TypeRowDetailsInfo) => React.ReactNode;
|
|
39
39
|
/* -------------------------------------------------------------------------- */
|
|
40
|
-
type loose_column_names = {
|
|
40
|
+
type loose_column_names = {
|
|
41
|
+
key: string;
|
|
42
|
+
field: string;
|
|
43
|
+
columnName: string;
|
|
44
|
+
name: string;
|
|
45
|
+
};
|
|
41
46
|
type loose_column_fields = loose_column_names & { title: string };
|
|
42
47
|
export type LooseColumnDefinition = Partial<loose_column_fields & ColumnDefinition>;
|
|
43
48
|
//
|
|
@@ -50,14 +55,13 @@ type GridOptions = Partial<TypeDataGridProps>;
|
|
|
50
55
|
/* -------------------------------------------------------------------------- */
|
|
51
56
|
export type AzGridProps = {
|
|
52
57
|
columns?: columnOrString[];
|
|
53
|
-
|
|
54
|
-
get_rows?: () => any[];
|
|
58
|
+
dataSource?: any[] | ((args: any) => any[] | Promise<any[] | any>);
|
|
55
59
|
|
|
56
60
|
licenseKey?: string;
|
|
57
61
|
|
|
58
62
|
gridOptions?: GridOptions;
|
|
59
63
|
|
|
60
|
-
|
|
64
|
+
columnExtensions?: Array<{ name: string } & Partial<ColumnDefinition>>;
|
|
61
65
|
editableColumns?: string[];
|
|
62
66
|
leftColumns?: string[];
|
|
63
67
|
rightColumns?: string[];
|
|
@@ -71,7 +75,7 @@ export type AzGridProps = {
|
|
|
71
75
|
selected?: RowSelectionValue;
|
|
72
76
|
/* -------------------------------------------------------------------------- */
|
|
73
77
|
onSelectionChange?: OnSelectionChangeFunc;
|
|
74
|
-
|
|
78
|
+
|
|
75
79
|
onRowClick?: (rowIndex: number, row: any) => void;
|
|
76
80
|
onRowDoubleClick?: (rowIndex: number, row: any) => void;
|
|
77
81
|
onLimitChange?: (v: number) => void;
|
|
@@ -91,7 +95,7 @@ type DataGridProps = ModifyFields<
|
|
|
91
95
|
AzGridProps,
|
|
92
96
|
{
|
|
93
97
|
columns: ColumnDefinition[];
|
|
94
|
-
|
|
98
|
+
dataSource: any;
|
|
95
99
|
}
|
|
96
100
|
>;
|
|
97
101
|
/* -------------------------------------------------------------------------- */
|
|
@@ -112,154 +116,60 @@ const defaultColumnOptions: ColumnDefinition = {
|
|
|
112
116
|
const dynamic_option_names = ['selected', 'loading', 'limit', 'skip'];
|
|
113
117
|
/* -------------------------------------------------------------------------- */
|
|
114
118
|
export function AzGrid(props: AzGridProps) {
|
|
115
|
-
const [pendingChanges, set_pendingChanges] = React.useState<number>(1);
|
|
116
|
-
const [cached_rows, set_cached_rows] = React.useState<any[]>([]);
|
|
117
|
-
|
|
118
119
|
/* -------------------------------------------------------------------------- */
|
|
119
120
|
/* Columns */
|
|
120
121
|
/* -------------------------------------------------------------------------- */
|
|
121
122
|
const cached_columns = React.useMemo(() => {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
/* ------------------------------- fix columns ------------------------------ */
|
|
132
|
-
|
|
133
|
-
mcols
|
|
134
|
-
.map((r) => {
|
|
135
|
-
if (r == null) return null;
|
|
136
|
-
if (typeof r === 'string') return { field: r, header: r };
|
|
137
|
-
if (typeof r === 'object') {
|
|
138
|
-
let final_cl: MakeWriteable<ColumnDefinition> = {
|
|
139
|
-
name: get_col_name(r),
|
|
140
|
-
header: r.header || r.title || r.name || '-',
|
|
141
|
-
width: r.width || undefined,
|
|
142
|
-
};
|
|
143
|
-
delete r.field;
|
|
144
|
-
delete r.key;
|
|
145
|
-
delete r.columnName;
|
|
146
|
-
final_cl = {
|
|
147
|
-
...defaultColumnOptions,
|
|
148
|
-
...r,
|
|
149
|
-
...final_cl,
|
|
150
|
-
};
|
|
151
|
-
return final_cl;
|
|
152
|
-
}
|
|
153
|
-
return null;
|
|
154
|
-
})
|
|
155
|
-
.forEach((r) => {
|
|
156
|
-
if (r != null) final_columns.push(r);
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
/* ---------------------------- apply extensions ---------------------------- */
|
|
160
|
-
if (mcolExts && Array.isArray(mcolExts))
|
|
161
|
-
for (let index = 0; index < mcolExts.length; index++) {
|
|
162
|
-
const ext = mcolExts[index];
|
|
163
|
-
const ext_cl = get_col_name(ext);
|
|
164
|
-
const mcol = final_columns.find((s) => s.name === ext_cl);
|
|
165
|
-
if (mcol) {
|
|
166
|
-
for (const key in ext) {
|
|
167
|
-
if (!mcol[key] && key != 'name') mcol[key] = ext[key];
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
// if (ext.widthGrow) mcol.widthGrow = ext.widthGrow;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/* ------------------------------- frozen cols ------------------------------ */
|
|
174
|
-
if (Array.isArray(leftColumns)) {
|
|
175
|
-
for (let index = 0; index < leftColumns.length; index++) {
|
|
176
|
-
const r = get_col_name(leftColumns[index]);
|
|
177
|
-
const mcol = final_columns.find((s) => s.name === r);
|
|
178
|
-
if (mcol) {
|
|
179
|
-
mcol.locked = 'start';
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
if (Array.isArray(rightColumns)) {
|
|
184
|
-
for (let index = 0; index < rightColumns.length; index++) {
|
|
185
|
-
const r = get_col_name(rightColumns[index]);
|
|
186
|
-
const mcol = final_columns.find((s) => s.name === r);
|
|
187
|
-
if (mcol) {
|
|
188
|
-
mcol.locked = 'end';
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
/* -------------------------------- ediatable ------------------------------- */
|
|
193
|
-
if (Array.isArray(editableColumns)) {
|
|
194
|
-
for (let index = 0; index < editableColumns.length; index++) {
|
|
195
|
-
const r = get_col_name(editableColumns[index]);
|
|
196
|
-
const mcol = final_columns.find((s) => s.name === r);
|
|
197
|
-
if (mcol) {
|
|
198
|
-
// mcol.editor = editorWrapper;
|
|
199
|
-
// mcol.editorOptions = {
|
|
200
|
-
// editOnClick: true,
|
|
201
|
-
// };
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
if (Array.isArray(customColumns)) {
|
|
206
|
-
for (let index = 0; index < customColumns.length; index++) {
|
|
207
|
-
const r = customColumns[index];
|
|
208
|
-
const rn = get_col_name(r);
|
|
209
|
-
const mcol = final_columns.find((s) => s.name === rn);
|
|
210
|
-
if (mcol) {
|
|
211
|
-
//@ts-ignore
|
|
212
|
-
mcol.render = r.render;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return final_columns;
|
|
218
|
-
}, [props.columns, props.leftColumns, props.editableColumns, props.tableColumnExtensions]);
|
|
219
|
-
/* -------------------------------------------------------------------------- */
|
|
220
|
-
|
|
123
|
+
return ApplyColumnData(props);
|
|
124
|
+
}, [
|
|
125
|
+
props.columns,
|
|
126
|
+
props.leftColumns,
|
|
127
|
+
props.rightColumns,
|
|
128
|
+
props.editableColumns,
|
|
129
|
+
props.columnExtensions,
|
|
130
|
+
props.customColumns,
|
|
131
|
+
]);
|
|
221
132
|
/* -------------------------------------------------------------------------- */
|
|
222
133
|
/* Row changes */
|
|
223
134
|
/* -------------------------------------------------------------------------- */
|
|
224
|
-
React.
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
set_pendingChanges(0);
|
|
239
|
-
}, [pendingChanges]);
|
|
240
|
-
|
|
241
|
-
React.useEffect(() => {
|
|
242
|
-
//console.log('Rows Changed !');
|
|
243
|
-
set_pendingChanges((r) => r + 1);
|
|
244
|
-
}, [props.rows]);
|
|
245
|
-
|
|
246
|
-
function onRowsChange(rows: any[], options: any) {
|
|
247
|
-
//console.log('onRowsChange');
|
|
248
|
-
if (props.onRowsChange) props.onRowsChange(rows, options);
|
|
249
|
-
set_pendingChanges((r) => r + 1); //notify the cache to update rows after we made changes to them
|
|
250
|
-
}
|
|
251
|
-
/* -------------------------------------------------------------------------- */
|
|
252
|
-
/* -------------------------------------------------------------------------- */
|
|
135
|
+
const dataSource = React.useCallback(
|
|
136
|
+
async (dt) => {
|
|
137
|
+
let result_rows: any[] = [];
|
|
138
|
+
let result_data: any = undefined;
|
|
139
|
+
if (typeof props.dataSource === 'function') {
|
|
140
|
+
result_data = await props.dataSource(dt);
|
|
141
|
+
if (typeof result_data === 'object') {
|
|
142
|
+
result_rows = result_data.data;
|
|
143
|
+
} else result_rows = result_data;
|
|
144
|
+
} else {
|
|
145
|
+
result_rows = props.dataSource || [];
|
|
146
|
+
}
|
|
147
|
+
if (!Array.isArray(result_rows)) result_rows = [result_rows];
|
|
148
|
+
if (props.allowChildRows) result_rows = fix_parent_child_relations(result_rows);
|
|
253
149
|
|
|
254
|
-
|
|
150
|
+
if (result_data && typeof result_data === 'object') {
|
|
151
|
+
return { ...result_data, data: result_rows };
|
|
152
|
+
}
|
|
153
|
+
return result_rows;
|
|
154
|
+
},
|
|
155
|
+
[props.dataSource]
|
|
156
|
+
);
|
|
157
|
+
return (
|
|
158
|
+
<DataGrid
|
|
159
|
+
{...props}
|
|
160
|
+
columns={cached_columns}
|
|
161
|
+
dataSource={dataSource}
|
|
162
|
+
highlightedRow={props.highlightedRow}
|
|
163
|
+
/>
|
|
164
|
+
);
|
|
255
165
|
}
|
|
256
166
|
|
|
257
167
|
/* -------------------------------------------------------------------------- */
|
|
258
168
|
function DataGrid(props: DataGridProps) {
|
|
259
|
-
const { columns,
|
|
169
|
+
const { columns, dataSource, dark, contextMenuItems } = props;
|
|
260
170
|
|
|
261
171
|
/* -------------------------------------------------------------------------- */
|
|
262
|
-
|
|
172
|
+
|
|
263
173
|
const [menuAnchorEl, set_menuAnchorEl] = React.useState<any>(null);
|
|
264
174
|
const [menuRow, set_menuRow] = React.useState<any>(null);
|
|
265
175
|
|
|
@@ -285,7 +195,8 @@ function DataGrid(props: DataGridProps) {
|
|
|
285
195
|
theme: dark ? 'amber-dark' : 'default-light',
|
|
286
196
|
};
|
|
287
197
|
return { ...defaultOptions, ...events, ...extra_ops };
|
|
288
|
-
}, [
|
|
198
|
+
}, []);
|
|
199
|
+
|
|
289
200
|
const static_gridOptions = React.useMemo<GridOptions>(() => {
|
|
290
201
|
return { ...base_gridOptions, ...props.gridOptions, ...forcedOptions };
|
|
291
202
|
}, [props.gridOptions, base_gridOptions]);
|
|
@@ -315,11 +226,6 @@ function DataGrid(props: DataGridProps) {
|
|
|
315
226
|
props.onRowDoubleClick && props.onRowDoubleClick(row.rowIndex, row.data);
|
|
316
227
|
}
|
|
317
228
|
|
|
318
|
-
/* ------------------------- update the selected row ------------------------ */
|
|
319
|
-
React.useEffect(() => {
|
|
320
|
-
if (highlightedRow) gridRef.current!.scrollToRow(getRowIndex(highlightedRow, rows));
|
|
321
|
-
}, [highlightedRow]);
|
|
322
|
-
|
|
323
229
|
/* ------------------------------- ContextMenu ------------------------------ */
|
|
324
230
|
|
|
325
231
|
function update_menuAnchorEl(el) {
|
|
@@ -343,34 +249,143 @@ function DataGrid(props: DataGridProps) {
|
|
|
343
249
|
{...dynamic_gridOptions}
|
|
344
250
|
className={'azgrid-filler'}
|
|
345
251
|
columns={columns}
|
|
346
|
-
dataSource={
|
|
252
|
+
dataSource={dataSource}
|
|
253
|
+
/>
|
|
254
|
+
<ContextMenu
|
|
255
|
+
menuAnchorEl={menuAnchorEl}
|
|
256
|
+
set_menuAnchorEl={update_menuAnchorEl}
|
|
257
|
+
menuRow={menuRow}
|
|
258
|
+
items={contextMenuItems}
|
|
347
259
|
/>
|
|
348
|
-
<ContextMenu menuAnchorEl={menuAnchorEl} set_menuAnchorEl={update_menuAnchorEl} menuRow={menuRow} items={contextMenuItems} />
|
|
349
260
|
</div>
|
|
350
261
|
);
|
|
351
262
|
}
|
|
263
|
+
|
|
352
264
|
/* -------------------------------------------------------------------------- */
|
|
353
265
|
|
|
266
|
+
/**
|
|
267
|
+
* Gets name of a column from its column object
|
|
268
|
+
* @param obj
|
|
269
|
+
* @returns
|
|
270
|
+
*/
|
|
354
271
|
function get_col_name(obj: any): string {
|
|
355
272
|
if (!obj) return 'default';
|
|
356
273
|
if (typeof obj == 'string') return obj;
|
|
357
274
|
if (typeof obj != 'object') return 'default';
|
|
358
275
|
return obj.name || obj.field || obj.key || obj.columnName || 'default';
|
|
359
276
|
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Gets default activation key for grid plugin
|
|
280
|
+
* @returns
|
|
281
|
+
*/
|
|
360
282
|
function get_default_key() {
|
|
361
283
|
return 'ExpiryDate=2999-01-01,Z=1040577552';
|
|
362
284
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
function
|
|
371
|
-
const
|
|
372
|
-
|
|
373
|
-
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* merges together all different props for columns
|
|
288
|
+
* to build a single final column data array
|
|
289
|
+
* @param props
|
|
290
|
+
* @returns
|
|
291
|
+
*/
|
|
292
|
+
function ApplyColumnData(props: any) {
|
|
293
|
+
const final_columns: MakeWriteable<ColumnDefinition>[] = [];
|
|
294
|
+
let mcols = props.columns || [];
|
|
295
|
+
let mcolExts = props.columnExtensions || [];
|
|
296
|
+
let rightColumns = props.rightColumns || [];
|
|
297
|
+
let leftColumns = props.leftColumns || [];
|
|
298
|
+
let editableColumns = props.editableColumns || [];
|
|
299
|
+
let customColumns = props.customColumns || [];
|
|
300
|
+
|
|
301
|
+
if (!Array.isArray(mcols)) return [];
|
|
302
|
+
/* ------------------------------- fix columns ------------------------------ */
|
|
303
|
+
|
|
304
|
+
mcols
|
|
305
|
+
.map((r) => {
|
|
306
|
+
if (r == null) return null;
|
|
307
|
+
if (typeof r === 'string') return { field: r, header: r };
|
|
308
|
+
if (typeof r === 'object') {
|
|
309
|
+
let final_cl: MakeWriteable<ColumnDefinition> = {
|
|
310
|
+
name: get_col_name(r),
|
|
311
|
+
header: r.header || r.title || r.name || '-',
|
|
312
|
+
width: r.width || undefined,
|
|
313
|
+
};
|
|
314
|
+
delete r.field;
|
|
315
|
+
delete r.key;
|
|
316
|
+
delete r.columnName;
|
|
317
|
+
final_cl = {
|
|
318
|
+
...defaultColumnOptions,
|
|
319
|
+
...r,
|
|
320
|
+
...final_cl,
|
|
321
|
+
};
|
|
322
|
+
return final_cl;
|
|
323
|
+
}
|
|
324
|
+
return null;
|
|
325
|
+
})
|
|
326
|
+
.forEach((r) => {
|
|
327
|
+
if (r != null) final_columns.push(r);
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
/* ---------------------------- apply extensions ---------------------------- */
|
|
331
|
+
if (mcolExts && Array.isArray(mcolExts))
|
|
332
|
+
for (let index = 0; index < mcolExts.length; index++) {
|
|
333
|
+
const ext = mcolExts[index];
|
|
334
|
+
const ext_cl = get_col_name(ext);
|
|
335
|
+
const mcol = final_columns.find((s) => s.name === ext_cl);
|
|
336
|
+
if (mcol) {
|
|
337
|
+
for (const key in ext) {
|
|
338
|
+
if (!mcol[key] && key != 'name') mcol[key] = ext[key];
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
// if (ext.widthGrow) mcol.widthGrow = ext.widthGrow;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/* ------------------------------- frozen cols ------------------------------ */
|
|
345
|
+
if (Array.isArray(leftColumns)) {
|
|
346
|
+
for (let index = 0; index < leftColumns.length; index++) {
|
|
347
|
+
const r = get_col_name(leftColumns[index]);
|
|
348
|
+
const mcol = final_columns.find((s) => s.name === r);
|
|
349
|
+
if (mcol) {
|
|
350
|
+
mcol.locked = 'start';
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
if (Array.isArray(rightColumns)) {
|
|
355
|
+
for (let index = 0; index < rightColumns.length; index++) {
|
|
356
|
+
const r = get_col_name(rightColumns[index]);
|
|
357
|
+
const mcol = final_columns.find((s) => s.name === r);
|
|
358
|
+
if (mcol) {
|
|
359
|
+
mcol.locked = 'end';
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
/* -------------------------------- ediatable ------------------------------- */
|
|
364
|
+
if (Array.isArray(editableColumns)) {
|
|
365
|
+
for (let index = 0; index < editableColumns.length; index++) {
|
|
366
|
+
const r = get_col_name(editableColumns[index]);
|
|
367
|
+
const mcol = final_columns.find((s) => s.name === r);
|
|
368
|
+
if (mcol) {
|
|
369
|
+
// mcol.editor = editorWrapper;
|
|
370
|
+
// mcol.editorOptions = {
|
|
371
|
+
// editOnClick: true,
|
|
372
|
+
// };
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
if (Array.isArray(customColumns)) {
|
|
377
|
+
for (let index = 0; index < customColumns.length; index++) {
|
|
378
|
+
const r = customColumns[index];
|
|
379
|
+
const rn = get_col_name(r);
|
|
380
|
+
const mcol = final_columns.find((s) => s.name === rn);
|
|
381
|
+
if (mcol) {
|
|
382
|
+
//@ts-ignore
|
|
383
|
+
mcol.render = r.render;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
return final_columns;
|
|
374
389
|
}
|
|
375
390
|
|
|
376
391
|
/* -------------------------------------------------------------------------- */
|