@azrico/reactgrid 1.3.50 → 1.3.54

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.
@@ -0,0 +1,122 @@
1
+ import { ModifyFields } from '../func/func_grid';
2
+ import { ConvertableToMenuItem } from '@azrico/controls';
3
+ import React from 'react';
4
+ import {
5
+ TypeCellSelection,
6
+ TypeColumn,
7
+ TypeDataGridProps,
8
+ TypeDataSource,
9
+ TypeEditInfo,
10
+ TypeFilterTypes,
11
+ TypeFilterValue,
12
+ TypeRowDetailsInfo,
13
+ TypeRowProps,
14
+ TypeRowSelection,
15
+ TypeComputedProps,
16
+ } from '@inovua/reactdatagrid-community/types';
17
+
18
+ import { TypeOnSelectionChangeArg } from '@inovua/reactdatagrid-community/types/TypeDataGridProps';
19
+
20
+ /* -------------------------------------------------------------------------- */
21
+ export type ColumnDefinition = TypeColumn;
22
+ export type CellDefinition = any;
23
+ export type RowDefinition = any;
24
+ export type RowProps = TypeRowProps;
25
+ export type RowSelectionValue = TypeRowSelection;
26
+ export type CellSelectionValue = TypeCellSelection;
27
+ export type DataRowDefinition = any;
28
+ export type FilterTypes = TypeFilterTypes;
29
+ export type FilterValues = TypeFilterValue;
30
+ export type DataSourceDefinition = TypeDataSource;
31
+ export type OnSelectionChangeFunc = (config: TypeOnSelectionChangeArg) => void;
32
+ export type OnCellSelectionChangeFunc = (s: { [key: string]: boolean }) => void;
33
+ export type RowDetailsFunc = (rowDetailsInfo: TypeRowDetailsInfo) => React.ReactNode;
34
+
35
+ export type loose_column_names = {
36
+ key: string;
37
+ field: string;
38
+ columnName: string;
39
+ name: string;
40
+ };
41
+ export type loose_column_fields = loose_column_names & {
42
+ title: string;
43
+ type: string;
44
+ items: any[];
45
+ };
46
+ export type LooseColumnDefinition = Partial<loose_column_fields & ColumnDefinition>;
47
+ //
48
+
49
+ export type CustomColumnDefinition = {
50
+ name: string;
51
+ render: (cell: any, formatterParams, onRendered) => React.ReactNode | undefined | null;
52
+ };
53
+ export type AzGridOptions = Partial<TypeDataGridProps>;
54
+ /* -------------------------------------------------------------------------- */
55
+ export type AzGridProps = {
56
+ dataSource?: any[] | ((args: any) => any[] | Promise<any[] | any>);
57
+ details_dataSource?: any[] | ((args: any) => any[] | Promise<any[] | any>); //details is rendered under each row
58
+ details_columns?: LooseColumnDefinition[];
59
+ details_filter?: FilterValues;
60
+
61
+ licenseKey?: string;
62
+
63
+ gridRef?: React.MutableRefObject<TypeComputedProps>;
64
+ gridOptions?: AzGridOptions;
65
+
66
+ columns?: LooseColumnDefinition[];
67
+ columnExtensions?: Partial<LooseColumnDefinition>;
68
+
69
+ editableColumns?: string[];
70
+ leftColumns?: string[];
71
+ rightColumns?: string[];
72
+ customColumns?: CustomColumnDefinition[];
73
+
74
+ contextMenuItems?: ConvertableToMenuItem;
75
+
76
+ highlightedRow?: any;
77
+ RowDetail?: RowDetailsFunc;
78
+
79
+ selected?: RowSelectionValue;
80
+ cellSelection?: CellSelectionValue;
81
+ /* -------------------------------------------------------------------------- */
82
+ onEditComplete?: (editInfo: TypeEditInfo) => void;
83
+ onSelectionChange?: OnSelectionChangeFunc;
84
+ onCellSelectionChange?: OnCellSelectionChangeFunc;
85
+
86
+ onRowClick?: (rowIndex: number, row: any) => void;
87
+ onRowDoubleClick?: (rowIndex: number, row: any) => void;
88
+ onLimitChange?: (v: number) => void;
89
+ onSkipChange?: (v: number) => void;
90
+ /* -------------------------------------------------------------------------- */
91
+ skip?: number;
92
+ limit?: number;
93
+ //
94
+ editable?: boolean | ((editValue: any, cellProps: any) => boolean);
95
+ advancedFilterFields?: string[];
96
+ //
97
+
98
+ loading?: boolean;
99
+ dark?: boolean;
100
+ delayedSize?: boolean;
101
+ allowChildRows?: boolean;
102
+ looseCacheCheck?: boolean;
103
+ className?: string;
104
+ };
105
+
106
+ export type DataGridProps = ModifyFields<
107
+ AzGridProps,
108
+ {
109
+ columns: ColumnDefinition[];
110
+ dataSource: any;
111
+ }
112
+ >;
113
+ export type GridType = TypeComputedProps;
114
+ export type DataGridWrapperProps = ModifyFields<
115
+ DataGridProps,
116
+ {
117
+ gridRef: React.MutableRefObject<TypeComputedProps>;
118
+ static_gridOptions: AzGridOptions;
119
+ dynamic_gridOptions: AzGridOptions;
120
+ children?: React.ReactNode;
121
+ }
122
+ >;
@@ -3,144 +3,21 @@ import '@inovua/reactdatagrid-enterprise/theme/default-dark.css';
3
3
  import '@inovua/reactdatagrid-enterprise/theme/amber-dark.css';
