@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.
@@ -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.useEffect(() => {
94
- setTimeout(() => {
95
- set_rows(getData());
96
- }, 1000);
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
- rows?: any[];
37
- get_rows?: () => any[];
36
+ dataSource?: any[] | ((args: any) => any[] | Promise<any[] | any>);
38
37
  licenseKey?: string;
39
38
  gridOptions?: GridOptions;
40
- tableColumnExtensions?: Array<{
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
- const final_columns = [];
43
- let mcols = props.columns || [];
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.useEffect(() => {
139
- if (pendingChanges <= 0) return;
140
- //console.log('Updated Pending Changes: ', pendingChanges);
141
- let new_rows = [];
142
- if (typeof props.get_rows === 'function') {
143
- new_rows = props.get_rows();
144
- } else new_rows = props.rows || [];
145
- /* -------------------------------------------------------------------------- */
146
- if (!Array.isArray(new_rows)) new_rows = [];
147
- new_rows = new_rows.filter(s => s != null);
148
- /* -------------------------- fix child parent rel -------------------------- */
149
- if (props.allowChildRows) new_rows = (0, _helpers.fix_parent_child_relations)(new_rows);
150
- set_cached_rows(new_rows);
151
- set_pendingChanges(0);
152
- }, [pendingChanges]);
153
- _react.default.useEffect(() => {
154
- //console.log('Rows Changed !');
155
- set_pendingChanges(r => r + 1);
156
- }, [props.rows]);
157
- function onRowsChange(rows, options) {
158
- //console.log('onRowsChange');
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
- rows: cached_rows,
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
- rows,
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
- }, [props.gridOptions]);
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: static_gridOptions.dataSource ? static_gridOptions.dataSource : rows
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
- function getRowIndex(row, allrows) {
282
- if (!allrows) return -1;
283
- return allrows.findIndex(s => rowKeyGetter(s) === rowKeyGetter(row)) || -1;
284
- }
285
- function rowKeyGetter(row) {
286
- return row.__uid;
287
- }
288
- function isRowSelected(row, highlightedRow) {
289
- const rid = rowKeyGetter(row);
290
- const highLight = rowKeyGetter(highlightedRow);
291
- return rid != null && rid === highLight;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azrico/reactgrid",
3
- "version": "1.0.19",
3
+ "version": "1.0.21",
4
4
  "main": "dist/index.js",
5
5
  "description": "React Datagrid",
6
6
  "author": "Azrideus <MehrdadTavangar@gmail.com>",
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({ __table_id: sub_selfid, __parent__table_id: String(index), username: 'sub-' + index, age: 20 });
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({ __table_id: sub2_selfid, __parent__table_id: sub_selfid, username: 'sub2-' + index, age: 20 });
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
- const [rows, set_rows] = React.useState<any[]>([]);
60
+
51
61
  const onSelectionChange = React.useCallback(({ selected }) => {
52
62
  setSelected(selected);
53
63
  }, []);
54
64
 
55
- React.useEffect(() => {
56
- setTimeout(() => {
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
- rows={rows}
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
  }
@@ -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 = { key: string; field: string; columnName: string; name: string };
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
- rows?: any[];
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
- tableColumnExtensions?: Array<{ name: string } & Partial<ColumnDefinition>>;
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
- onRowsChange?: (rows: any[], options: any) => void;
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
- rows: DataRowDefinition[];
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
- const final_columns: MakeWriteable<ColumnDefinition>[] = [];
123
- let mcols = props.columns || [];
124
- let mcolExts = props.tableColumnExtensions || [];
125
- let rightColumns = props.rightColumns || [];
126
- let leftColumns = props.leftColumns || [];
127
- let editableColumns = props.editableColumns || [];
128
- let customColumns = props.customColumns || [];
129
-
130
- if (!Array.isArray(mcols)) return [];
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.useEffect(() => {
225
- if (pendingChanges <= 0) return;
226
- //console.log('Updated Pending Changes: ', pendingChanges);
227
- let new_rows: any[] = [];
228
- if (typeof props.get_rows === 'function') {
229
- new_rows = props.get_rows();
230
- } else new_rows = props.rows || [];
231
- /* -------------------------------------------------------------------------- */
232
- if (!Array.isArray(new_rows)) new_rows = [];
233
- new_rows = new_rows.filter((s) => s != null);
234
- /* -------------------------- fix child parent rel -------------------------- */
235
- if (props.allowChildRows) new_rows = fix_parent_child_relations(new_rows);
236
-
237
- set_cached_rows(new_rows);
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
- return <DataGrid {...props} columns={cached_columns} rows={cached_rows} onRowsChange={onRowsChange} highlightedRow={props.highlightedRow} />;
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, rows, highlightedRow, dark, contextMenuItems, onRowsChange } = props;
169
+ const { columns, dataSource, dark, contextMenuItems } = props;
260
170
 
261
171
  /* -------------------------------------------------------------------------- */
262
- const gridRef = React.useRef<any>(null);
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
- }, [props.gridOptions]);
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={static_gridOptions.dataSource ? static_gridOptions.dataSource : rows}
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
- function getRowIndex(row: any, allrows?: any[]): number {
364
- if (!allrows) return -1;
365
- return allrows.findIndex((s) => rowKeyGetter(s) === rowKeyGetter(row)) || -1;
366
- }
367
- function rowKeyGetter(row: any) {
368
- return row.__uid;
369
- }
370
- function isRowSelected(row: any, highlightedRow: any) {
371
- const rid = rowKeyGetter(row);
372
- const highLight = rowKeyGetter(highlightedRow);
373
- return rid != null && rid === highLight;
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
  /* -------------------------------------------------------------------------- */