es-grid-template 1.9.19 → 1.9.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.
@@ -727,6 +727,172 @@ export const detectSeparators = str => {
727
727
  // Không có dấu hoặc không hợp lệ
728
728
  return null;
729
729
  };
730
+ export const isDateValue = value => {
731
+ if (value === null || value === undefined) {
732
+ return false;
733
+ }
734
+
735
+ // Date object
736
+ if (value instanceof Date) {
737
+ return !isNaN(value.getTime());
738
+ }
739
+
740
+ // number timestamp
741
+ if (typeof value === 'number') {
742
+ const date = new Date(value);
743
+ return !isNaN(date.getTime());
744
+ }
745
+ if (typeof value !== 'string') return false;
746
+ const str = value.trim();
747
+ if (!str) {
748
+ return false;
749
+ }
750
+
751
+ // Các format date phổ biến
752
+ const patterns = [
753
+ // dd/MM/yyyy
754
+ /^\d{2}\/\d{2}\/\d{4}$/,
755
+ // d/M/yyyy
756
+ /^\d{1,2}\/\d{1,2}\/\d{4}$/,
757
+ // yyyy/MM/dd
758
+ /^\d{4}\/\d{2}\/\d{2}$/,
759
+ // yyyy/M/d
760
+ /^\d{4}\/\d{1,2}\/\d{1,2}$/,
761
+ // MM/yyyy
762
+ /^\d{2}\/\d{4}$/,
763
+ // M/yyyy
764
+ /^\d{1,2}\/\d{4}$/,
765
+ // yyyy/MM
766
+ /^\d{4}\/\d{2}$/,
767
+ // yyyy/M
768
+ /^\d{4}\/\d{1,2}$/,
769
+ // dd-MM-yyyy
770
+ /^\d{2}-\d{2}-\d{4}$/,
771
+ // yyyy-MM-dd
772
+ /^\d{4}-\d{2}-\d{2}$/,
773
+ // yyyy-M-d
774
+ /^\d{4}-\d{1,2}-\d{1,2}$/,
775
+ // ISO datetime
776
+ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/,
777
+ // ISO datetime milliseconds
778
+ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z?$/,
779
+ // yyyyMMdd
780
+ /^\d{8}$/,
781
+ // dd MMM yyyy
782
+ /^\d{1,2}\s[A-Za-z]{3}\s\d{4}$/,
783
+ // MMM dd, yyyy
784
+ /^[A-Za-z]{3}\s\d{1,2},\s\d{4}$/,
785
+ // full text date
786
+ /^[A-Za-z]+,\s[A-Za-z]+\s\d{1,2},\s\d{4}$/];
787
+ const matched = patterns.some(regex => regex.test(str));
788
+ if (matched) {
789
+ return true;
790
+ }
791
+
792
+ // fallback:
793
+ // nếu regex không match nhưng Date parse được
794
+ if (!matched) {
795
+ const fallbackDate = new Date(str);
796
+ return !isNaN(fallbackDate.getTime());
797
+ }
798
+
799
+ // validate real date
800
+ const date = new Date(str);
801
+ return !isNaN(date.getTime());
802
+ };
803
+ export const convertFomatedDateToDate = value => {
804
+ const monthMap = {
805
+ Jan: 0,
806
+ Feb: 1,
807
+ Mar: 2,
808
+ Apr: 3,
809
+ May: 4,
810
+ Jun: 5,
811
+ Jul: 6,
812
+ Aug: 7,
813
+ Sep: 8,
814
+ Oct: 9,
815
+ Nov: 10,
816
+ Dec: 11
817
+ };
818
+ let date = null;
819
+
820
+ // dd/MM/yyyy | d/M/yyyy
821
+ if (/^\d{1,2}\/\d{1,2}\/\d{4}$/.test(value)) {
822
+ const [d, m, y] = value.split('/').map(Number);
823
+ date = new Date(y, m - 1, d);
824
+ }
825
+
826
+ // yyyy/MM/dd | yyyy/M/d
827
+ else if (/^\d{4}\/\d{1,2}\/\d{1,2}$/.test(value)) {
828
+ const [y, m, d] = value.split('/').map(Number);
829
+ date = new Date(y, m - 1, d);
830
+ }
831
+
832
+ // MM/yyyy | M/yyyy
833
+ else if (/^\d{1,2}\/\d{4}$/.test(value)) {
834
+ const [m, y] = value.split('/').map(Number);
835
+ date = new Date(y, m - 1, 1);
836
+ }
837
+
838
+ // yyyy/MM | yyyy/M
839
+ else if (/^\d{4}\/\d{1,2}$/.test(value)) {
840
+ const [y, m] = value.split('/').map(Number);
841
+ date = new Date(y, m - 1, 1);
842
+ }
843
+
844
+ // dd-MM-yyyy
845
+ else if (/^\d{2}-\d{2}-\d{4}$/.test(value)) {
846
+ const [d, m, y] = value.split('-').map(Number);
847
+ date = new Date(y, m - 1, d);
848
+ }
849
+
850
+ // yyyy-MM-dd | yyyy-M-d
851
+ else if (/^\d{4}-\d{1,2}-\d{1,2}$/.test(value)) {
852
+ const [y, m, d] = value.split('-').map(Number);
853
+ date = new Date(y, m - 1, d);
854
+ }
855
+
856
+ // ISO datetime
857
+ else if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/.test(value)) {
858
+ date = new Date(value);
859
+ }
860
+
861
+ // ISO datetime milliseconds
862
+ else if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z?$/.test(value)) {
863
+ date = new Date(value);
864
+ }
865
+
866
+ // yyyyMMdd
867
+ else if (/^\d{8}$/.test(value)) {
868
+ const y = Number(value.slice(0, 4));
869
+ const m = Number(value.slice(4, 6));
870
+ const d = Number(value.slice(6, 8));
871
+ date = new Date(y, m - 1, d);
872
+ }
873
+
874
+ // dd MMM yyyy
875
+ else if (/^\d{1,2}\s[A-Za-z]{3}\s\d{4}$/.test(value)) {
876
+ const [d, mon, y] = value.split(' ');
877
+ date = new Date(Number(y), monthMap[mon], Number(d));
878
+ }
879
+
880
+ // MMM dd, yyyy
881
+ else if (/^[A-Za-z]{3}\s\d{1,2},\s\d{4}$/.test(value)) {
882
+ const [mon, dayComma, y] = value.split(' ');
883
+ const d = Number(dayComma.replace(',', ''));
884
+ date = new Date(Number(y), monthMap[mon], d);
885
+ }
886
+
887
+ // full text date
888
+ else if (/^[A-Za-z]+,\s[A-Za-z]+\s\d{1,2},\s\d{4}$/.test(value)) {
889
+ date = new Date(value);
890
+ }
891
+ if (!date || isNaN(date.getTime())) {
892
+ return null;
893
+ }
894
+ return date;
895
+ };
730
896
  function isDate(value) {
731
897
  if (value instanceof Date) {
732
898
  return !isNaN(value.getTime());
@@ -786,8 +952,11 @@ export const shouldInclude = (item, queries, ignoreAccents) => {
786
952
  } = query;
787
953
  const itemValue = item[field];
788
954
  let condition = false;
789
- const isDateComparison = isDate(itemValue) || isDateString(value);
790
- const itemDate = isDateComparison ? new Date(itemValue) : null;
955
+
956
+ // const aaa = convertFomatedDateToDate('25/01/2026')
957
+
958
+ const isDateComparison = isDate(itemValue) || isDateString(value) || isDateValue(itemValue) || isDateValue(value);
959
+ const itemDate = isDateComparison ? isNaN(new Date(itemValue).getTime()) ? convertFomatedDateToDate(itemValue) : new Date(itemValue) : null;
791
960
  const queryDate = isDateComparison ? parseToDate(value) : null;
792
961
  const itemStr = removeVietnameseTones(itemValue?.toString().toLowerCase?.() ?? '');
793
962
  const queryStr = removeVietnameseTones(value?.toString().toLowerCase?.() ?? '');
@@ -66,7 +66,6 @@ const TableBodyRow = ({
66
66
  rowData: row.original,
67
67
  field: colKey
68
68
  })(e);
69
- onContextMenu?.(row.original)(e);
70
69
  }
71
70
  }