4
4
  import '../themes/base_styles.css';
5
5
  import '../themes/grid.css';
6
-
7
- import {
8
- ApplyColumnData,
9
- ApplyDataSource,
10
- ModifyFields,
11
- find_realData,
12
- get_default_key,
13
- get_row_id,
14
- validateCache,
15
- } from '../func/func_grid';
16
- import { ContextMenu, ConvertableToMenuItem } from '@azrico/controls';
17
- import React, { useCallback, useState } from 'react';
18
- import {
19
- TypeCellSelection,
20
- TypeColumn,
21
- TypeDataGridProps,
22
- TypeDataSource,
23
- TypeEditInfo,
24
- TypeFilterTypes,
25
- TypeFilterValue,
26
- TypeRowDetailsInfo,
27
- TypeRowProps,
28
- TypeRowSelection,
29
- TypeComputedProps,
30
- } from '@inovua/reactdatagrid-community/types';
31
- import { fix_parent_child_relations, func_selection } from '../func/func_child';
32
- import { array_intersection, fn_eval } from '@azrico/object';
6
+ import { get_default_key } from '../func/func_grid';
7
+ import { ContextMenu } from '@azrico/controls';
8
+ import React from 'react';
33
9
 
34
10
  import ReactDataGrid from '@inovua/reactdatagrid-enterprise';
35
- import { TypeOnSelectionChangeArg } from '@inovua/reactdatagrid-community/types/TypeDataGridProps';
36
11
  import clsx from 'clsx';
37
12
  import { useComponentSize } from 'react-use-size';
38
13
 
39
- import debounce from 'lodash.debounce';
40
- /* -------------------------------------------------------------------------- */
41
-
42
- /* -------------------------------------------------------------------------- */
43
- export type ColumnDefinition = TypeColumn;
44
- export type CellDefinition = any;
45
- export type RowDefinition = any;
46
- export type RowProps = TypeRowProps;
47
- export type RowSelectionValue = TypeRowSelection;
48
- export type CellSelectionValue = TypeCellSelection;
49
- export type DataRowDefinition = any;
50
- export type FilterTypes = TypeFilterTypes;
51
- export type FilterValues = TypeFilterValue;
52
- export type DataSourceDefinition = TypeDataSource;
53
- export type OnSelectionChangeFunc = (config: TypeOnSelectionChangeArg) => void;
54
- export type OnCellSelectionChangeFunc = (s: { [key: string]: boolean }) => void;
55
- export type RowDetailsFunc = (rowDetailsInfo: TypeRowDetailsInfo) => React.ReactNode;
14
+ import { AzGridOptions, AzGridProps, DataGridWrapperProps } from '../types/types';
15
+ import { useGridEvents } from '../hooks/useGridEvents';
16
+ import { useColumnData } from '../hooks/useColumnData';
17
+ import { useDataSource } from '../hooks/useDatasource';
18
+ import { useGridSearch } from '../hooks/useGridSearch';
56
19
  /* -------------------------------------------------------------------------- */
