es-grid-template 1.8.92 → 1.8.94

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.
Files changed (36) hide show
  1. package/es/ali-table/InternalTable.js +3 -3
  2. package/es/ali-table/interfaces.d.ts +8 -5
  3. package/es/ali-table/pipeline/features/columnCustom.js +2 -10
  4. package/es/grid-component/hooks/constant.d.ts +1 -0
  5. package/es/grid-component/type.d.ts +2 -3
  6. package/es/group-component/hook/useFilterOperator.js +2 -2
  7. package/es/group-component/hook/utils.d.ts +3 -3
  8. package/es/table-component/InternalTable.js +12 -4
  9. package/es/table-component/TableContainer.js +2 -0
  10. package/es/table-component/TableContainerEdit.js +2 -0
  11. package/es/table-component/body/EditableCell.js +52 -0
  12. package/es/table-component/header/TableHeadCell2.js +6 -3
  13. package/es/table-component/hook/useFilterOperator.js +2 -2
  14. package/es/table-component/hook/utils.d.ts +3 -1
  15. package/es/table-component/hook/utils.js +80 -0
  16. package/es/table-component/table/Grid.d.ts +1 -1
  17. package/es/table-component/table/Grid.js +23 -1
  18. package/es/table-component/useContext.d.ts +2 -1
  19. package/lib/ali-table/InternalTable.js +3 -3
  20. package/lib/ali-table/interfaces.d.ts +8 -5
  21. package/lib/ali-table/pipeline/features/columnCustom.js +2 -10
  22. package/lib/grid-component/hooks/constant.d.ts +1 -0
  23. package/lib/grid-component/type.d.ts +2 -3
  24. package/lib/group-component/hook/useFilterOperator.js +2 -2
  25. package/lib/table-component/InternalTable.js +12 -4
  26. package/lib/table-component/TableContainer.js +2 -0
  27. package/lib/table-component/TableContainerEdit.js +2 -0
  28. package/lib/table-component/body/EditableCell.js +52 -0
  29. package/lib/table-component/header/TableHeadCell2.js +6 -3
  30. package/lib/table-component/hook/useFilterOperator.js +2 -2
  31. package/lib/table-component/hook/utils.d.ts +3 -1
  32. package/lib/table-component/hook/utils.js +85 -3
  33. package/lib/table-component/table/Grid.d.ts +1 -1
  34. package/lib/table-component/table/Grid.js +22 -0
  35. package/lib/table-component/useContext.d.ts +2 -1
  36. package/package.json +1 -1
@@ -72,9 +72,6 @@ const InternalTable = props => {
72
72
  document.removeEventListener('resize', handleWindowResize);
73
73
  };
74
74
  }, []);
75
- const isDataTree = React.useMemo(() => {
76
- return isTreeArray(dataSource);
77
- }, [dataSource]);
78
75
  const [visibleKeys, setVisibleKeys] = React.useState(undefined);
79
76
  const [filterState, setFilterState] = React.useState(undefined);
80
77
  const [sortState, setSortState] = React.useState(undefined);
@@ -87,6 +84,9 @@ const InternalTable = props => {
87
84
  }
88
85
  return addRowIdArray(dataSource);
89
86
  }, [dataSource, groupAble, groupColumns, groupSetting]);