72
71
  }), visibleCells.map(cell => {
@@ -135,95 +135,175 @@ export interface SpanRect {
135
135
  right: number;
136
136
  }
137
137
  export type ColumnTable<RecordType = AnyObject> = {
138
+ /** Field key dùng để mapping dữ liệu */
138
139
  field: string;
140
+ /** Text hiển thị ở header */
141
+ headerText?: string;
142
+ /** Field gốc trước khi transform */
139
143
  fieldOriginal?: string;
144
+ /** Độ rộng column */
140
145
  width?: number;
146
+ /** Độ rộng tối đa */
141
147
  maxWidth?: number;
148
+ /** Độ rộng tối thiểu */
142
149
  minWidth?: number;
150
+ /** Hiển thị trong popup chọn column */
151
+ showInColumnChoose?: boolean;
152
+ /** Kiểu dữ liệu của column */
143
153
  type?: IColumnType;
154
+ /** Format hiển thị dữ liệu column type = number */
155
+ format?: IFormat | ((rowData: any) => IFormat);
156
+ /**
157
+ * @deprecated Please use `isSummary` instead.
158
+ * @since 1.7.25
159
+ */
144
160
  haveSum?: boolean;
161
+ /** Có tính tổng column type = number hay không
162
+ *
163
+ * Mặc định = true
164
+ */
145
165
  isSummary?: boolean;
166
+ /** Có tính tổng theo group */
167
+ sumGroup?: boolean;
168
+ /** Template custom cho ô summary */
146
169
  summaryTemplate?: (data: number, key: string) => ReactElement | ReactNode;
147
- /** Custom method to get cell props */
148
- format?: IFormat | ((rowData: any) => IFormat);
149
- allowFiltering?: boolean;
150
170
  /**
151
171
  * @deprecated Please use `allowSortering` instead.
152
172
  * @since 1.7.25
153
173
  */
154
174
  sorter?: boolean;
175
+ /** Cho phép filter
176
+ *
177
+ * Mặc định = true
178
+ */
179
+ allowFiltering?: boolean;
180
+ /** Cho phép sort dữ liệu
181
+ *
182
+ * Mặc định = true
183
+ * */
155
184
  allowSortering?: boolean;
185
+ /** Kiểu filter */
186
+ typeFilter?: TypeFilter;
187
+ /** Toán tử filter mặc định */
156
188
  operator?: FilterOperator;
189
+ /** Ẩn phần chọn toán tử filter
190
+ * mặc đinh = false
191
+ */
157
192
  hideOperator?: boolean;
193
+ /** Custom Placeholder cho input/ Select/ Date.... filter */
158
194
  placeholder?: string;
159
- showInColumnChoose?: boolean;
160
- typeFilter?: TypeFilter;
195
+ /** Data source cho select/filter */
161
196
  source?: any[];
197
+ /** Hiển thị ô search trong select filter */
162
198
  showFilterSearch?: boolean;
163
- headerText?: string;
164
199
  /**
165
200
  * @deprecated Please use `visible` instead.
166
201
  * @since 1.7.33
167
202
  */
168
203
  hidden?: boolean;
204
+ /** Hiển thị / ẩn column
205
+ * mặc định = true
206
+ * */
169
207
  visible?: boolean;
208
+ /** Tooltip cho header */
170
209
  headerTooltip?: boolean | string | (() => ReactNode | ReactElement);
210
+ /** Tên group header */
171
211
  columnGroupText?: string;
172
- /**
173
- * @deprecated Please use `textAlign` instead.
174
- * @since 1.7.34
175
- */
176
- align?: ITextAlign;
177
- textAlign?: ITextAlign;
212
+ /** Canh lề nội dung header */
178
213
  headerTextAlign?: ITextAlign;
179
- template?: ReactNode | ReactElement | ((args: ColumnTemplate<RecordType>) => ReactNode | ReactElement);
180
- showTooltip?: boolean;
181
- tooltipDescription?: string | ((args: {
182
- value: any;
183
- rowData: RecordType;
184
- }) => ReactNode | ReactElement);
214
+ /** Template custom render header */
185
215
  headerTemplate?: React.ReactNode | React.ReactElement | ((column: ColumnTable<RecordType>) => React.ReactNode | React.ReactElement);
186
- commandItems?: CommandItem[];
187
- children?: ColumnTable<RecordType>[];
188
- editType?: EditType | ((rowData?: RecordType) => EditType);
189
- disable?: boolean | ((rowData: any) => boolean);
190
- editEnable?: boolean | ((rowData: any) => boolean);
191
- isClearable?: boolean;
192
- maxDate?: any;
193
- minDate?: any;
194
- maxTime?: any;
195
- minTime?: any;
196
- max?: number;
197
- min?: number;
198
- editSelectSettings?: IEditSelectSettings;
199
- editFromSettings?: IEditFromSettings;
200
216
  /**
201
217
  * @deprecated Please use `fixed` instead.
202
218
  * @since 1.7.25
203
219
  */
204
220
  fixedType?: FixedType;
221
+ /** Fixed column trái/phải */
205
222
  fixed?: FixedType;
206
223
  /**
207
- * @deprecated Please use `wrapSettings` instead.
224
+ * @deprecated Please use `wrapSettings` on Table instead.
208
225
  * @since 1.7.34
209
226
  */
210
227
  headerTextWrap?: boolean;
228
+ /** Hiển thị dấu ... khi text overflow */
211
229
  ellipsis?: boolean;
230
+ /** Cho phép resize column
231
+ *
232
+ * Mặc định = true
233
+ */
212
234
  allowResizing?: boolean;
213
- allowSelection?: boolean | ((rowData: RecordType) => boolean);
235
+ /**
236
+ * @deprecated Please use `textAlign` instead.
237
+ * @since 1.7.34
238
+ */
239
+ align?: ITextAlign;
240
+ /** Canh lề nội dung cell */
241
+ textAlign?: ITextAlign;
242
+ /** Template custom render cell */
243
+ template?: ReactNode | ReactElement | ((args: ColumnTemplate<RecordType>) => ReactNode | ReactElement);
244
+ /** Hiển thị tooltip cell */
245
+ showTooltip?: boolean;
246
+ /** Nội dung tooltip của cell */
247
+ tooltipDescription?: string | ((args: {
248
+ value: any;
249
+ rowData: RecordType;
250
+ }) => ReactNode | ReactElement);
251
+ /**
252
+ * @deprecated Please use `getCellProps` instead.
253
+ * @since 1.7.34
254
+ */
214
255
  onCellStyles?: Omit<React.CSSProperties, 'display' | 'width' | 'minWidth' | 'left' | 'right' | 'position'> | ((cellValue: any, cell: Cell<RecordType, unknown>) => Omit<React.CSSProperties, 'display' | 'width' | 'minWidth' | 'left' | 'right' | 'position'>);
256
+ /**
257
+ * @deprecated Please use `headerCellProps` instead.
258
+ * @since 1.7.34
259
+ */
215
260
  onCellHeaderStyles?: Omit<React.CSSProperties, 'display' | 'width' | 'minWidth' | 'left' | 'right' | 'position'> | ((cell: Header<RecordType, unknown>) => Omit<React.CSSProperties, 'display' | 'width' | 'minWidth' | 'left' | 'right' | 'position'>);
261
+ /**
262
+ * @deprecated Please use `getCellProps` instead.
263
+ * @since 1.7.34
264
+ */
265
+ onCell?: (rowData: RecordType, index: number) => React.TdHTMLAttributes<HTMLTableCellElement>;
216
266
  onCellFooterStyles?: Omit<React.CSSProperties, 'display' | 'width' | 'minWidth' | 'left' | 'right' | 'position'> | ((cellValue: any, cell: Header<RecordType, unknown>) => Omit<React.CSSProperties, 'display' | 'width' | 'minWidth' | 'left' | 'right' | 'position'>);
217
- sumGroup?: boolean;
218
267
  /** Custom data retrieval method */
268
+ /** Custom method lấy value cell */
219
269
  getValue?: (row: any, rowIndex: number) => any;
220
- /** Custom render method */
221
270
  /** Custom method to get cell props */
222
271
  getCellProps?: (value: any, row: any, rowIndex: number) => CellProps;
223
272
  /** Props for the header cell */
224
273
  headerCellProps?: CellProps;
225
274
  /** Custom method to get cell SpanRect */
275
+ /** Custom merge cell */
226
276
  getSpanRect?: (value: any, row: any, rowIndex: number) => SpanRect;
277
+ /** Kiểu editor khi edit cell */
278
+ editType?: EditType | ((rowData?: RecordType) => EditType);
279
+ /** Disable editor */
280
+ disable?: boolean | ((rowData: any) => boolean);
281
+ /** Cho phép edit */
282
+ editEnable?: boolean | ((rowData: any) => boolean);
283
+ /** Cho phép clear value khi edit */
284
+ isClearable?: boolean;
285
+ /** Ngày lớn nhất cho date picker */
286
+ maxDate?: any;
287
+ /** Ngày nhỏ nhất cho date picker */
288
+ minDate?: any;
289
+ /** Thời gian lớn nhất */
290
+ maxTime?: any;
291
+ /** Thời gian nhỏ nhất */
292
+ minTime?: any;
293
+ /** Giá trị số lớn nhất khi editType : number */
294
+ max?: number;
295
+ /** Giá trị số nhỏ nhất khi editType : number */
296
+ min?: number;
297
+ /** Config select editor */
298
+ editSelectSettings?: IEditSelectSettings;
299
+ /** Config form editor */
300
+ editFromSettings?: IEditFromSettings;
301
+ /** Cho phép select column */
302
+ allowSelection?: boolean | ((rowData: RecordType) => boolean);
303
+ /** Danh sách command/action trong column type = command */
304
+ commandItems?: CommandItem[];
305
+ /** Column con (multi header/group column) */
306
+ children?: ColumnTable<RecordType>[];
227
307
  };
228
308
  export type ColumnsTable<RecordType = AnyObject> = ColumnTable<RecordType>[];
229
309
  export type IFTheme = {
@@ -155,42 +155,53 @@ export declare const removeColumns: <RecordType>(columns: ColumnTable<RecordType
155
155
  export declare const fixColumnsLeft: <RecordType>(columns: ColumnTable<RecordType>[], fixedFields: string[]) => {
156
156
  fixed: string;
157
157
  field: string;
158
+ headerText?: string;
158
159
  fieldOriginal?: string;
159
160
  width?: number;
160
161
  maxWidth?: number;
161
162
  minWidth?: number;
163
+ showInColumnChoose?: boolean;
162
164
  type?: IColumnType;
165
+ format?: IFormat | ((rowData: any) => IFormat);
163
166
  haveSum?: boolean;
164
167
  isSummary?: boolean;
168
+ sumGroup?: boolean;
165
169
  summaryTemplate?: (data: number, key: string) => import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
166
- format?: IFormat | ((rowData: any) => IFormat);
167
- allowFiltering?: boolean;
168
170
  sorter?: boolean;
171
+ allowFiltering?: boolean;
169
172
  allowSortering?: boolean;
173
+ typeFilter?: TypeFilter;
170
174
  operator?: FilterOperator;
171
175
  hideOperator?: boolean;
172
176
  placeholder?: string;
173
- showInColumnChoose?: boolean;
174
- typeFilter?: TypeFilter;
175
177
  source?: any[];
176
178
  showFilterSearch?: boolean;
177
- headerText?: string;
178
179
  hidden?: boolean;
179
180
  visible?: boolean;
180
181
  headerTooltip?: string | boolean | (() => import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>);
181
182
  columnGroupText?: string;
183
+ headerTextAlign?: import("./../../grid-component/type").ITextAlign;
184
+ headerTemplate?: import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | ((column: ColumnTable<RecordType>) => import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>);
185
+ fixedType?: import("./../../grid-component/type").FixedType;
186
+ headerTextWrap?: boolean;
187
+ ellipsis?: boolean;
188
+ allowResizing?: boolean;
182
189
  align?: import("./../../grid-component/type").ITextAlign;
183
190
  textAlign?: import("./../../grid-component/type").ITextAlign;
184
- headerTextAlign?: import("./../../grid-component/type").ITextAlign;
185
191
  template?: import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | ((args: import("./../../grid-component/type").ColumnTemplate<RecordType>) => import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>);
186
192
  showTooltip?: boolean;
187
193
  tooltipDescription?: string | ((args: {
188
194
  value: any;
189
195
  rowData: RecordType;
190
196
  }) => import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>);
191
- headerTemplate?: import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | ((column: ColumnTable<RecordType>) => import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>);
192
- commandItems?: import("./../../grid-component/type").CommandItem[];
193
- children?: ColumnTable<RecordType>[];
197
+ onCellStyles?: Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width"> | ((cellValue: any, cell: import("@tanstack/react-table").Cell<RecordType, unknown>) => Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width">);
198
+ onCellHeaderStyles?: Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width"> | ((cell: import("@tanstack/react-table").Header<RecordType, unknown>) => Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width">);
199
+ onCell?: (rowData: RecordType, index: number) => import("react").TdHTMLAttributes<HTMLTableCellElement>;
200
+ onCellFooterStyles?: Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width"> | ((cellValue: any, cell: import("@tanstack/react-table").Header<RecordType, unknown>) => Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width">);
201
+ getValue?: (row: any, rowIndex: number) => any;
202
+ getCellProps?: (value: any, row: any, rowIndex: number) => import("./../../grid-component/type").CellProps;
203
+ headerCellProps?: import("./../../grid-component/type").CellProps;
204
+ getSpanRect?: (value: any, row: any, rowIndex: number) => import("./../../grid-component/type").SpanRect;
194
205
  editType?: EditType | ((rowData?: RecordType) => EditType);
195
206
  disable?: boolean | ((rowData: any) => boolean);
196
207
  editEnable?: boolean | ((rowData: any) => boolean);
@@ -203,18 +214,8 @@ export declare const fixColumnsLeft: <RecordType>(columns: ColumnTable<RecordTyp
203
214
  min?: number;
204
215
  editSelectSettings?: import("./../../grid-component/type").IEditSelectSettings;
205
216
  editFromSettings?: import("./../../grid-component/type").IEditFromSettings;
206
- fixedType?: import("./../../grid-component/type").FixedType;
207
- headerTextWrap?: boolean;
208
- ellipsis?: boolean;
209
- allowResizing?: boolean;
210
217
  allowSelection?: boolean | ((rowData: RecordType) => boolean);
211
- onCellStyles?: Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width"> | ((cellValue: any, cell: import("@tanstack/react-table").Cell<RecordType, unknown>) => Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width">);
212
- onCellHeaderStyles?: Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width"> | ((cell: import("@tanstack/react-table").Header<RecordType, unknown>) => Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width">);
213
- onCellFooterStyles?: Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width"> | ((cellValue: any, cell: import("@tanstack/react-table").Header<RecordType, unknown>) => Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width">);
214
- sumGroup?: boolean;
215
- getValue?: (row: any, rowIndex: number) => any;
216
- getCellProps?: (value: any, row: any, rowIndex: number) => import("./../../grid-component/type").CellProps;
217
- headerCellProps?: import("./../../grid-component/type").CellProps;
218
- getSpanRect?: (value: any, row: any, rowIndex: number) => import("./../../grid-component/type").SpanRect;
218
+ commandItems?: import("./../../grid-component/type").CommandItem[];
219
+ children?: ColumnTable<RecordType>[];
219
220
  }[];