57
- type loose_column_names = {
58
- key: string;
59
- field: string;
60
- columnName: string;
61
- name: string;
62
- };
63
- type loose_column_fields = loose_column_names & {
64
- title: string;
65
- type: string;
66
- items: any[];
67
- };
68
- export type LooseColumnDefinition = Partial<loose_column_fields & ColumnDefinition>;
69
- //
70
20
 
71
- export type CustomColumnDefinition = {
72
- name: string;
73
- render: (cell: any, formatterParams, onRendered) => React.ReactNode | undefined | null;
74
- };
75
- export type AzGridOptions = Partial<TypeDataGridProps>;
76
- /* -------------------------------------------------------------------------- */
77
- export type AzGridProps = {
78
- dataSource?: any[] | ((args: any) => any[] | Promise<any[] | any>);
79
- details_dataSource?: any[] | ((args: any) => any[] | Promise<any[] | any>); //details is rendered under each row
80
- details_columns?: LooseColumnDefinition[];
81
- details_filter?: FilterValues;
82
-
83
- licenseKey?: string;
84
-
85
- gridRef?: React.MutableRefObject<TypeComputedProps>;
86
- gridOptions?: AzGridOptions;
87
-
88
- columns?: LooseColumnDefinition[];
89
- columnExtensions?: Partial<LooseColumnDefinition>;
90
-
91
- editableColumns?: string[];
92
- leftColumns?: string[];
93
- rightColumns?: string[];
94
- customColumns?: CustomColumnDefinition[];
95
-
96
- contextMenuItems?: ConvertableToMenuItem;
97
-
98
- highlightedRow?: any;
99
- RowDetail?: RowDetailsFunc;
100
-
101
- selected?: RowSelectionValue;
102
- cellSelection?: CellSelectionValue;
103
- /* -------------------------------------------------------------------------- */
104
- onEditComplete?: (editInfo: TypeEditInfo) => void;
105
- onSelectionChange?: OnSelectionChangeFunc;
106
- onCellSelectionChange?: OnCellSelectionChangeFunc;
107
-
108
- onRowClick?: (rowIndex: number, row: any) => void;
109
- onRowDoubleClick?: (rowIndex: number, row: any) => void;
110
- onLimitChange?: (v: number) => void;
111
- onSkipChange?: (v: number) => void;
112
- /* -------------------------------------------------------------------------- */
113
- skip?: number;
114
- limit?: number;
115
- //
116
- editable?: boolean | ((editValue: any, cellProps: any) => boolean);
117
- advancedFilterFields?: string[];
118
- //
119
-
120
- loading?: boolean;
121
- dark?: boolean;
122
- delayedSize?: boolean;
123
- allowChildRows?: boolean;
124
- looseCacheCheck?: boolean;
125
- className?: string;
126
- };
127
-
128
- type DataGridProps = ModifyFields<
129
- AzGridProps,
130
- {
131
- columns: ColumnDefinition[];
132
- dataSource: any;
133
- }
134
- >;
135
- type DataGridWrapperProps = ModifyFields<
136
- DataGridProps,
137
- {
138
- gridRef: React.MutableRefObject<TypeComputedProps>;
139
- static_gridOptions: AzGridOptions;
140
- dynamic_gridOptions: AzGridOptions;
141
- children?: React.ReactNode;
142
- }
143
- >;
144
21
  /* -------------------------------------------------------------------------- */
145
22
 