87
+ const isDataTree = React.useMemo(() => {
88
+ return isTreeArray(convertData);
89
+ }, [convertData]);
90
90
  const mergedData = React.useMemo(() => {
91
91
  if (sortState || filterState) {
92
92
  return filterDataByColumns(convertData, filterState ?? [], sortState ?? [], [], ignoreAccents);
@@ -1,11 +1,14 @@
1
1
  import type { ReactElement, ReactNode } from 'react';
2
2
  import type React from 'react';
3
- import type { ColumnTemplate, CommandItem, IFormat, ITextAlign } from '../grid-component/type';
4
- export type ArtColumnAlign = 'left' | 'center' | 'right';
3
+ import type { ColumnTemplate, CommandItem, FilterOperator, IColumnType, IFormat, ITextAlign, TypeFilter } from '../grid-component/type';
5
4
  export type CellProps = React.TdHTMLAttributes<HTMLTableCellElement>;
6
- export type TypeFilter = 'Text' | 'Date' | 'Time' | 'Datetime' | 'DateRange' | 'Month' | 'Quarter' | 'Year' | 'Week' | 'Number' | 'NumberRange' | 'Dropdown' | 'DropTree' | 'Checkbox' | 'CheckboxTree' | 'CheckboxDropdown';
7
- export type IColumnType = 'number' | 'time' | 'date' | 'week' | 'month' | 'file' | 'quarter' | 'year' | 'datetime' | 'string' | 'boolean' | 'checkbox' | 'color' | null | undefined;
8
- export type FilterOperator = 'equal' | 'notEqual' | 'greaterThan' | 'greaterThanOrEqual' | 'lessThan' | 'lessThanOrEqual' | 'startsWith' | 'endsWith' | 'contains';
5
+ export type FilterState = {
6
+ field: any;
7
+ key: any;
8
+ column: ArtColumn;
9
+ filteredKeys: any[];
10
+ operator: string | undefined;
11
+ };
9
12
  export interface ArtColumnStaticPart {
10
13
  /** Column name */
11
14
  headerText?: string;
@@ -121,14 +121,7 @@ export function columnCustom(opts) {
121
121
  if (newVisible) {
122
122
  const filterValue = filterColumnState.filteredKeys ?? [];
123
123
  const operator = filterColumnState.operator;
124
-
125
- // const filterValueOrigin = fieldOriginal ? (fieldOriginal.getFilterValue() ?? []) as string[] : undefined
126
-
127
- // const operatorValue = (column.getFilterOperator() ?? getDefaultOperator(column)) as string
128
124
  const operatorValue = operator ?? getDefaultOperator(column);
129
-
130
- // setSelectedKeys(filterValueOrigin ?? filterValue)
131
-
132
125
  pipeline.setStateAtKey(stateKeyColumnFilter, {
133
126
  operator: operatorValue,
134
127
  filteredKeys: filterValue,
@@ -443,9 +436,8 @@ export function columnCustom(opts) {
443
436
  };
444
437
  }
445
438
  const prevGetCellProps = col?.getCellProps;
446
- const headerCustomTooltip = col.headerTooltip ?? (t ? t(col.headerText) : col.headerText);
439
+ const headerCustomTooltip = col?.headerTooltip ?? (t ? t(col?.headerText) : col?.headerText);
447
440
  const htmlTooltip = headerCustomTooltip;
448
- const hasValue = htmlTooltip.trim().length > 0;
449
441
 
450
442
  // Cell thường có thể filter và sort được
451
443
  return {
@@ -518,7 +510,7 @@ export function columnCustom(opts) {
518
510
  })),
519
511
  headerCellProps: mergeCellProps(col.headerCellProps ?? {}, {
520
512
  'data-tooltip-id': `${id}-tooltip-content`,
521
- 'data-tooltip-content': !hasValue ? '' : htmlTooltip,
513
+ 'data-tooltip-content': htmlTooltip,
522
514
  style: {
523
515
  overflow: 'visible',
524
516
  position: 'relative'
@@ -5,6 +5,7 @@ export type IOperator = {
5
5
  label: string;
6
6
  key: string;
7
7
  };
8
+ export type Operator = 'equal' | 'greaterthan' | 'greaterthanorequal' | 'lessthan' | 'lessthanorequal' | 'notequal' | 'startswith' | 'endswith' | 'contains';
8
9
  export declare const numberOperator: IOperator[];
9
10
  export declare const stringOperator: IOperator[];
10
11
  export declare const dateOperator: IOperator[];
@@ -3,7 +3,6 @@ import type { ItemType } from 'rc-master-ui/es/menu/interface';
3
3
  import type { Cell, Header, OnChangeFn } from '@tanstack/react-table';
4
4
  import type { CSSProperties, ReactElement, ReactNode } from 'react';
5
5
  import type { TableLocale } from "rc-master-ui/lib/table/interface";
6
- import type { IOperator } from '../grid-component/hooks';
7
6
  import type { PaginationLocale } from 'rc-master-ui/lib/pagination/Pagination';
8
7
  declare module "@tanstack/table-core" {
9
8
  interface ColumnMeta<any, any> extends ColumnTable {
@@ -98,7 +97,7 @@ export type EditType = 'text' | 'numeric' | 'asyncSelect' | 'date' | 'datetime'
98
97
  export type ITextAlign = 'center' | 'left' | 'right';
99
98
  export type TypeFilter = 'Text' | 'Date' | 'Time' | 'Datetime' | 'DateRange' | 'Month' | 'Quarter' | 'Year' | 'Week' | 'Number' | 'NumberRange' | 'Dropdown' | 'DropTree' | 'Checkbox' | 'CheckboxTree' | 'CheckboxDropdown';
100
99
  export type IColumnType = 'number' | 'time' | 'date' | 'week' | 'month' | 'file' | 'quarter' | 'year' | 'datetime' | 'string' | 'boolean' | 'checkbox' | 'color' | null | undefined;
101
- export type FilterOperator = 'equal' | 'notEqual' | 'greaterThan' | 'greaterThanOrEqual' | 'lessThan' | 'lessThanOrEqual' | 'startsWith' | 'endsWith' | 'contains';
100
+ export type FilterOperator = 'equal' | 'notequal' | 'greaterthan' | 'greaterthanorequal' | 'lessthan' | 'lessthanorequal' | 'startswith' | 'endswith' | 'contains';
102
101
  export type FixedType = 'left' | 'right' | boolean;
103
102
  export type SelectMode = 'checkbox' | 'radio' | undefined;
104
103
  type IGrid = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24;
@@ -614,7 +613,7 @@ export type Sorter = {
614
613
  export type FilterItem = {
615
614
  field: string;
616
615
  key: string;
617
- operator: IOperator;
616
+ operator: FilterOperator;
618
617
  predicate: 'and' | 'or';
619
618
  value: any;
620
619
  };
@@ -23,9 +23,9 @@ export function customStringFilterFn(row, columnId, filterValue) {
23
23
  switch (operator) {
24
24
  case 'equal':
25
25
  return cellValue === filterValue;
26
- case 'startsWith':
26
+ case 'startswith':
27
27
  return cellValue.toLowerCase().startsWith(filterValue.toLowerCase());
28
- case 'endsWith':
28
+ case 'endswith':
29
29
  return cellValue.toLowerCase().endsWith(filterValue.toLowerCase());
30
30
  default:
31
31
  return cellValue.toLowerCase().includes(filterValue.toLowerCase());
@@ -208,9 +208,9 @@ export declare const fixColumnsLeft: <RecordType>(columns: ColumnTable<RecordTyp
208
208
  ellipsis?: boolean;
209
209
  allowResizing?: boolean;
210
210
  allowSelection?: boolean | ((rowData: RecordType) => boolean);
211
- onCellStyles?: Omit<CSSProperties, "width" | "left" | "right" | "display" | "minWidth" | "position"> | ((cellValue: any, cell: import("@tanstack/react-table").Cell<RecordType, unknown>) => Omit<CSSProperties, "width" | "left" | "right" | "display" | "minWidth" | "position">);
212
- onCellHeaderStyles?: Omit<CSSProperties, "width" | "left" | "right" | "display" | "minWidth" | "position"> | ((cell: import("@tanstack/react-table").Header<RecordType, unknown>) => Omit<CSSProperties, "width" | "left" | "right" | "display" | "minWidth" | "position">);
213
- onCellFooterStyles?: Omit<CSSProperties, "width" | "left" | "right" | "display" | "minWidth" | "position"> | ((cellValue: any, cell: import("@tanstack/react-table").Header<RecordType, unknown>) => Omit<CSSProperties, "width" | "left" | "right" | "display" | "minWidth" | "position">);
211
+ onCellStyles?: Omit<CSSProperties, "left" | "right" | "display" | "width" | "minWidth" | "position"> | ((cellValue: any, cell: import("@tanstack/react-table").Cell<RecordType, unknown>) => Omit<CSSProperties, "left" | "right" | "display" | "width" | "minWidth" | "position">);
212
+ onCellHeaderStyles?: Omit<CSSProperties, "left" | "right" | "display" | "width" | "minWidth" | "position"> | ((cell: import("@tanstack/react-table").Header<RecordType, unknown>) => Omit<CSSProperties, "left" | "right" | "display" | "width" | "minWidth" | "position">);
213
+ onCellFooterStyles?: Omit<CSSProperties, "left" | "right" | "display" | "width" | "minWidth" | "position"> | ((cellValue: any, cell: import("@tanstack/react-table").Header<RecordType, unknown>) => Omit<CSSProperties, "left" | "right" | "display" | "width" | "minWidth" | "position">);
214
214
  sumGroup?: boolean;
215
215
  getValue?: (row: any, rowIndex: number) => any;
216
216
  getCellProps?: (value: any, row: any, rowIndex: number) => import("./../../grid-component/type").CellProps;
@@ -33,6 +33,10 @@ const InternalTable = props => {
33
33
  expandable,
34
34
  onChooseColumns,
35
35
  onExpandClick,
36
+ defaultFilter,
37
+ defaultSorter,
38
+ onFilter,
39
+ onSorter,
36
40
  // contextMenuClick,
37
41
  // contextMenuOpen,
38
42
  height,
@@ -74,8 +78,8 @@ const InternalTable = props => {
74
78
  document.removeEventListener('resize', handleWindowResize);
75
79
  };
76
80
  }, []);
77
- const [filterStates, setFilterState] = React.useState(null);
78
- const [sorterStates, setSorterStates] = React.useState([]);
81
+ const [filterStates, setFilterState] = React.useState(undefined);
82
+ const [sorterStates, setSorterStates] = React.useState(undefined);
79
83
  const [isFullScreen, setIsFullScreen] = React.useState(false);
80
84
  const [columns, setColumns] = React.useState([]);
81
85
  const [isExpandClick, setIsExpandClick] = React.useState(false);
@@ -139,8 +143,8 @@ const InternalTable = props => {
139
143
  value: selectedRowKeys
140
144
  });
141
145
  const mergedData = React.useMemo(() => {
142
- return filterDataByColumns(convertData, filterStates, sorterStates, mergedFilterKeys, ignoreAccents);
143
- }, [convertData, filterStates, mergedFilterKeys, sorterStates, ignoreAccents]);
146
+ return filterDataByColumns(convertData, onFilter ? undefined : filterStates ?? defaultFilter, onSorter ? undefined : sorterStates ?? defaultSorter, mergedFilterKeys, ignoreAccents);
147
+ }, [convertData, filterStates, mergedFilterKeys, sorterStates, ignoreAccents, defaultFilter, defaultSorter, onFilter, onSorter]);
144
148
  const columnVisibility = React.useMemo(() => {
145
149
  return getInvisibleColumns(columns);
146
150
  }, [columns]);
@@ -187,6 +191,10 @@ const InternalTable = props => {
187
191
  columnHidden: columnsHiddenKeys ? convertToObj(columnsHiddenKeys) : columnVisibility,
188
192
  triggerFilter: setFilterState,
189
193
  triggerSorter: setSorterStates,
194
+ defaultFilter: defaultFilter,
195
+ defaultSorter: defaultSorter,
196
+ onFilter: onFilter,
197
+ onSorter: onSorter,
190
198
  setMergedFilterKeys: setMergedFilterKeys,
191
199
  mergedFilterKeys: mergedFilterKeys,
192
200
  expanded: expanded,
@@ -34,6 +34,7 @@ const TableContainer = props => {
34
34
  contextMenuItems,
35
35
  setSorterChange,
36
36
  setFilterChange,
37
+ defaultFilter,
37
38
  height,
38
39
  minHeight,
39
40
  showToolbar,
@@ -290,6 +291,7 @@ const TableContainer = props => {
290
291
  onContextMenu,
291
292
  setSorterChange,
292
293
  setFilterChange,
294
+ defaultFilter,
293
295
  windowSize,
294
296
  isDataTree,
295
297
  focusedCell,
@@ -81,6 +81,7 @@ const TableContainerEdit = props => {
81
81
  contextMenuItems,
82
82
  setSorterChange,
83
83
  setFilterChange,
84
+ defaultFilter,
84
85
  onCellPaste,
85
86
  // triggerPaste,
86
87
  validate,
@@ -1716,6 +1717,7 @@ const TableContainerEdit = props => {
1716
1717
  // onContextMenu,
1717
1718
  setSorterChange,
1718
1719
  setFilterChange,
1720
+ defaultFilter,
1719
1721
  rangeState,
1720
1722
  setRangeState,
1721
1723
  rangePasteState,
@@ -447,6 +447,32 @@ const EditableCell = props => {
447
447
  });
448
448
  }
449
449
  },
450
+ onKeyDown: event => {
451
+ if (event.key === 'Enter' && event.target?.value && column?.editSelectSettings?.searchTextAsValue && isMulti !== true) {
452
+ const val = event.target.value;
453
+ onChange(val ?? '');
454
+ const formState = getValues();
455
+ // const itemState = getValues(dataIndex)
456
+ // @ts-ignore
457
+ const prevState = record[dataIndex];
458
+ const newState = val;
459
+ handleCellChange?.({
460
+ key,
461
+ field: column.field ?? column.field,
462
+ record: formState,
463
+ prevState,
464
+ newState,
465
+ option: {
466
+ value: val,
467
+ label: val,
468
+ searchTextAsValue: true
469
+ },
470
+ indexCol,
471
+ indexRow,
472
+ type: 'blur'
473
+ });
474
+ }
475
+ },
450
476
  "data-tooltip-content": message,
451
477
  "data-tooltip-id": `${id}-tooltip-error`
452
478
  });
@@ -526,6 +552,32 @@ const EditableCell = props => {
526
552
  });
527
553
  }
528
554
  },
555
+ onKeyDown: event => {
556
+ if (event.key === 'Enter' && event.target?.value && column?.editSelectSettings?.searchTextAsValue && isMulti !== true) {
557
+ const val = event.target.value;
558
+ onChange(val ?? '');
559
+ const formState = getValues();
560
+ // const itemState = getValues(dataIndex)
561
+ // @ts-ignore
562
+ const prevState = record[dataIndex];
563
+ const newState = val;
564
+ handleCellChange?.({
565
+ key,
566
+ field: column.field ?? column.field,
567
+ record: formState,
568
+ prevState,
569
+ newState,
570
+ option: {
571
+ value: val,
572
+ label: val,
573
+ searchTextAsValue: true
574
+ },
575
+ indexCol,
576
+ indexRow,
577
+ type: 'blur'
578
+ });
579
+ }
580
+ },
529
581
  dropdownRender: menu => {
530
582
  if (toolbarItems && toolbarItems.length > 0) {
531
583
  return /*#__PURE__*/React.createElement(React.Fragment, null, menu, toolbarItems && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Divider, {
@@ -36,7 +36,8 @@ const TableHeadCell2 = props => {
36
36
  setExpanded,
37
37
  expandable,
38
38
  dataSource,
39
- rowKey
39
+ rowKey,
40
+ defaultFilter
40
41
  } = useContext(TableContext);
41
42
  const [tableLocal] = useLocale('Table');
42
43
  const visibleCols = table.getVisibleFlatColumns();
@@ -97,7 +98,8 @@ const TableHeadCell2 = props => {
97
98
  if (newVisible) {
98
99
  const filterValue = column.getFilterValue() ?? [];
99
100
  const filterValueOrigin = fieldOriginal ? fieldOriginal.getFilterValue() ?? [] : undefined;
100
- const operatorValue = column.getFilterOperator() ?? getDefaultOperator(column.columnDef?.meta ?? {});
101
+ const defaultFilterOption = defaultFilter?.find(it => it.field === originalColumn.field);
102
+ const operatorValue = column.getFilterOperator() ?? defaultFilterOption?.operator ?? getDefaultOperator(column.columnDef?.meta ?? {});
101
103
  setSelectedKeys(filterValueOrigin ?? filterValue);
102
104
  if (fieldOriginal) {
103
105
  fieldOriginal.setFilterOperator?.(operatorValue);
@@ -151,7 +153,8 @@ const TableHeadCell2 = props => {
151
153
  destroyPopupOnHide: true,
152
154
  dropdownRender: () => {
153
155
  const type = getTypeFilter(originalColumn);
154
- const operatorValue = column.getFilterOperator() ?? getDefaultOperator(originalColumn);
156
+ const defaultOperatorValue = defaultFilter?.find(it => it.field === originalColumn.field);
157
+ const operatorValue = column.getFilterOperator() ?? defaultOperatorValue?.operator ?? getDefaultOperator(originalColumn);
155
158
  const operatorOptions = ['Checkbox', 'Dropdown', 'DropTree', 'CheckboxDropdown'].includes(type) ? booleanOperator : !type || type === 'Text' ? stringOperator : numberOperator;
156
159
  return /*#__PURE__*/React.createElement("div", {
157
160
  // className='ui-rc-table-filter-dropdown'
@@ -23,9 +23,9 @@ export function customStringFilterFn(row, columnId, filterValue) {
23
23
  switch (operator) {
24
24
  case 'equal':
25
25
  return cellValue === filterValue;
26
- case 'startsWith':
26
+ case 'startswith':
27
27
  return cellValue.toLowerCase().startsWith(filterValue.toLowerCase());
28
- case 'endsWith':
28
+ case 'endswith':
29
29
  return cellValue.toLowerCase().endsWith(filterValue.toLowerCase());
30
30
  default:
31
31
  return cellValue.toLowerCase().includes(filterValue.toLowerCase());
@@ -8,6 +8,7 @@ import dayjs from "dayjs";
8
8
  import type { IPositionCell } from "../useContext";
9
9
  import type { ColumnDef } from "@tanstack/react-table";
10
10
  import type { TreeDataNode } from "antd";
11
+ import type { FilterState } from "../../ali-table/interfaces";
11
12
  export declare const newGuid: () => any;
12
13
  export declare const convertDayjsToDate: (dateString: string, format?: string) => Date;
13
14
  export declare const convertDateToDayjs: (date: Date | undefined, format?: string) => dayjs.Dayjs;
@@ -72,7 +73,7 @@ export declare function compareDate(itemValue: any, value: any): boolean;
72
73
  export declare const removeVietnameseTones: (str: any) => any;
73
74
  export declare const shouldInclude: (item: any, queries: any[], ignoreAccents?: boolean) => any;
74
75
  export declare function sortData(data: any[], sorter: Sorter[]): any[];
75
- export declare function filterDataByColumns(data: any[], queries: FilterItem[], sorter: Sorter[], keysFilter: string[] | undefined, ignoreAccents?: boolean): any[];
76
+ export declare function filterDataByColumns(data: any[], queries: FilterItem[] | undefined, sorter: Sorter[] | undefined, keysFilter: string[] | undefined, ignoreAccents?: boolean): any[];
76
77
  export declare const getAllRowKey: (data: any[]) => any[];
77
78
  export declare const isEditable: <RecordType>(column: ColumnTable, rowData: RecordType) => boolean | ((rowData: any) => boolean);
78
79
  export declare const checkFieldKey: (key: string | undefined) => string;
@@ -119,6 +120,7 @@ export declare function addRowsUp(array: any, n: number): {
119
120
  addedRows: any[];
120
121
  };
121
122
  export declare const convertFilters: (filters: any[]) => any[];
123
+ export declare const revertConvertFilters: (clauses: any[]) => FilterState[];
122
124
  export declare function getInvisibleColumns(columns: ColumnTable[]): Record<string, boolean>;
123
125
  export declare const getAllVisibleKeys: (columns: any[]) => any[];
124
126
  export declare const getAllVisibleKeys1: (columns: ColumnTable[]) => any[];
@@ -1769,6 +1769,86 @@ export const convertFilters = filters => {
1769
1769
  });
1770
1770
  return result;
1771
1771
  };
1772
+ export const revertConvertFilters = clauses => {
1773
+ const map = new Map();
1774
+ clauses.forEach(c => {
1775
+ const k = `${c.key}__${c.field}`;
1776
+ const cur = map.get(k) ?? {
1777
+ key: c.key,
1778
+ field: c.field,
1779
+ items: []
1780
+ };
1781
+ cur.items.push(c);
1782
+ map.set(k, cur);
1783
+ });
1784
+ const result = [];
1785
+ for (const {
1786
+ key,
1787
+ field,
1788
+ items
1789
+ } of map.values()) {
1790
+ // normalize operator strings
1791
+ // const ops = items.map((i: any) => (i.operator ? String(i.operator).toLowerCase() : i.operator))
1792
+
1793
+ // if all predicates are 'or' => checkbox-like multi values
1794
+ if (items.every(i => i.predicate === 'or')) {
1795
+ const filteredKeys = items.map(i => i.value);
1796
+ const operator = items[0]?.operator;
1797
+ const column = {
1798
+ field,
1799
+ typeFilter: 'Checkbox'
1800
+ };
1801
+ result.push({
1802
+ field,
1803
+ key,
1804
+ column,
1805
+ filteredKeys,
1806
+ operator
1807
+ });
1808
+ continue;
1809
+ }
1810
+
1811
+ // handle range (greaterthanorequal + lessthanorequal)
1812
+ const gte = items.find(i => String(i.operator).toLowerCase() === 'greaterthanorequal');
1813
+ const lte = items.find(i => String(i.operator).toLowerCase() === 'lessthanorequal');
1814
+ if (gte || lte) {
1815
+ const a = gte?.value;
1816
+ const b = lte?.value;
1817
+ const filteredKeys = [a, b].filter(v => v !== undefined);
1818
+ const isNum = filteredKeys.every(v => typeof v === 'number' || !isNaN(Number(v)) && String(v).trim() !== '');
1819
+ const typeFilter = isNum ? 'NumberRange' : 'DateRange';
1820
+ const column = {
1821
+ field,
1822
+ typeFilter
1823
+ };
1824
+ result.push({
1825
+ field,
1826
+ key,
1827
+ column,
1828
+ filteredKeys,
1829
+ operator: undefined
1830
+ });
1831
+ continue;
1832
+ }
1833
+
1834
+ // default: single-value (and) or multiple and-predicates -> collect unique values
1835
+ const filteredKeys = Array.from(new Set(items.map(i => i.value)));
1836
+ const operator = items[0]?.operator;
1837
+ const typeFilter = filteredKeys.length === 1 && isDateString(filteredKeys[0]) ? 'Date' : undefined;
1838
+ const column = {
1839
+ field,
1840
+ typeFilter
1841
+ };
1842
+ result.push({
1843
+ field,
1844
+ key,
1845
+ column,
1846
+ filteredKeys,
1847
+ operator
1848
+ });
1849
+ }
1850
+ return result;
1851
+ };
1772
1852
 
1773
1853
  // export function getInvisibleColumns(columns: ColumnTable[]): Record<string, boolean> {
1774
1854
  // const result: Record<string, boolean> = {};
@@ -19,7 +19,7 @@ type Props<T> = Omit<TableProps<T>, 'columns'> & {
19
19
  isFullScreen: boolean;
20
20
  setIsFullScreen: Dispatch<SetStateAction<boolean>>;
21
21
  triggerFilter: Dispatch<SetStateAction<any>>;
22
- triggerSorter: Dispatch<SetStateAction<Sorter[]>>;
22
+ triggerSorter: Dispatch<SetStateAction<Sorter[] | undefined>>;
23
23
  setIsExpandClick: Dispatch<SetStateAction<boolean>>;
24
24
  onContextMenu?: (data: T) => (event: any) => void;
25
25
  triggerChangeColumns?: (args: any, keys: any, type: string) => void;
@@ -14,7 +14,7 @@ import { arrayMove } from '@dnd-kit/sortable';
14
14
  import React, { Fragment } from 'react';
15
15
  import TableContainer from "../TableContainer";
16
16
  import { OperatorFeature } from "../features/operator";
17
- import { convertFilters, convertToObjTrue, filterByIds, filterDataByColumns, getAllRowKey, isObjEqual } from "../hook/utils";
17
+ import { convertFilters, convertToObjTrue, filterByIds, filterDataByColumns, getAllRowKey, isObjEqual, revertConvertFilters } from "../hook/utils";
18
18
  import TableContainerEdit from "../TableContainerEdit";
19
19
  import classNames from 'classnames';
20
20
  import { GridStyle } from "../style";
@@ -57,6 +57,8 @@ const Grid = props => {
57
57
  fullScreenTitle,
58
58
  className: tableClassNames,
59
59
  setIsExpandClick,
60
+ defaultFilter,
61
+ defaultSorter,
60
62
  ...rest
61
63
  } = props;
62
64
  const [columnResizeMode] = React.useState('onChange');
@@ -166,6 +168,25 @@ const Grid = props => {
166
168
 
167
169
  // debugTable: true
168
170
  });
171
+ React.useEffect(() => {
172
+ if (defaultFilter) {
173
+ const a = revertConvertFilters(defaultFilter);
174
+ const rs = a.map(it => ({
175
+ id: it.field,
176
+ value: it.filteredKeys
177
+ }));
178
+ setColumnFilters(rs);
179
+ }
180
+ }, [defaultFilter]);
181
+ React.useEffect(() => {
182
+ if (defaultSorter) {
183
+ const rs = defaultSorter.map(it => ({
184
+ id: it.field,
185
+ desc: it.order === 'descend'
186
+ }));
187
+ setSorting(rs);
188
+ }
189
+ }, [defaultSorter]);
169
190
  React.useEffect(() => {
170
191
  if (columnHidden) {
171
192
  const abb = table.getVisibleLeafColumns()?.[0];
@@ -292,6 +313,7 @@ const Grid = props => {
292
313
  setIsSelectionChange: setIsSelectionChange,
293
314
  setSorterChange: setSorterChange,
294
315
  setFilterChange: setFilterChange,
316
+ defaultFilter: defaultFilter,
295
317
  height: height ?? minHeight ?? 700,
296
318
  minHeight: minHeight,
297
319
  pagination: pagination,
@@ -1,5 +1,5 @@
1
1
  import type { Dispatch, SetStateAction } from 'react';
2
- import type { ColumnTable, ExpandableConfig, IFormat, IWrapSettings, Locale, PaginationConfig, RangeState, RecordDoubleClickEventArgs, RowClassName, SelectionSettings, SourceFilter } from "./../grid-component/type";
2
+ import type { ColumnTable, ExpandableConfig, FilterItem, IFormat, IWrapSettings, Locale, PaginationConfig, RangeState, RecordDoubleClickEventArgs, RowClassName, SelectionSettings, SourceFilter } from "./../grid-component/type";
3
3
  import type { SubmitHandler } from "react-hook-form";
4
4
  import type { ExpandedState, Row, Table } from '@tanstack/react-table';
5
5
  export type IPositionCell = {
@@ -35,6 +35,7 @@ export interface IContext<T> {
35
35
  }>>;
36
36
  setSorterChange: Dispatch<SetStateAction<boolean>>;
37
37
  setFilterChange: Dispatch<SetStateAction<boolean>>;
38
+ defaultFilter?: FilterItem[];
38
39
  onContextMenu?: (data: T) => (event: any) => void;
39
40
  locale?: Locale;
40
41
  lang?: string;
@@ -81,9 +81,6 @@ const InternalTable = props => {
81
81
  document.removeEventListener('resize', handleWindowResize);
82
82
  };
83
83
  }, []);
84
- const isDataTree = _react.default.useMemo(() => {
85
- return (0, _utils.isTreeArray)(dataSource);
86
- }, [dataSource]);
87
84
  const [visibleKeys, setVisibleKeys] = _react.default.useState(undefined);
88
85
  const [filterState, setFilterState] = _react.default.useState(undefined);
89
86
  const [sortState, setSortState] = _react.default.useState(undefined);
@@ -96,6 +93,9 @@ const InternalTable = props => {
96
93
  }
97
94
  return (0, _utils.addRowIdArray)(dataSource);
98
95
  }, [dataSource, groupAble, groupColumns, groupSetting]);
96
+ const isDataTree = _react.default.useMemo(() => {
97
+ return (0, _utils.isTreeArray)(convertData);
98
+ }, [convertData]);
99
99
  const mergedData = _react.default.useMemo(() => {
100
100
  if (sortState || filterState) {
101
101
  return (0, _utils.filterDataByColumns)(convertData, filterState ?? [], sortState ?? [], [], ignoreAccents);
@@ -1,11 +1,14 @@
1
1
  import type { ReactElement, ReactNode } from 'react';
2
2
  import type React from 'react';
3
- import type { ColumnTemplate, CommandItem, IFormat, ITextAlign } from '../grid-component/type';
4
- export type ArtColumnAlign = 'left' | 'center' | 'right';
3
+ import type { ColumnTemplate, CommandItem, FilterOperator, IColumnType, IFormat, ITextAlign, TypeFilter } from '../grid-component/type';
5
4
  export type CellProps = React.TdHTMLAttributes<HTMLTableCellElement>;
6
- export type TypeFilter = 'Text' | 'Date' | 'Time' | 'Datetime' | 'DateRange' | 'Month' | 'Quarter' | 'Year' | 'Week' | 'Number' | 'NumberRange' | 'Dropdown' | 'DropTree' | 'Checkbox' | 'CheckboxTree' | 'CheckboxDropdown';
7
- export type IColumnType = 'number' | 'time' | 'date' | 'week' | 'month' | 'file' | 'quarter' | 'year' | 'datetime' | 'string' | 'boolean' | 'checkbox' | 'color' | null | undefined;
8
- export type FilterOperator = 'equal' | 'notEqual' | 'greaterThan' | 'greaterThanOrEqual' | 'lessThan' | 'lessThanOrEqual' | 'startsWith' | 'endsWith' | 'contains';
5
+ export type FilterState = {
6
+ field: any;
7
+ key: any;
8
+ column: ArtColumn;
9
+ filteredKeys: any[];
10
+ operator: string | undefined;
11
+ };
9
12
  export interface ArtColumnStaticPart {
10
13
  /** Column name */
11
14
  headerText?: string;
@@ -128,14 +128,7 @@ function columnCustom(opts) {
128
128
  if (newVisible) {
129
129
  const filterValue = filterColumnState.filteredKeys ?? [];
130
130
  const operator = filterColumnState.operator;
131
-
132
- // const filterValueOrigin = fieldOriginal ? (fieldOriginal.getFilterValue() ?? []) as string[] : undefined
133
-
134
- // const operatorValue = (column.getFilterOperator() ?? getDefaultOperator(column)) as string
135
131
  const operatorValue = operator ?? (0, _utils2.getDefaultOperator)(column);
136
-
137
- // setSelectedKeys(filterValueOrigin ?? filterValue)
138
-
139
132
  pipeline.setStateAtKey(stateKeyColumnFilter, {
140
133
  operator: operatorValue,
141
134
  filteredKeys: filterValue,
@@ -450,9 +443,8 @@ function columnCustom(opts) {
450
443
  };
451
444
  }
452
445
  const prevGetCellProps = col?.getCellProps;
453
- const headerCustomTooltip = col.headerTooltip ?? (t ? t(col.headerText) : col.headerText);
446
+ const headerCustomTooltip = col?.headerTooltip ?? (t ? t(col?.headerText) : col?.headerText);
454
447
  const htmlTooltip = headerCustomTooltip;
455
- const hasValue = htmlTooltip.trim().length > 0;
456
448
 
457
449
  // Cell thường có thể filter và sort được
458
450
  return {
@@ -525,7 +517,7 @@ function columnCustom(opts) {
525
517
  })),
526
518
  headerCellProps: (0, _utils.mergeCellProps)(col.headerCellProps ?? {}, {
527
519
  'data-tooltip-id': `${id}-tooltip-content`,
528
- 'data-tooltip-content': !hasValue ? '' : htmlTooltip,
520
+ 'data-tooltip-content': htmlTooltip,
529
521
  style: {
530
522
  overflow: 'visible',
531
523
  position: 'relative'
@@ -5,6 +5,7 @@ export type IOperator = {
5
5
  label: string;
6
6
  key: string;
7
7
  };
8
+ export type Operator = 'equal' | 'greaterthan' | 'greaterthanorequal' | 'lessthan' | 'lessthanorequal' | 'notequal' | 'startswith' | 'endswith' | 'contains';
8
9
  export declare const numberOperator: IOperator[];
9
10
  export declare const stringOperator: IOperator[];
10
11
  export declare const dateOperator: IOperator[];
@@ -3,7 +3,6 @@ import type { ItemType } from 'rc-master-ui/es/menu/interface';
3
3
  import type { Cell, Header, OnChangeFn } from '@tanstack/react-table';
4
4
  import type { CSSProperties, ReactElement, ReactNode } from 'react';
5
5
  import type { TableLocale } from "rc-master-ui/lib/table/interface";
6
- import type { IOperator } from '../grid-component/hooks';
7
6
  import type { PaginationLocale } from 'rc-master-ui/lib/pagination/Pagination';
8
7
  declare module "@tanstack/table-core" {
9
8
  interface ColumnMeta<any, any> extends ColumnTable {
@@ -98,7 +97,7 @@ export type EditType = 'text' | 'numeric' | 'asyncSelect' | 'date' | 'datetime'
98
97
  export type ITextAlign = 'center' | 'left' | 'right';
99
98
  export type TypeFilter = 'Text' | 'Date' | 'Time' | 'Datetime' | 'DateRange' | 'Month' | 'Quarter' | 'Year' | 'Week' | 'Number' | 'NumberRange' | 'Dropdown' | 'DropTree' | 'Checkbox' | 'CheckboxTree' | 'CheckboxDropdown';
100
99
  export type IColumnType = 'number' | 'time' | 'date' | 'week' | 'month' | 'file' | 'quarter' | 'year' | 'datetime' | 'string' | 'boolean' | 'checkbox' | 'color' | null | undefined;
101
- export type FilterOperator = 'equal' | 'notEqual' | 'greaterThan' | 'greaterThanOrEqual' | 'lessThan' | 'lessThanOrEqual' | 'startsWith' | 'endsWith' | 'contains';
100
+ export type FilterOperator = 'equal' | 'notequal' | 'greaterthan' | 'greaterthanorequal' | 'lessthan' | 'lessthanorequal' | 'startswith' | 'endswith' | 'contains';
102
101
  export type FixedType = 'left' | 'right' | boolean;
103
102
  export type SelectMode = 'checkbox' | 'radio' | undefined;
104
103
  type IGrid = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24;
@@ -614,7 +613,7 @@ export type Sorter = {
614
613
  export type FilterItem = {
615
614
  field: string;
616
615
  key: string;
617
- operator: IOperator;
616
+ operator: FilterOperator;
618
617
  predicate: 'and' | 'or';
619
618
  value: any;
620
619
  };
@@ -30,9 +30,9 @@ function customStringFilterFn(row, columnId, filterValue) {
30
30
  switch (operator) {
31
31
  case 'equal':
32
32
  return cellValue === filterValue;
33
- case 'startsWith':
33
+ case 'startswith':
34
34
  return cellValue.toLowerCase().startsWith(filterValue.toLowerCase());
35
- case 'endsWith':
35
+ case 'endswith':
36
36
  return cellValue.toLowerCase().endsWith(filterValue.toLowerCase());
37
37
  default:
38
38
  return cellValue.toLowerCase().includes(filterValue.toLowerCase());
@@ -42,6 +42,10 @@ const InternalTable = props => {
42
42
  expandable,
43
43
  onChooseColumns,
44
44
  onExpandClick,
45
+ defaultFilter,
46
+ defaultSorter,
47
+ onFilter,
48
+ onSorter,
45
49
  // contextMenuClick,
46
50
  // contextMenuOpen,
47
51
  height,
@@ -83,8 +87,8 @@ const InternalTable = props => {
83
87
  document.removeEventListener('resize', handleWindowResize);
84
88
  };
85
89
  }, []);
86
- const [filterStates, setFilterState] = _react.default.useState(null);
87
- const [sorterStates, setSorterStates] = _react.default.useState([]);
90
+ const [filterStates, setFilterState] = _react.default.useState(undefined);
91
+ const [sorterStates, setSorterStates] = _react.default.useState(undefined);
88
92
  const [isFullScreen, setIsFullScreen] = _react.default.useState(false);
89
93
  const [columns, setColumns] = _react.default.useState([]);
90
94
  const [isExpandClick, setIsExpandClick] = _react.default.useState(false);
@@ -148,8 +152,8 @@ const InternalTable = props => {
148
152
  value: selectedRowKeys
149
153
  });
150
154
  const mergedData = _react.default.useMemo(() => {
151
- return (0, _utils.filterDataByColumns)(convertData, filterStates, sorterStates, mergedFilterKeys, ignoreAccents);
152
- }, [convertData, filterStates, mergedFilterKeys, sorterStates, ignoreAccents]);
155
+ return (0, _utils.filterDataByColumns)(convertData, onFilter ? undefined : filterStates ?? defaultFilter, onSorter ? undefined : sorterStates ?? defaultSorter, mergedFilterKeys, ignoreAccents);
156
+ }, [convertData, filterStates, mergedFilterKeys, sorterStates, ignoreAccents, defaultFilter, defaultSorter, onFilter, onSorter]);
153
157
  const columnVisibility = _react.default.useMemo(() => {
154
158
  return (0, _utils.getInvisibleColumns)(columns);
155
159
  }, [columns]);
@@ -196,6 +200,10 @@ const InternalTable = props => {
196
200
  columnHidden: columnsHiddenKeys ? (0, _utils.convertToObj)(columnsHiddenKeys) : columnVisibility,
197
201
  triggerFilter: setFilterState,
198
202
  triggerSorter: setSorterStates,
203
+ defaultFilter: defaultFilter,
204
+ defaultSorter: defaultSorter,
205
+ onFilter: onFilter,
206
+ onSorter: onSorter,
199
207
  setMergedFilterKeys: setMergedFilterKeys,
200
208
  mergedFilterKeys: mergedFilterKeys,
201
209
  expanded: expanded,
@@ -41,6 +41,7 @@ const TableContainer = props => {
41
41
  contextMenuItems,
42
42
  setSorterChange,
43
43
  setFilterChange,
44
+ defaultFilter,
44
45
  height,
45
46
  minHeight,
46
47
  showToolbar,
@@ -297,6 +298,7 @@ const TableContainer = props => {
297
298
  onContextMenu,
298
299
  setSorterChange,
299
300
  setFilterChange,
301
+ defaultFilter,
300
302
  windowSize,
301
303
  isDataTree,
302
304
  focusedCell,
@@ -88,6 +88,7 @@ const TableContainerEdit = props => {
88
88
  contextMenuItems,
89
89
  setSorterChange,
90
90
  setFilterChange,
91
+ defaultFilter,
91
92
  onCellPaste,
92
93
  // triggerPaste,
93
94
  validate,
@@ -1723,6 +1724,7 @@ const TableContainerEdit = props => {
1723
1724
  // onContextMenu,
1724
1725
  setSorterChange,
1725
1726
  setFilterChange,
1727
+ defaultFilter,
1726
1728
  rangeState,
1727
1729
  setRangeState,
1728
1730
  rangePasteState,
@@ -455,6 +455,32 @@ const EditableCell = props => {
455
455
  });
456
456
  }
457
457
  },
458
+ onKeyDown: event => {
459
+ if (event.key === 'Enter' && event.target?.value && column?.editSelectSettings?.searchTextAsValue && isMulti !== true) {
460
+ const val = event.target.value;
461
+ onChange(val ?? '');
462
+ const formState = getValues();
463
+ // const itemState = getValues(dataIndex)
464
+ // @ts-ignore
465
+ const prevState = record[dataIndex];
466
+ const newState = val;
467
+ handleCellChange?.({
468
+ key,
469
+ field: column.field ?? column.field,
470
+ record: formState,
471
+ prevState,
472
+ newState,
473
+ option: {
474
+ value: val,
475
+ label: val,
476
+ searchTextAsValue: true
477
+ },
478
+ indexCol,
479
+ indexRow,
480
+ type: 'blur'
481
+ });
482
+ }
483
+ },
458
484
  "data-tooltip-content": message,
459
485
  "data-tooltip-id": `${id}-tooltip-error`
460
486
  });
@@ -534,6 +560,32 @@ const EditableCell = props => {
534
560
  });
535
561
  }
536
562
  },
563
+ onKeyDown: event => {
564
+ if (event.key === 'Enter' && event.target?.value && column?.editSelectSettings?.searchTextAsValue && isMulti !== true) {
565
+ const val = event.target.value;
566
+ onChange(val ?? '');
567
+ const formState = getValues();
568
+ // const itemState = getValues(dataIndex)
569
+ // @ts-ignore
570
+ const prevState = record[dataIndex];
571
+ const newState = val;
572
+ handleCellChange?.({
573
+ key,
574
+ field: column.field ?? column.field,
575
+ record: formState,
576
+ prevState,
577
+ newState,
578
+ option: {
579
+ value: val,
580
+ label: val,
581
+ searchTextAsValue: true
582
+ },
583
+ indexCol,
584
+ indexRow,
585
+ type: 'blur'
586
+ });
587
+ }
588
+ },
537
589
  dropdownRender: menu => {
538
590
  if (toolbarItems && toolbarItems.length > 0) {
539
591
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, menu, toolbarItems && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_antd.Divider, {
@@ -45,7 +45,8 @@ const TableHeadCell2 = props => {
45
45
  setExpanded,
46
46
  expandable,
47
47
  dataSource,
48
- rowKey
48
+ rowKey,
49
+ defaultFilter
49
50
  } = (0, _react.useContext)(_useContext.TableContext);
50
51
  const [tableLocal] = (0, _locale.useLocale)('Table');
51
52
  const visibleCols = table.getVisibleFlatColumns();
@@ -106,7 +107,8 @@ const TableHeadCell2 = props => {
106
107
  if (newVisible) {
107
108
  const filterValue = column.getFilterValue() ?? [];
108
109
  const filterValueOrigin = fieldOriginal ? fieldOriginal.getFilterValue() ?? [] : undefined;
109
- const operatorValue = column.getFilterOperator() ?? (0, _utils.getDefaultOperator)(column.columnDef?.meta ?? {});
110
+ const defaultFilterOption = defaultFilter?.find(it => it.field === originalColumn.field);
111
+ const operatorValue = column.getFilterOperator() ?? defaultFilterOption?.operator ?? (0, _utils.getDefaultOperator)(column.columnDef?.meta ?? {});
110
112
  setSelectedKeys(filterValueOrigin ?? filterValue);
111
113
  if (fieldOriginal) {
112
114
  fieldOriginal.setFilterOperator?.(operatorValue);
@@ -160,7 +162,8 @@ const TableHeadCell2 = props => {
160
162
  destroyPopupOnHide: true,
161
163
  dropdownRender: () => {
162
164
  const type = (0, _utils.getTypeFilter)(originalColumn);
163
- const operatorValue = column.getFilterOperator() ?? (0, _utils.getDefaultOperator)(originalColumn);
165
+ const defaultOperatorValue = defaultFilter?.find(it => it.field === originalColumn.field);
166
+ const operatorValue = column.getFilterOperator() ?? defaultOperatorValue?.operator ?? (0, _utils.getDefaultOperator)(originalColumn);
164
167
  const operatorOptions = ['Checkbox', 'Dropdown', 'DropTree', 'CheckboxDropdown'].includes(type) ? _hooks.booleanOperator : !type || type === 'Text' ? _hooks.stringOperator : _hooks.numberOperator;
165
168
  return /*#__PURE__*/_react.default.createElement("div", {
166
169
  // className='ui-rc-table-filter-dropdown'
@@ -30,9 +30,9 @@ function customStringFilterFn(row, columnId, filterValue) {
30
30
  switch (operator) {
31
31
  case 'equal':
32
32
  return cellValue === filterValue;
33
- case 'startsWith':
33
+ case 'startswith':
34
34
  return cellValue.toLowerCase().startsWith(filterValue.toLowerCase());
35
- case 'endsWith':
35
+ case 'endswith':
36
36
  return cellValue.toLowerCase().endsWith(filterValue.toLowerCase());
37
37
  default:
38
38
  return cellValue.toLowerCase().includes(filterValue.toLowerCase());
@@ -8,6 +8,7 @@ import dayjs from "dayjs";
8
8
  import type { IPositionCell } from "../useContext";
9
9
  import type { ColumnDef } from "@tanstack/react-table";
10
10
  import type { TreeDataNode } from "antd";
11
+ import type { FilterState } from "../../ali-table/interfaces";
11
12
  export declare const newGuid: () => any;
12
13
  export declare const convertDayjsToDate: (dateString: string, format?: string) => Date;
13
14
  export declare const convertDateToDayjs: (date: Date | undefined, format?: string) => dayjs.Dayjs;
@@ -72,7 +73,7 @@ export declare function compareDate(itemValue: any, value: any): boolean;
72
73
  export declare const removeVietnameseTones: (str: any) => any;
73
74
  export declare const shouldInclude: (item: any, queries: any[], ignoreAccents?: boolean) => any;
74
75
  export declare function sortData(data: any[], sorter: Sorter[]): any[];
75
- export declare function filterDataByColumns(data: any[], queries: FilterItem[], sorter: Sorter[], keysFilter: string[] | undefined, ignoreAccents?: boolean): any[];
76
+ export declare function filterDataByColumns(data: any[], queries: FilterItem[] | undefined, sorter: Sorter[] | undefined, keysFilter: string[] | undefined, ignoreAccents?: boolean): any[];
76
77
  export declare const getAllRowKey: (data: any[]) => any[];
77
78
  export declare const isEditable: <RecordType>(column: ColumnTable, rowData: RecordType) => boolean | ((rowData: any) => boolean);
78
79
  export declare const checkFieldKey: (key: string | undefined) => string;
@@ -119,6 +120,7 @@ export declare function addRowsUp(array: any, n: number): {
119
120
  addedRows: any[];
120
121
  };
121
122
  export declare const convertFilters: (filters: any[]) => any[];
123
+ export declare const revertConvertFilters: (clauses: any[]) => FilterState[];
122
124
  export declare function getInvisibleColumns(columns: ColumnTable[]): Record<string, boolean>;
123
125
  export declare const getAllVisibleKeys: (columns: any[]) => any[];
124
126
  export declare const getAllVisibleKeys1: (columns: ColumnTable[]) => any[];
@@ -54,7 +54,7 @@ exports.parseExcelClipboard = parseExcelClipboard;
54
54
  exports.parseExcelClipboardText = parseExcelClipboardText;
55
55
  exports.removeColumns = void 0;
56
56
  exports.removeDuplicatesByKey = removeDuplicatesByKey;
57
- exports.sortByType = exports.shouldInclude = exports.removeVietnameseTones = void 0;
57
+ exports.sortByType = exports.shouldInclude = exports.revertConvertFilters = exports.removeVietnameseTones = void 0;
58
58
  exports.sortData = sortData;
59
59
  exports.sumFields = sumFields;
60
60
  exports.sumNumberFields = sumNumberFields;
@@ -62,7 +62,8 @@ exports.sumSize = void 0;
62
62
  exports.toggleRowAndChildren = toggleRowAndChildren;
63
63
  exports.updateArrayByKey = exports.unFlattenData = void 0;
64
64
  exports.updateColumnWidthsRecursive = updateColumnWidthsRecursive;
65
- exports.updateColumnsByGroup = exports.updateColumns1 = void 0;
65
+ exports.updateColumns1 = void 0;
66
+ exports.updateColumnsByGroup = void 0;
66
67
  exports.updateOrInsert = updateOrInsert;
67
68
  exports.updateWidthsByOther = updateWidthsByOther;
68
69
  var _uuid = require("uuid");
@@ -1884,6 +1885,87 @@ const convertFilters = filters => {
1884
1885
  });
1885
1886
  return result;
1886
1887
  };
1888
+ exports.convertFilters = convertFilters;
1889
+ const revertConvertFilters = clauses => {
1890
+ const map = new Map();
1891
+ clauses.forEach(c => {
1892
+ const k = `${c.key}__${c.field}`;
1893
+ const cur = map.get(k) ?? {
1894
+ key: c.key,
1895
+ field: c.field,
1896
+ items: []
1897
+ };
1898
+ cur.items.push(c);
1899
+ map.set(k, cur);
1900
+ });
1901
+ const result = [];
1902
+ for (const {
1903
+ key,
1904
+ field,
1905
+ items
1906
+ } of map.values()) {
1907
+ // normalize operator strings
1908
+ // const ops = items.map((i: any) => (i.operator ? String(i.operator).toLowerCase() : i.operator))
1909
+
1910
+ // if all predicates are 'or' => checkbox-like multi values
1911
+ if (items.every(i => i.predicate === 'or')) {
1912
+ const filteredKeys = items.map(i => i.value);
1913
+ const operator = items[0]?.operator;
1914
+ const column = {
1915
+ field,
1916
+ typeFilter: 'Checkbox'
1917
+ };
1918
+ result.push({
1919
+ field,
1920
+ key,
1921
+ column,
1922
+ filteredKeys,
1923
+ operator
1924
+ });
1925
+ continue;
1926
+ }
1927
+
1928
+ // handle range (greaterthanorequal + lessthanorequal)
1929
+ const gte = items.find(i => String(i.operator).toLowerCase() === 'greaterthanorequal');
1930
+ const lte = items.find(i => String(i.operator).toLowerCase() === 'lessthanorequal');
1931
+ if (gte || lte) {
1932
+ const a = gte?.value;
1933
+ const b = lte?.value;
1934
+ const filteredKeys = [a, b].filter(v => v !== undefined);
1935
+ const isNum = filteredKeys.every(v => typeof v === 'number' || !isNaN(Number(v)) && String(v).trim() !== '');
1936
+ const typeFilter = isNum ? 'NumberRange' : 'DateRange';
1937
+ const column = {
1938
+ field,
1939
+ typeFilter
1940
+ };
1941
+ result.push({
1942
+ field,
1943
+ key,
1944
+ column,
1945
+ filteredKeys,
1946
+ operator: undefined
1947
+ });
1948
+ continue;
1949
+ }
1950
+
1951
+ // default: single-value (and) or multiple and-predicates -> collect unique values
1952
+ const filteredKeys = Array.from(new Set(items.map(i => i.value)));
1953
+ const operator = items[0]?.operator;
1954
+ const typeFilter = filteredKeys.length === 1 && isDateString(filteredKeys[0]) ? 'Date' : undefined;
1955
+ const column = {
1956
+ field,
1957
+ typeFilter
1958
+ };
1959
+ result.push({
1960
+ field,
1961
+ key,
1962
+ column,
1963
+ filteredKeys,
1964
+ operator
1965
+ });
1966
+ }
1967
+ return result;
1968
+ };
1887
1969
 
1888
1970
  // export function getInvisibleColumns(columns: ColumnTable[]): Record<string, boolean> {
1889
1971
  // const result: Record<string, boolean> = {};
@@ -1894,7 +1976,7 @@ const convertFilters = filters => {
1894
1976
  // }
1895
1977
  // return result;
1896
1978
  // }
1897
- exports.convertFilters = convertFilters;
1979
+ exports.revertConvertFilters = revertConvertFilters;
1898
1980
  function getInvisibleColumns(columns) {
1899
1981
  const result = {};
1900
1982
  function traverse(cols) {
@@ -19,7 +19,7 @@ type Props<T> = Omit<TableProps<T>, 'columns'> & {
19
19
  isFullScreen: boolean;
20
20
  setIsFullScreen: Dispatch<SetStateAction<boolean>>;
21
21
  triggerFilter: Dispatch<SetStateAction<any>>;
22
- triggerSorter: Dispatch<SetStateAction<Sorter[]>>;
22
+ triggerSorter: Dispatch<SetStateAction<Sorter[] | undefined>>;
23
23
  setIsExpandClick: Dispatch<SetStateAction<boolean>>;
24
24
  onContextMenu?: (data: T) => (event: any) => void;
25
25
  triggerChangeColumns?: (args: any, keys: any, type: string) => void;
@@ -62,6 +62,8 @@ const Grid = props => {
62
62
  fullScreenTitle,
63
63
  className: tableClassNames,
64
64
  setIsExpandClick,
65
+ defaultFilter,
66
+ defaultSorter,
65
67
  ...rest
66
68
  } = props;
67
69
  const [columnResizeMode] = _react.default.useState('onChange');
@@ -171,6 +173,25 @@ const Grid = props => {
171
173
 
172
174
  // debugTable: true
173
175
  });
176
+ _react.default.useEffect(() => {
177
+ if (defaultFilter) {
178
+ const a = (0, _utils.revertConvertFilters)(defaultFilter);
179
+ const rs = a.map(it => ({
180
+ id: it.field,
181
+ value: it.filteredKeys
182
+ }));
183
+ setColumnFilters(rs);
184
+ }
185
+ }, [defaultFilter]);
186
+ _react.default.useEffect(() => {
187
+ if (defaultSorter) {
188
+ const rs = defaultSorter.map(it => ({
189
+ id: it.field,
190
+ desc: it.order === 'descend'
191
+ }));
192
+ setSorting(rs);
193
+ }
194
+ }, [defaultSorter]);
174
195
  _react.default.useEffect(() => {
175
196
  if (columnHidden) {
176
197
  const abb = table.getVisibleLeafColumns()?.[0];
@@ -297,6 +318,7 @@ const Grid = props => {
297
318
  setIsSelectionChange: setIsSelectionChange,
298
319
  setSorterChange: setSorterChange,
299
320
  setFilterChange: setFilterChange,
321
+ defaultFilter: defaultFilter,
300
322
  height: height ?? minHeight ?? 700,
301
323
  minHeight: minHeight,
302
324
  pagination: pagination,
@@ -1,5 +1,5 @@
1
1
  import type { Dispatch, SetStateAction } from 'react';
2
- import type { ColumnTable, ExpandableConfig, IFormat, IWrapSettings, Locale, PaginationConfig, RangeState, RecordDoubleClickEventArgs, RowClassName, SelectionSettings, SourceFilter } from "./../grid-component/type";
2
+ import type { ColumnTable, ExpandableConfig, FilterItem, IFormat, IWrapSettings, Locale, PaginationConfig, RangeState, RecordDoubleClickEventArgs, RowClassName, SelectionSettings, SourceFilter } from "./../grid-component/type";
3
3
  import type { SubmitHandler } from "react-hook-form";
4
4
  import type { ExpandedState, Row, Table } from '@tanstack/react-table';
5
5
  export type IPositionCell = {
@@ -35,6 +35,7 @@ export interface IContext<T> {
35
35
  }>>;
36
36
  setSorterChange: Dispatch<SetStateAction<boolean>>;
37
37
  setFilterChange: Dispatch<SetStateAction<boolean>>;
38
+ defaultFilter?: FilterItem[];
38
39
  onContextMenu?: (data: T) => (event: any) => void;
39
40
  locale?: Locale;
40
41
  lang?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "es-grid-template",
3
- "version": "1.8.92",
3
+ "version": "1.8.94",
4
4
  "description": "es-grid-template",
5
5
  "keywords": [
6
6
  "react",