220
221
  export declare function sortColumnsByField<T extends ColumnTable>(columns: T[], priorityFields: string[]): T[];
@@ -533,9 +533,8 @@ const EditableCell = props => {
533
533
  placeholder: t && column.placeholder ? t(column.placeholder) : tableLocal?.selectPlaceholder,
534
534
  allowClear: column.isClearable ?? false,
535
535
  maxTagCount: 'responsive',
536
- popupMatchSelectWidth: menuWidth ? menuWidth + 10 : undefined
537
- // optionFilterProp="label"
538
- ,
536
+ popupMatchSelectWidth: menuWidth ? menuWidth + 10 : undefined,
537
+ optionFilterProp: "label",
539
538
  popupClassName: 'be-popup-container',
540
539
  status: isInvalid ? 'error' : undefined,
541
540
  filterOption: filterKey ? (input, option) => {
@@ -672,9 +671,8 @@ const EditableCell = props => {
672
671
  placeholder: t && column.placeholder ? t(column.placeholder) : tableLocal?.selectPlaceholder,
673
672
  allowClear: column.isClearable ?? false,
674
673
  maxTagCount: 'responsive',
675
- popupMatchSelectWidth: menuWidth ? menuWidth + 10 : undefined
676
- // optionFilterProp="label"
677
- ,
674
+ popupMatchSelectWidth: menuWidth ? menuWidth + 10 : undefined,
675
+ optionFilterProp: "label",
678
676
  popupClassName: 'be-popup-container',
679
677
  loadOptions: loadOptions,
680
678
  status: isInvalid ? 'error' : undefined,
@@ -191,17 +191,6 @@ const TableBodyCell = props => {
191
191
  const record = cell.row.original;
192
192
  const columnMeta = cell.column.columnDef.meta ?? {};
193
193
  const cellStyles = typeof columnMeta.onCellStyles === 'function' ? columnMeta.onCellStyles(cell.getValue(), cell) : columnMeta.onCellStyles;
194
- const tooltipContent = _react.default.useMemo(() => {
195
- if (isOpenTooltip === false) {
196
- return '';
197
- } else {
198
- const abc = columnMeta?.tooltipDescription ? typeof columnMeta.tooltipDescription === 'function' ? columnMeta.tooltipDescription({
199
- value: cell.getValue(),
200
- rowData: record
201
- }) : columnMeta.tooltipDescription : cell.getValue();
202
- return abc;
203
- }
204
- }, [cell, columnMeta, isOpenTooltip, record]);
205
194
 
206
195
  // const tooltipContent: any = (isOpenTooltip === false)
207
196
  // ? ''
@@ -227,6 +216,18 @@ const TableBodyCell = props => {
227
216
  const cellValue = cell.getValue();
228
217
  const rowIndex = cell.row.index;
229
218
  const fomatedValue = (0, _useColumns.renderValueCell)(columnMeta, cellValue, record, rowIndex, colIndex, format, false);
219
+ const valueCellString = (0, _useColumns.getValueCellString)(columnMeta, cellValue, record, rowIndex, colIndex, format);
220
+ const tooltipContent = _react.default.useMemo(() => {
221
+ if (isOpenTooltip === false) {
222
+ return '';
223
+ } else {
224
+ const abc = columnMeta?.tooltipDescription ? typeof columnMeta.tooltipDescription === 'function' ? columnMeta.tooltipDescription({
225
+ value: cell.getValue(),
226
+ rowData: record
227
+ }) : columnMeta.tooltipDescription : valueCellString;
228
+ return abc;
229
+ }
230
+ }, [cell, columnMeta, isOpenTooltip, record, valueCellString]);
230
231
  if (cell.column.id === "#") {
231
232
  return /*#__PURE__*/_react.default.createElement("div", {
232
233
  key: cell.id,
@@ -244,10 +244,13 @@ const TableBodyCellEdit = props => {
244
244
  const [isOpenTooltip, setIsOpenTooltip] = _react.default.useState(false);
245
245
  const rowError = dataErrors ? dataErrors.find(it => it.id === cell.row.id) : undefined;
246
246
  const message = rowError && rowError[cell.column.id]?.field === cell.column.id ? rowError[cell.column.id].message : undefined;
247
- const tooltipContent = isOpenTooltip === false ? '' : columnMeta?.tooltipDescription ? typeof columnMeta.tooltipDescription === 'function' ? columnMeta.tooltipDescription({
248
- value: cell.getValue(),
249
- rowData: record
250
- }) : columnMeta.tooltipDescription : cell.getValue();
247
+
248
+ // const tooltipContent = (isOpenTooltip === false)
249
+ // ? ''
250
+ // : columnMeta?.tooltipDescription
251
+ // ? (typeof columnMeta.tooltipDescription === 'function' ? columnMeta.tooltipDescription({ value: cell.getValue(), rowData: record }) : columnMeta.tooltipDescription)
252
+ // : cell.getValue()
253
+
251
254
  const canEdit = (0, _utils.isEditable)(cell.column.columnDef.meta, record) && isRowEditable !== false;
252
255
 
253
256
  // const allRows = table.getRowModel().rows;
@@ -299,6 +302,19 @@ const TableBodyCellEdit = props => {
299
302
  const isLeftPaste = colIdxPaste === pasteRangeState.startColIndex;
300
303
  const isRightPaste = colIdxPaste === pasteRangeState.endColIndex;
301
304
  const parrents = cell.row.getParentRows();
305
+ const valeOfCell = cell.getValue();
306
+ const valueCellString = (0, _useColumns.getValueCellString)(columnMeta, valeOfCell, record, rowNumber, colIndex, format);
307
+ const tooltipContent = _react.default.useMemo(() => {
308
+ if (isOpenTooltip === false) {
309
+ return '';
310
+ } else {
311
+ const abc = columnMeta?.tooltipDescription ? typeof columnMeta.tooltipDescription === 'function' ? columnMeta.tooltipDescription({
312
+ value: cell.getValue(),
313
+ rowData: record
314
+ }) : columnMeta.tooltipDescription : valueCellString;
315
+ return abc;
316
+ }
317
+ }, [cell, columnMeta, isOpenTooltip, record, valueCellString]);
302
318
  const triggerDragPaste = (pasteState, ctrlKey) => {
303
319
  const tmpCols = table.getVisibleLeafColumns();
304
320
  const rowPasteIds = (0, _utils.getRowIdsBetween)(table, startPasteCell?.rowId ?? '', endPasteCell?.rowId ?? '');
@@ -203,7 +203,9 @@ const TableHeadCell2 = props => {
203
203
  doFilter,
204
204
  format,
205
205
  dataSourceFilter,
206
- tableLocal
206
+ tableLocal,
207
+ prevFilterValue: column.getFilterValue(),
208
+ triggerVisible
207
209
  })), /*#__PURE__*/_react.default.createElement(_antd.Space, {
208
210
  style: {
209
211
  justifyContent: 'end',
@@ -16,6 +16,8 @@ type RenderFilterProps<RecordType> = {
16
16
  dateRangeLocale?: any;
17
17
  doFilter?: (type: boolean) => void;
18
18
  tableLocal: any;
19
+ prevFilterValue?: string[];
20
+ triggerVisible?: (visible: boolean) => void;
19
21
  };
20
22
  export declare const renderFilter: <RecordType>(args: RenderFilterProps<RecordType>) => React.JSX.Element;
21
23
  export {};
@@ -19,6 +19,16 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
19
19
 
20
20
  // import type { AnyObject } from './type';
21
21
 
22
+ const isEqualDateArray = (arr1, arr2) => {
23
+ if (arr1?.length !== arr2?.length) {
24
+ return false;
25
+ }
26
+ return arr1?.every((item, index) => {
27
+ const date1 = new Date(item).getTime();
28
+ const date2 = new Date(arr2?.[index]).getTime();
29
+ return date1 === date2;
30
+ });
31
+ };
22
32
  const renderFilter = args => {
23
33
  const {
24
34
  column,
@@ -29,7 +39,9 @@ const renderFilter = args => {
29
39
  dataSourceFilter,
30
40
  format,
31
41
  doFilter,
32
- tableLocal
42
+ tableLocal,
43
+ prevFilterValue,
44
+ triggerVisible
33
45
  } = args;
34
46
  const {
35
47
  format: columnFormat,
@@ -106,10 +118,26 @@ const renderFilter = args => {
106
118
  onChange: value => {
107
119
  const newDateRangeValue = value ? [value[0] ? (0, _moment.default)(value[0]).format() : '', value[1] ? (0, _moment.default)(value[1]).format() : ''] : [];
108
120
  setSelectedKeys(newDateRangeValue);
109
- }
121
+ },
122
+ onOk: value => {
123
+ const newDateRangeValue = value ? [value[0] ? (0, _moment.default)(value[0]).format() : '', value[1] ? (0, _moment.default)(value[1]).format() : ''] : [];
124
+ setSelectedKeys(newDateRangeValue);
125
+ },
126
+ onExit: () => {
127
+ // clear nhưng chưa ấn OK
128
+ if (!dateRangeValue) {
129
+ return;
130
+ }
110
131
 
111
- // onSelect={(val) => {
112
- // }}
132
+ // Click ok
133
+ if (!isEqualDateArray(dateRangeValue, prevFilterValue)) {
134
+ // giá trị khác nhau
135
+ doFilter?.(true);
136
+ } else {
137
+ // giá trị = nhau
138
+ triggerVisible?.(false);
139
+ }
140
+ }
113
141
 
114
142
  // menuClassName="rc-menu-popup"
115
143
  ,