146
23
  const defaultOptions: AzGridOptions = {
@@ -168,35 +45,12 @@ export function AzGrid(props: AzGridProps) {
168
45
  /* -------------------------------------------------------------------------- */
169
46
  /* Columns */
170
47
  /* -------------------------------------------------------------------------- */
171
- const cached_columns = React.useMemo(() => {
172
- return ApplyColumnData(props);
173
- }, [
174
- props.columns,
175
- props.leftColumns,
176
- props.rightColumns,
177
- props.editableColumns,
178
- props.columnExtensions,
179
- props.customColumns,
180
- ]);
48
+ const cached_columns = useColumnData(props);
49
+ const dataSource = useDataSource(props.dataSource, props);
181
50
  /* -------------------------------------------------------------------------- */
182
51
  /* Row changes */
183
52
  /* -------------------------------------------------------------------------- */
184
53
 
185
- const cached_data = React.useRef<any>();
186
- const last_cache_info = React.useRef<any>();
187
-
188
- const dataSource = React.useCallback(
189
- async (dt) => {
190
- return await ApplyDataSource(props.dataSource, {
191
- skip: dt?.skip,
192
- limit: dt?.limit,
193
- cached_data: cached_data,
194
- last_cache_info: last_cache_info,
195
- });
196
- },
197
- [props.dataSource]
198
- );
199
-
200
54
  const base_gridOptions = React.useMemo<AzGridOptions>(() => {
201
55
  const firstcolumn = cached_columns[0];
202
56
  const licenseKey = props.licenseKey || get_default_key();
@@ -270,87 +124,14 @@ export function AzGrid(props: AzGridProps) {
270
124
  */
271
125
  function DataGridEventsWrapper(props: DataGridWrapperProps) {
272
126
  /* -------------------------------------------------------------------------- */
273
-
274
- const click_data = React.useRef<any>(null);
275
-
276
- const [menuAnchorEl, set_menuAnchorEl] = React.useState<any>(null);
277
- const [menuRow, set_menuRow] = React.useState<any>(null);
278
-
279
- /* -------------------------------------------------------------------------- */
280
- /* refresh functions */
281
- /* -------------------------------------------------------------------------- */
282
- const refreshColumn = React.useCallback(
283
- (col: string) => {
284
- const dt = props.gridRef.current.ungroupedData;
285
- for (let index = 0; index < dt.length; index++) {
286
- (props.gridRef.current as any).setItemPropertyAt(index, col, dt[index][col]);
287
- }
288
- },
289
- [props.gridRef.current]
290
- );
291
- const refresh = React.useCallback(() => {
292
- const dt = props.gridRef.current.ungroupedData;
293
- for (let index = 0; index < dt.length; index++) {
294
- (props.gridRef.current as any).setItemAt(index, {}, { replace: false });
295
- }
296
- }, [props.gridRef.current]);
297
- React.useEffect(() => {
298
- if (!props.gridRef.current) return;
299
- props.gridRef.current['refresh'] = refresh;
300
- props.gridRef.current['refreshColumn'] = refreshColumn;
301
- }, [props.gridRef.current, props.dataSource, refresh, refreshColumn]);
302
- /* -------------------------------------------------------------------------- */
303
- /* events */
304
- /* -------------------------------------------------------------------------- */
305
- const onRowClick = React.useCallback(
306
- (rowProps, event) => {
307
- const nowDate = Date.now();
308
- const lastclick: number = click_data.current[get_row_id(rowProps)];
309
- if (lastclick) {
310
- const diffTime = Math.abs(nowDate - lastclick);
311
- if (diffTime < 400) {
312
- click_data.current[get_row_id(rowProps)] = null;
313
- return (
314
- props.onRowDoubleClick &&
315
- props.onRowDoubleClick(rowProps.rowIndex, rowProps.data)
316
- );
317
- }
318
- }
319
-
320
- click_data.current[get_row_id(rowProps)] = nowDate;
321
- return props.onRowClick && props.onRowClick(rowProps.rowIndex, rowProps.data);
322
- },
323
- [props.onRowClick, props.onRowDoubleClick]
324
- );
325
-
326
- React.useEffect(() => {
327
- click_data.current = {};
328
- }, [props.dataSource]);
329
-
330
- /* ------------------------------- ContextMenu ------------------------------ */
331
- const onRowContextMenu = React.useCallback((rowProps, event) => {
332
- if (!rowProps || !rowProps.data || func_selection.has_selection()) {
333
- update_menuRow(null, null);
334
- return true;
335
- }
336
- event.preventDefault();
337
-
338
- const realRow = find_realData(rowProps.dataSourceArray, event.target, rowProps.data);
339
- const anEl = func_selection.getVirtualElement(event.clientX, event.clientY);
340
- update_menuRow(realRow, anEl);
341
- return false;
342
- }, []);
343
-
344
- const update_menuRow = React.useCallback((r: any = null, el: any = null) => {
345
- set_menuRow(r || null);
346
- set_menuAnchorEl(el || null);
347
- }, []);
348
-
349
- /* -------------------------------------------------------------------------- */
350
- const onRenderRow = useCallback((rowProps) => {
351
- // save the original handlers to be called later
352
- rowProps['data-row-id'] = get_row_id(rowProps.data);
353
- }, []);
127
+ const {
128
+ onRowClick,
129
+ onRowContextMenu,
130
+ onRenderRow,
131
+ update_menuRow,
132
+ menuAnchorEl,
133
+ menuRow,
134
+ } = useGridEvents(props.gridRef.current, props);
354
135
  /* -------------------------------------------------------------------------- */
355
136
  /**
356
137
  * Merge click events into grid options
@@ -392,25 +173,8 @@ function DataGridEventsWrapper(props: DataGridWrapperProps) {
392
173
  }
393
174
 
394
175
  function DataGridDetailsWrapper(props: DataGridWrapperProps) {
395
- const cached_details_columns = React.useMemo(() => {
396
- return ApplyColumnData(props.details_columns);
397
- }, [props.details_columns]);
398
-
399
- const cached_data = React.useRef<any>();
400
- const last_cache_info = React.useRef<any>();
401
-
402
- const details_dataSource = React.useCallback(
403
- async (dt) => {
404
- const res = await ApplyDataSource(props.details_dataSource, {
405
- skip: dt.skip,
406
- limit: dt.limit,
407
- cached_data: cached_data,
408
- last_cache_info: last_cache_info,
409
- });
410
- return res;
411
- },
412
- [props.details_dataSource]
413
- );
176
+ const cached_details_columns = useColumnData(props.details_columns);
177
+ const details_dataSource = useDataSource(props.details_dataSource, props);
414
178
  const renderDetailsGrid = ({ data }) => {
415
179
  return (
416
180
  <ReactDataGrid
@@ -467,75 +231,11 @@ function DataGridDelayedSizeWrapper(props: DataGridWrapperProps) {
467
231
  );
468
232
  }
469
233
  function DataGridSearchWrapper(props: DataGridWrapperProps) {
470
- const [search, set_search] = React.useState('');
471
- const [filteredData, set_filteredData] = React.useState<any>([]);
472
- const currentSearch = React.useRef('');
473
- const currentDS = React.useRef<any[]>([]);
474
-
475
- const try_search = React.useCallback(
476
- debounce(() => {
477
- if (!Array.isArray(currentDS.current)) {
478
- return;
479
- }
480
- let newData: any[] = [];
481
- if (currentSearch.current) {
482
- const visibleColumns = props.gridRef.current.visibleColumns;
483
- const columns_to_search: string[] = array_intersection(
484
- props.advancedFilterFields || [],
485
- visibleColumns.map((r) => r.id)
486
- );
487
- const lowerSearchText = currentSearch.current.toLowerCase().trim();
488
- if (!lowerSearchText || columns_to_search.length === 0)
489
- newData = currentDS.current;
490
- else {
491
- newData = currentDS.current.filter((p) => {
492
- for (let index = 0; index < columns_to_search.length; index++) {
493
- const col = columns_to_search[index];
494
- const v = (p[col] + '').toLowerCase(); //value of column
495
- if (v && v.indexOf(lowerSearchText) != -1) {
496
- //if one column is matching then the row is a match
497
- return true;
498
- }
499
- }
500
- return false;
501
- });
502
- }
503
- } else newData = currentDS.current;
504
- set_filteredData(newData);
505
- }, 1000),
506
- []
507
- );
508
- React.useEffect(() => {
509
- fn_eval(props.dataSource).then((r) => {
510
- currentDS.current = typeof r === 'object' ? r.data || r : r;
511
- searchIfNeeded();
512
- });
513
- }, [props.dataSource]);
514
-
515
- React.useEffect(() => {
516
- currentSearch.current = search;
517
- searchIfNeeded();
518
- }, [search]);
519
-
520
- function searchIfNeeded() {
521
- if (!search) {
522
- set_filteredData(props.dataSource);
523
- } else try_search();
524
- }
234
+ const { element, filteredData } = useGridSearch(props.gridRef.current, props);
525
235
 
526
236
  return (
527
237
  <div className={'azgrid-flexed azgrid-flexlayout azgrid-nooverflow'}>
528
- <form className={'azgrid-searcharea'}>
529
- <label>
530
- Search
531
- <input
532
- type="text"
533
- name="name"
534
- value={search}
535
- onChange={(e) => set_search(e.target.value)}
536
- />
537
- </label>
538
- </form>
238
+ {element}
539
239
  <DataGridCore {...props} dataSource={filteredData} />
540
240
  </div>
541
241
  );
@@ -1,4 +1,4 @@
1
- export * from './DataGrid';
2
-
3
- import AzGrid from './DataGrid';
4
- export default AzGrid;
1
+ export * from './DataGrid';
2
+
3
+ import AzGrid from './DataGrid';
4
+ export default AzGrid;