es-grid-template 0.0.7 → 0.0.13

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 (116) hide show
  1. package/LICENSE +21 -19
  2. package/es/{CheckboxFilter.d.ts → grid-component/CheckboxFilter.d.ts} +1 -1
  3. package/es/{CheckboxFilter.js → grid-component/CheckboxFilter.js} +7 -11
  4. package/es/grid-component/ColumnsChoose.d.ts +9 -0
  5. package/es/{ColumnsChoose.js → grid-component/ColumnsChoose.js} +66 -70
  6. package/es/grid-component/EditableCell.d.ts +19 -0
  7. package/es/grid-component/EditableCell.js +842 -0
  8. package/es/{FilterSearch.js → grid-component/FilterSearch.js} +2 -2
  9. package/es/grid-component/GridStyle.d.ts +4 -0
  10. package/es/grid-component/GridStyle.js +5 -0
  11. package/es/grid-component/InternalTable.d.ts +6 -0
  12. package/es/grid-component/InternalTable.js +283 -0
  13. package/es/grid-component/LoadingSpinner.d.ts +3 -0
  14. package/es/grid-component/LoadingSpinner.js +20 -0
  15. package/es/grid-component/Message/Message.d.ts +2 -0
  16. package/es/grid-component/Message/Message.js +16 -0
  17. package/es/grid-component/Message/index.d.ts +1 -0
  18. package/es/grid-component/Message/index.js +1 -0
  19. package/es/grid-component/TableGrid.d.ts +10 -0
  20. package/es/grid-component/TableGrid.js +375 -0
  21. package/es/grid-component/async-table-select/index.d.ts +9 -0
  22. package/es/grid-component/async-table-select/index.js +37 -0
  23. package/es/{hooks → grid-component/hooks}/constant.d.ts +14 -0
  24. package/es/{hooks → grid-component/hooks}/constant.js +17 -2
  25. package/es/grid-component/hooks/useColumns/index.d.ts +6 -0
  26. package/es/grid-component/hooks/useColumns/index.js +422 -0
  27. package/es/grid-component/hooks/utils.d.ts +35 -0
  28. package/es/{hooks → grid-component/hooks}/utils.js +147 -19
  29. package/es/grid-component/index.d.ts +2 -0
  30. package/es/grid-component/index.js +2 -0
  31. package/es/grid-component/rc-table/Grid.d.ts +8 -0
  32. package/es/grid-component/rc-table/Grid.js +99 -0
  33. package/es/grid-component/rc-table/GridEdit.d.ts +9 -0
  34. package/es/grid-component/rc-table/GridEdit.js +706 -0
  35. package/es/grid-component/type.d.ts +225 -0
  36. package/es/grid-component/useContext.d.ts +27 -0
  37. package/es/grid-component/useContext.js +4 -0
  38. package/es/index.d.ts +1 -2
  39. package/es/index.js +2 -2
  40. package/es/table-grid/styles.scss +551 -0
  41. package/lib/{CheckboxFilter.d.ts → grid-component/CheckboxFilter.d.ts} +1 -1
  42. package/lib/{CheckboxFilter.js → grid-component/CheckboxFilter.js} +11 -14
  43. package/lib/grid-component/ColumnsChoose.d.ts +9 -0
  44. package/lib/{ColumnsChoose.js → grid-component/ColumnsChoose.js} +66 -70
  45. package/lib/grid-component/EditableCell.d.ts +19 -0
  46. package/lib/grid-component/EditableCell.js +844 -0
  47. package/lib/{FilterSearch.js → grid-component/FilterSearch.js} +3 -3
  48. package/lib/grid-component/GridStyle.d.ts +4 -0
  49. package/lib/grid-component/GridStyle.js +12 -0
  50. package/lib/grid-component/InternalTable.d.ts +6 -0
  51. package/lib/grid-component/InternalTable.js +292 -0
  52. package/lib/grid-component/LoadingSpinner.d.ts +3 -0
  53. package/lib/grid-component/LoadingSpinner.js +29 -0
  54. package/lib/grid-component/Message/Message.d.ts +2 -0
  55. package/lib/grid-component/Message/Message.js +25 -0
  56. package/lib/grid-component/Message/index.d.ts +1 -0
  57. package/lib/grid-component/Message/index.js +16 -0
  58. package/lib/grid-component/TableGrid.d.ts +10 -0
  59. package/lib/grid-component/TableGrid.js +382 -0
  60. package/lib/grid-component/async-table-select/index.d.ts +9 -0
  61. package/lib/grid-component/async-table-select/index.js +46 -0
  62. package/lib/{hooks → grid-component/hooks}/constant.d.ts +14 -0
  63. package/lib/{hooks → grid-component/hooks}/constant.js +18 -3
  64. package/lib/grid-component/hooks/useColumns/index.d.ts +6 -0
  65. package/lib/grid-component/hooks/useColumns/index.js +435 -0
  66. package/lib/grid-component/hooks/utils.d.ts +35 -0
  67. package/lib/{hooks → grid-component/hooks}/utils.js +164 -22
  68. package/lib/grid-component/index.d.ts +2 -0
  69. package/lib/grid-component/index.js +9 -0
  70. package/lib/grid-component/rc-table/Grid.d.ts +8 -0
  71. package/lib/grid-component/rc-table/Grid.js +108 -0
  72. package/lib/grid-component/rc-table/GridEdit.d.ts +9 -0
  73. package/lib/grid-component/rc-table/GridEdit.js +715 -0
  74. package/lib/grid-component/type.d.ts +225 -0
  75. package/lib/grid-component/useContext.d.ts +27 -0
  76. package/lib/grid-component/useContext.js +10 -0
  77. package/lib/index.d.ts +1 -2
  78. package/lib/index.js +7 -3
  79. package/lib/table-grid/styles.scss +551 -0
  80. package/package.json +17 -6
  81. package/es/ColumnsChoose.d.ts +0 -10
  82. package/es/GridTable.d.ts +0 -7
  83. package/es/GridTable.js +0 -927
  84. package/es/hooks/useColumns/index.d.ts +0 -2
  85. package/es/hooks/useColumns/index.js +0 -25
  86. package/es/hooks/utils.d.ts +0 -18
  87. package/es/styles.scss +0 -30
  88. package/es/type.d.ts +0 -88
  89. package/lib/ColumnsChoose.d.ts +0 -10
  90. package/lib/GridTable.d.ts +0 -7
  91. package/lib/GridTable.js +0 -936
  92. package/lib/hooks/useColumns/index.d.ts +0 -2
  93. package/lib/hooks/useColumns/index.js +0 -31
  94. package/lib/hooks/utils.d.ts +0 -18
  95. package/lib/styles.scss +0 -30
  96. package/lib/type.d.ts +0 -88
  97. /package/es/{ContextMenu.d.ts → grid-component/ContextMenu.d.ts} +0 -0
  98. /package/es/{ContextMenu.js → grid-component/ContextMenu.js} +0 -0
  99. /package/es/{FilterSearch.d.ts → grid-component/FilterSearch.d.ts} +0 -0
  100. /package/es/{hooks → grid-component/hooks}/index.d.ts +0 -0
  101. /package/es/{hooks → grid-component/hooks}/index.js +0 -0
  102. /package/es/{hooks → grid-component/hooks}/useIsOverflow.d.ts +0 -0
  103. /package/es/{hooks → grid-component/hooks}/useIsOverflow.js +0 -0
  104. /package/es/{hooks → grid-component/hooks}/useOnClickOutside.d.ts +0 -0
  105. /package/es/{hooks → grid-component/hooks}/useOnClickOutside.js +0 -0
  106. /package/es/{type.js → grid-component/type.js} +0 -0
  107. /package/lib/{ContextMenu.d.ts → grid-component/ContextMenu.d.ts} +0 -0
  108. /package/lib/{ContextMenu.js → grid-component/ContextMenu.js} +0 -0
  109. /package/lib/{FilterSearch.d.ts → grid-component/FilterSearch.d.ts} +0 -0
  110. /package/lib/{hooks → grid-component/hooks}/index.d.ts +0 -0
  111. /package/lib/{hooks → grid-component/hooks}/index.js +0 -0
  112. /package/lib/{hooks → grid-component/hooks}/useIsOverflow.d.ts +0 -0
  113. /package/lib/{hooks → grid-component/hooks}/useIsOverflow.js +0 -0
  114. /package/lib/{hooks → grid-component/hooks}/useOnClickOutside.d.ts +0 -0
  115. /package/lib/{hooks → grid-component/hooks}/useOnClickOutside.js +0 -0
  116. /package/lib/{type.js → grid-component/type.js} +0 -0
package/es/GridTable.js DELETED
@@ -1,927 +0,0 @@
1
- import _extends from "@babel/runtime/helpers/esm/extends";
2
- import React, { Fragment, useLayoutEffect, useMemo, useRef, useState } from 'react';
3
- import { Table } from "ui-rc";
4
- import { Resizable } from 'react-resizable';
5
- import { createStyles } from 'antd-style';
6
- import { NumericFormat, numericFormatter } from "react-numeric-component";
7
- // import {Button, DatePicker, Input, Space} from "antd"
8
- import { SearchOutlined } from '@ant-design/icons';
9
- import { Select, Toolbar, DatePicker, Input } from "ui-rc";
10
- // import {flatColumns} from "../../hooks/useColumns";
11
- // import {
12
- // checkDecimalSeparator,
13
- // checkThousandSeparator,
14
- // convertDateToDayjs,
15
- // convertDayjsToDate,
16
- // getTypeFilter,
17
- // getDatepickerFormat,
18
- // isColor,
19
- // isEmpty,
20
- // numberOperator,
21
- // sumDataByField,
22
- // translateOption
23
- // } from "../hooks";
24
-
25
- // import type {ColumnsType, ColumnType, GridTableProps} from "../../type";
26
- import dayjs from "dayjs";
27
- import 'dayjs/locale/es';
28
- import 'dayjs/locale/vi';
29
- import "./styles.scss";
30
-
31
- // import en from 'antd/es/date-picker/locale/en_US'
32
-
33
- // import vi from 'antd/es/date-picker/locale/vi_VN'
34
-
35
- import moment from "moment";
36
- import CheckboxFilter from "./CheckboxFilter";
37
- import ContextMenu from "./ContextMenu";
38
- import { ColumnsChoose } from "./ColumnsChoose";
39
- import classNames from "classnames";
40
- // import type {PickerLocale} from "antd/es/date-picker/generatePicker";
41
-
42
- import { checkDecimalSeparator, checkThousandSeparator, convertDateToDayjs, convertDayjsToDate, getTypeFilter, getDatepickerFormat, isColor, isEmpty, numberOperator, sumDataByField, translateOption } from "./hooks";
43
- // import type {PickerLocale} from "ui-rc/dist/date-picker/generatePicker";
44
-
45
- import { Button } from "antd";
46
- import { flatColumns } from "./hooks/useColumns";
47
- const {
48
- RangePicker
49
- } = DatePicker;
50
- const convertFilters = filters => {
51
- const result = [];
52
- filters.forEach(({
53
- key,
54
- column,
55
- filteredKeys,
56
- operator
57
- }) => {
58
- if (!filteredKeys || filteredKeys.length === 0) return;
59
- if (column.typeFilter === "DateRange" && filteredKeys.length === 2) {
60
- result.push({
61
- key,
62
- field: column.dataIndex,
63
- value: filteredKeys[0],
64
- predicate: "and",
65
- operator: "greaterthanorequal"
66
- }, {
67
- key,
68
- field: column.dataIndex,
69
- value: filteredKeys[1],
70
- predicate: "and",
71
- operator: "lessthanorequal"
72
- });
73
- } else if (column.typeFilter === 'Checkbox') {
74
- filteredKeys.forEach(value => {
75
- result.push({
76
- key,
77
- field: column.dataIndex,
78
- value,
79
- predicate: "or",
80
- operator
81
- });
82
- });
83
- } else {
84
- result.push({
85
- key,
86
- field: column.dataIndex,
87
- value: filteredKeys[0],
88
- predicate: 'and',
89
- operator
90
- });
91
- }
92
- });
93
- return result;
94
- };
95
- const ResizableTitle = props => {
96
- const {
97
- onResize,
98
- width,
99
- ...restProps
100
- } = props;
101
- if (!width) {
102
- return /*#__PURE__*/React.createElement("th", restProps);
103
- }
104
- return (
105
- /*#__PURE__*/
106
- // @ts-ignore
107
- React.createElement(Resizable, {
108
- width: width,
109
- height: 0,
110
- handle: /*#__PURE__*/React.createElement("span", {
111
- className: "react-resizable-handle",
112
- onClick: e => {
113
- e.stopPropagation();
114
- }
115
- }),
116
- onResize: onResize,
117
- draggableOpts: {
118
- enableUserSelectHack: false
119
- }
120
- }, /*#__PURE__*/React.createElement("th", restProps))
121
- );
122
- };
123
- const useStyle = createStyles(({
124
- css
125
- }) => {
126
- // const { antCls } = token
127
- const antCls = 'ui-rc';
128
- return {
129
- customTable: css`
130
- ${antCls}-table {
131
- ${antCls}-table-container {
132
- ${antCls}-table-body,
133
- ${antCls}-table-content {
134
- scrollbar-width: thin;
135
- scrollbar-color: #eaeaea transparent;
136
- scrollbar-gutter: stable;
137
- }
138
- }
139
- }
140
- `
141
- };
142
- });
143
- const GridTable = props => {
144
- const {
145
- columns: defaultColumns,
146
- dataSource,
147
- format,
148
- virtual = true,
149
- t,
150
- lang,
151
- contextMenuOpen,
152
- contextMenuItems: propContextMenuItems,
153
- contextMenuHidden,
154
- contextMenuClick,
155
- recordDoubleClick,
156
- toolbarItems,
157
- showColumnChoose,
158
- onFilter,
159
- selectionSettings,
160
- rowSelection,
161
- rowSelected,
162
- rowKey = 'id',
163
- ...rest
164
- } = props;
165
- const {
166
- styles
167
- } = useStyle();
168
-
169
- // const locale = lang && lang === 'en' ? en : vi
170
-
171
- // const buddhistLocale: PickerLocale = {
172
- // ...locale,
173
- // lang: {
174
- // ...locale.lang
175
- //
176
- // }
177
- // }
178
-
179
- // console.log('buddhistLocale', buddhistLocale)
180
- const clickRef = useRef(null);
181
- const searchInput = useRef(null);
182
- const menuRef = useRef(null);
183
- const viewportWidth = window.innerWidth;
184
- const viewportHeight = window.innerHeight;
185
- const defaultSelected = useMemo(() => {
186
- return selectionSettings?.defaultSelectedRowKeys ?? [];
187
- }, [selectionSettings?.defaultSelectedRowKeys]);
188
- const [menuVisible, setMenuVisible] = React.useState(false);
189
- const [selectedRowData, setSelectedRowData] = React.useState(null);
190
- const [position, setPosition] = React.useState({
191
- x: 0,
192
- y: 0,
193
- viewportWidth,
194
- viewportHeight
195
- });
196
- // const [filters, setFilters] = React.useState<any[]>([])
197
-
198
- const [selectedRowKeys, setSelectedRowKeys] = useState(defaultSelected);
199
- const contextMenuItems = React.useMemo(() => {
200
- if (typeof contextMenuHidden === "function" && propContextMenuItems && selectedRowData) {
201
- const hiddenItems = contextMenuHidden({
202
- rowInfo: {
203
- rowData: selectedRowData
204
- }
205
- });
206
- return propContextMenuItems.filter(item => !hiddenItems.includes(item?.key));
207
- }
208
- if (contextMenuHidden && typeof contextMenuHidden !== 'function' && propContextMenuItems) {
209
- return propContextMenuItems.filter(item => !contextMenuHidden.includes(item?.key));
210
- }
211
- return propContextMenuItems;
212
- }, [propContextMenuItems, contextMenuHidden, selectedRowData]);
213
- useLayoutEffect(() => {
214
- setMenuVisible(false);
215
- }, []);
216
- const handleSearch = (selectedKeys, confirm
217
- // dataIndex: any
218
- ) => {
219
- confirm();
220
- };
221
- const renderFilter = (column, selectedKeys, setSelectedKeys, confirm, visible, searchValue, setSearchValue) => {
222
- const type = getTypeFilter(column);
223
- const dateFormat = getDatepickerFormat(column.type, column) ?? 'DD/MM/YYYY';
224
- const dateRangeFormat = getDatepickerFormat(column.type, column) ?? 'DD/MM/YYYY';
225
- switch (type) {
226
- case 'Number':
227
- return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
228
- className: 'mb-1'
229
- }, /*#__PURE__*/React.createElement(NumericFormat, {
230
- value: selectedKeys[0]
231
- // thousandSeparator={checkThousandSeparator(thousandSeparator, decimalSeparator)}
232
- // decimalSeparator={checkDecimalSeparator(thousandSeparator, decimalSeparator)}
233
- // allowNegative={col.format && col.format.allowNegative === true}
234
- ,
235
- allowNegative: true,
236
- customInput: Input,
237
- className: ' rounded-0 input-element form-control',
238
- onValueChange: values => {
239
- // onChangeValueFilter(type, values.floatValue)
240
- setSelectedKeys(values.floatValue || values.floatValue === 0 ? [values.floatValue] : []);
241
- }
242
- }))));
243
- case 'NumberRange':
244
- return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
245
- className: 'mb-1 d-flex flex-column gap-1'
246
- }, /*#__PURE__*/React.createElement("div", {
247
- style: {
248
- marginBottom: 8
249
- }
250
- }, /*#__PURE__*/React.createElement(NumericFormat, {
251
- value: selectedKeys[0]
252
- // thousandSeparator={checkThousandSeparator(thousandSeparator, decimalSeparator)}
253
- // decimalSeparator={checkDecimalSeparator(thousandSeparator, decimalSeparator)}
254
- ,
255
- allowNegative: true,
256
- customInput: Input,
257
- className: ' rounded-0 input-element form-control'
258
- // onValueChange={(values: any) => {
259
- // onChangeValueFilter(type, values.floatValue, 'min')
260
- // }}
261
- ,
262
- placeholder: 'Min',
263
- autoFocus: true
264
- })), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(NumericFormat, {
265
- value: selectedKeys[1]
266
- // thousandSeparator={checkThousandSeparator(thousandSeparator, decimalSeparator)}
267
- // decimalSeparator={checkDecimalSeparator(thousandSeparator, decimalSeparator)}
268
- ,
269
- allowNegative: true,
270
- customInput: Input,
271
- className: ' rounded-0 input-element form-control',
272
- onValueChange: () => {
273
- // onChangeValueFilter(type, values.floatValue, 'max')
274
- },
275
- placeholder: 'Max'
276
- })))));
277
- case 'Date':
278
- const dateValue = selectedKeys[0] ? convertDateToDayjs(new Date(selectedKeys[0]), dateFormat) : null;
279
- return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
280
- className: 'mb-1'
281
- }, /*#__PURE__*/React.createElement(DatePicker, {
282
- format: {
283
- format: dateFormat,
284
- type: 'mask'
285
- }
286
- // locale={buddhistLocale}
287
- ,
288
- style: {
289
- width: '100%',
290
- height: '100%'
291
- },
292
- value: dateValue,
293
- defaultValue: dateValue,
294
- placeholder: column.placeholder,
295
- onChange: (valueDate, dateString) => {
296
- const newDateValue = dateString ? moment(convertDayjsToDate(dateString, dateFormat)).format() : null;
297
- setSelectedKeys(newDateValue ? [newDateValue] : []);
298
- }
299
- }))));
300
- case 'DateRange':
301
- const dateRangeValue = [selectedKeys[0] ? convertDateToDayjs(new Date(selectedKeys[0]), dateRangeFormat) : '', selectedKeys[1] ? convertDateToDayjs(new Date(selectedKeys[1]), dateRangeFormat) : ''];
302
- return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
303
- className: 'mb-1'
304
- }, /*#__PURE__*/React.createElement(RangePicker, {
305
- format: {
306
- format: dateRangeFormat,
307
- type: 'mask'
308
- }
309
- // defaultValue={dateRangeValue}
310
- ,
311
- value: dateRangeValue,
312
- placeholder: ['Ngày bắt đầu', 'Ngày kết thúc'],
313
- popupStyle: {
314
- zIndex: 9999
315
- },
316
- onChange: (value, dateString) => {
317
- const newDateRangeValue = dateString[0] ? [dateString[0] ? moment(convertDayjsToDate(dateString[0], dateRangeFormat)).format() : '', dateString[1] ? moment(convertDayjsToDate(dateString[1], dateRangeFormat)).format() : ''] : '';
318
-
319
- // setSelectedKeys(newDateValue ? [newDateValue] : [])
320
- setSelectedKeys(newDateRangeValue);
321
- },
322
- style: {
323
- width: '100%'
324
- }
325
- // popupClassName={'adv-popup-container'}
326
- // getPopupContainer={() => menuRef.current}
327
- }))));
328
- case 'Dropdown':
329
- return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
330
- className: 'mb-1'
331
- }, /*#__PURE__*/React.createElement(Select, {
332
- options: translateOption(numberOperator, t),
333
- style: {
334
- width: '100%',
335
- marginBottom: 8
336
- },
337
- value: selectedKeys[0],
338
- onChange: val => {
339
- // setOperatorKey(val)
340
- setSelectedKeys(val ? [val] : []);
341
- },
342
- showSearch: true,
343
- allowClear: true
344
- }))));
345
-
346
- // case 'DropTree':
347
- // return (
348
- // <Fragment>
349
- // <div>
350
- // {col.filterOption && col.filterOption.showOperator === false ? (
351
- // ''
352
- // ) : (
353
- // <div className={'mb-1'}>
354
- // <Select
355
- // options={translateOption(numberOperator, t)}
356
- // // options={t ? numberOperator.map((it: any) => ({...it, label: t(it.label)})) : numberOperator}
357
- //
358
- // classNamePrefix='select'
359
- // className={`react-select`}
360
- // value={translateOption(numberOperator, t).find(
361
- // ope => ope.value === (operator ? operator : getDefaultOperator(col))
362
- // )}
363
- // onChange={(val: any) => {
364
- // setCurrentFilter((prevState: any) => ({ ...prevState, operator: val.value }))
365
- // }}
366
- // />
367
- // </div>
368
- // )}
369
- //
370
- // <div className={'mb-1'}>
371
- // <Input
372
- // placeholder={'Nhập giá trị'}
373
- // value={value}
374
- // onChange={(val: any) => {
375
- // onChangeValueFilter(type, val.value)
376
- // }}
377
- // />
378
- // </div>
379
- //
380
- // <div className={'d-flex justify-content-end'}>
381
- // <Button color='flat-primary' className={'me-1 be-button'} onClick={(e: any) => handleOnFilter(e)}>
382
- // {t ? t('Filter') : 'Filter'}
383
- // </Button>
384
- // <Button color='flat-secondary' className={'be-button'} onClick={(e: any) => handleClearFilter(e)}>
385
- // {t ? t('Delete') : 'Delete'}
386
- // </Button>
387
- // </div>
388
- // </div>
389
- // </Fragment>
390
- // )
391
- //
392
- case 'Checkbox':
393
- return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
394
- className: 'mb-1'
395
- }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(CheckboxFilter
396
- // column={column}
397
- , {
398
- locale: {
399
- filterTitle: 'Chọn tất cả',
400
- filterCheckall: 'Chọn tất cả'
401
- },
402
- selectedKeys: selectedKeys,
403
- onSelect: setSelectedKeys,
404
- options: [{
405
- text: 'Joe',
406
- value: 'Joe'
407
- }, {
408
- text: 'Jim',
409
- value: 'Jim'
410
- }, {
411
- text: 'Green',
412
- value: 'Green'
413
- }, {
414
- text: 'Black',
415
- value: 'Black'
416
- }, {
417
- text: 'Category 1',
418
- value: 'Category 1'
419
- }, {
420
- text: 'Yellow',
421
- value: 'Yellow'
422
- }, {
423
- text: 'Pink',
424
- value: 'Pink'
425
- }, {
426
- text: 'Category 2',
427
- value: 'Category 666'
428
- }, {
429
- text: 'Category 2',
430
- value: 'Category 555'
431
- }, {
432
- text: 'Category 2',
433
- value: 'Category 55'
434
- }, {
435
- text: 'Category 2',
436
- value: 'Category 44'
437
- }, {
438
- text: 'Category 2',
439
- value: 'Category 33'
440
- }, {
441
- text: 'Category 2',
442
- value: 'Category 22'
443
- }, {
444
- text: 'Category 2',
445
- value: 'Category 11'
446
- }
447
- // {
448
- // text: 'Submenu',
449
- // value: 'Submenu',
450
- // children: [
451
- // {
452
- // text: 'Green',
453
- // value: 'Green',
454
- // },
455
- // {
456
- // text: 'Black',
457
- // value: 'Black',
458
- // },
459
- // ],
460
- // },
461
- ],
462
- filterMultiple: true,
463
- open: visible,
464
- searchValue: searchValue,
465
- setSearchValue: setSearchValue
466
- })))));
467
- case 'Text':
468
- default:
469
- return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
470
- className: 'mb-1'
471
- }, /*#__PURE__*/React.createElement(Input, {
472
- ref: searchInput,
473
- placeholder: `Search ${column.key}`,
474
- value: selectedKeys[0],
475
- onChange: e => setSelectedKeys(e.target.value ? [e.target.value] : []),
476
- onPressEnter: () => handleSearch(selectedKeys, confirm),
477
- allowClear: true
478
- }))));
479
- }
480
- };
481
- const getColumnSearchProps = column => ({
482
- filterDropdown: ({
483
- setSelectedKeys,
484
- selectedKeys,
485
- confirm,
486
- // clearFilters,
487
- close,
488
- setOperatorKey,
489
- operatorKey,
490
- visible,
491
- searchValue,
492
- setSearchValue
493
- }) => {
494
- // const typeFilter = getTypeFilter(columns as RcColumnType)
495
- return /*#__PURE__*/React.createElement("div", {
496
- style: {
497
- padding: 8,
498
- minWidth: 275
499
- },
500
- onKeyDown: e => e.stopPropagation()
501
- }, (column.showOperator !== false || column.typeFilter !== 'DateRange' && column.typeFilter !== 'NumberRange') && /*#__PURE__*/React.createElement("div", {
502
- className: 'mb-1'
503
- }, /*#__PURE__*/React.createElement(Select, {
504
- options: translateOption(numberOperator, t),
505
- style: {
506
- width: '100%',
507
- marginBottom: 8
508
- },
509
- value: operatorKey,
510
- onChange: val => {
511
- setOperatorKey(val);
512
- }
513
- })), /*#__PURE__*/React.createElement("div", {
514
- style: {
515
- marginBottom: 8
516
- }
517
- }, renderFilter(column, selectedKeys, setSelectedKeys, confirm, visible, searchValue, setSearchValue)), /*#__PURE__*/React.createElement("div", {
518
- style: {
519
- justifyContent: 'end',
520
- width: '100%'
521
- }
522
- }, /*#__PURE__*/React.createElement(Button, {
523
- type: "primary",
524
- onClick: () => {
525
- confirm({
526
- closeDropdown: false
527
- });
528
- handleSearch(selectedKeys, confirm);
529
- },
530
- icon: /*#__PURE__*/React.createElement(SearchOutlined, null),
531
- size: "small",
532
- style: {
533
- width: 90
534
- }
535
- }, "Filter"), /*#__PURE__*/React.createElement(Button, {
536
- type: "link",
537
- size: "small",
538
- onClick: () => {
539
- close();
540
- }
541
- }, "close")));
542
- },
543
- // filterIcon: (filtered: boolean) => (
544
- // <SearchOutlined style={{ color: filtered ? '#1677ff' : undefined }} />
545
- // ),
546
-
547
- onFilter: (value, record) => {
548
- // @ts-ignore
549
- return record[column.dataIndex];
550
- },
551
- filterDropdownProps: {
552
- onOpenChange(open) {
553
- if (open) {
554
- setTimeout(() => searchInput.current?.select(), 100);
555
- }
556
- }
557
-
558
- // trigger: ['hover']
559
- }
560
- });
561
- const renderContent = column => value => {
562
- switch (column?.type) {
563
- case 'number':
564
- const thousandSeparator = column.format?.thousandSeparator ? column.format?.thousandSeparator : format?.thousandSeparator;
565
- const decimalSeparator = column.format?.decimalSeparator ? column.format?.decimalSeparator : format?.decimalSeparator;
566
- const dec = column.format?.decimalScale || column.format?.decimalScale === 0 ? column.format?.decimalScale : format?.decimalScale;
567
- const content = !isEmpty(value) ? dec || dec === 0 ? parseFloat(Number(value).toFixed(dec)).toString() : value.toString() : '0';
568
- const numericFormatProps = {
569
- thousandSeparator: checkThousandSeparator(thousandSeparator, decimalSeparator),
570
- decimalSeparator: checkDecimalSeparator(thousandSeparator, decimalSeparator),
571
- allowNegative: (column.format?.allowNegative ? column.format?.allowNegative : format?.allowNegative) ?? true,
572
- prefix: column.format?.prefix ? column.format?.prefix : format?.prefix,
573
- suffix: column.format?.suffix ? column.format?.suffix : format?.suffix,
574
- decimalScale: column.format?.decimalScale || column.format?.decimalScale === 0 ? column.format?.decimalScale : format?.decimalScale,
575
- fixedDecimalScale: (column.format?.fixedDecimalScale ? column.format?.fixedDecimalScale : format?.fixedDecimalScale) ?? false
576
- };
577
- return !isEmpty(content) ? numericFormatter(content, numericFormatProps) : '';
578
- case 'date':
579
- return value ? dayjs(value).format(column.format?.dateFormat ?? format?.dateFormat ?? 'DD/MM/YYYY') : '';
580
- case 'time':
581
- return value ? value : '';
582
- case 'year':
583
- const year = value ? moment(value).format('yyyy') : '';
584
- return /*#__PURE__*/React.createElement(Fragment, null, year);
585
- case 'datetime':
586
- return value ? moment(value).format(column.format?.datetimeFormat ?? format?.datetimeFormat ?? 'DD/MM/YYYY HH:mm') : '';
587
- case 'boolean':
588
- return value ? 'true' : 'false';
589
- case 'color':
590
- return /*#__PURE__*/React.createElement(Fragment, null, isColor(value) ? /*#__PURE__*/React.createElement("div", {
591
- className: 'w-100 h-100',
592
- style: {
593
- backgroundColor: value,
594
- border: '1px solid #f0f0f0'
595
- }
596
- }) : '');
597
- case 'checkbox':
598
- return /*#__PURE__*/React.createElement(Input, {
599
- checked: !!content,
600
- readOnly: true,
601
- type: "checkbox"
602
- });
603
- case 'file':
604
- const nameFile = typeof value === 'object' && !Array.isArray(value) ? value.name : Array.isArray(value) ? value.map(it => typeof it === 'object' ? it.name : it).filter(Boolean).join(", ") : '';
605
- return value ? nameFile : '';
606
- default:
607
- if (Array.isArray(value)) {
608
- return value.join(', ');
609
- }
610
- return value;
611
- }
612
- };
613
- const addIsFilter = columns => {
614
- return columns.map(column => {
615
- // @ts-ignore
616
- if (!column?.dataIndex && !column.key) {
617
- return column;
618
- }
619
- // @ts-ignore
620
- if (column?.children && column.children.length > 0) {
621
- return {
622
- ...column,
623
- // @ts-ignore
624
- children: addIsFilter(column.children) // Xử lý đệ quy cho cấp con
625
- };
626
- }
627
- // @ts-ignore
628
- if (column?.dataIndex === 'index' || column.allowFiltering === false) {
629
- return {
630
- ...column
631
- };
632
- }
633
- return {
634
- ...getColumnSearchProps(column),
635
- render: renderContent(column),
636
- ...column
637
- };
638
- });
639
- };
640
- const tmpColumns = useMemo(() => {
641
- // return addIsFilter(defaultColumns ?? [])
642
- return addIsFilter(defaultColumns ? [Table.SELECTION_COLUMN, ...defaultColumns] : []);
643
- }, [defaultColumns]);
644
- const [columns, setColumns] = useState(tmpColumns ?? []);
645
- const handleResize = indexPath => (e, {
646
- size
647
- }) => {
648
- const updateColumns = (cols, path) => {
649
- const [currentIndex, ...restPath] = path;
650
- return cols.map((col, idx) => {
651
- if (idx === currentIndex) {
652
- if (restPath.length === 0) {
653
- // Cập nhật width của cột cuối cùng trong path
654
- // return { ...col, width: size.width }
655
-
656
- // Kiểm tra minWidth trước khi cập nhật width
657
- if (col.minWidth && size.width < col.minWidth) {
658
- e.preventDefault();
659
- return col; // Không cập nhật nếu nhỏ hơn minWidth
660
- }
661
-
662
- // Kiểm tra minWidth trước khi cập nhật width
663
- if (col.maxWidth && size.width > col.maxWidth) {
664
- e.preventDefault();
665
- return col; // Không cập nhật nếu nhỏ hơn minWidth
666
- }
667
- return {
668
- ...col,
669
- width: size.width
670
- };
671
- } else if (col.children) {
672
- // Tiếp tục cập nhật các cấp con
673
- return {
674
- ...col,
675
- children: updateColumns(col.children, restPath)
676
- };
677
- }
678
- }
679
- // e.preventDefault()
680
- return col;
681
- });
682
- };
683
- setColumns(prevColumns => updateColumns(prevColumns, indexPath));
684
- };
685
- const addResizeHandlers = (cols, parentPath = []) => {
686
- return cols.map((col, index) => {
687
- const currentPath = [...parentPath, index];
688
- if (!col?.dataIndex && !col.key) {
689
- return col;
690
- }
691
- if (col.children) {
692
- return {
693
- ...col,
694
- ellipsis: col.ellipsis !== true,
695
- children: addResizeHandlers(col.children, currentPath)
696
- };
697
- }
698
- return {
699
- ...col,
700
- ellipsis: col.ellipsis !== true,
701
- onHeaderCell: () => ({
702
- width: col.width,
703
- onResize: handleResize(currentPath)
704
- })
705
- };
706
- });
707
- };
708
-
709
- // const resizableColumns = createResizableColumns(columns)
710
-
711
- // const resizableColumns = addResizeHandlers(columns)
712
- const resizableColumns = useMemo(() => {
713
- return addResizeHandlers(columns);
714
- }, [columns]);
715
-
716
- // const handleReset = (clearFilters: () => void) => {
717
- // clearFilters()
718
- // }
719
-
720
- // const handleChangeOperator = (val: IFilterOperator) => {
721
- // setOperator(val)
722
- // }
723
-
724
- const onContextMenu = data => event => {
725
- event.preventDefault(); // Ngăn chặn menu mặc định của trình duyệt
726
-
727
- setSelectedRowData(data);
728
- contextMenuOpen?.({
729
- rowInfo: {
730
- rowData: data
731
- },
732
- event
733
- });
734
- setMenuVisible(true);
735
-
736
- // Đợi DOM cập nhật và lấy kích thước menu
737
- setTimeout(() => {
738
- const menuElement = menuRef.current; // Lấy menu từ DOM
739
- const menuWidth = menuElement?.offsetWidth || 200; // Mặc định 200px nếu chưa render
740
- const menuHeight = menuElement?.offsetHeight; // Mặc định 450px nếu chưa render
741
-
742
- // Điều chỉnh vị trí menu
743
- let x = event.clientX;
744
- let y = event.clientY;
745
- if (x + menuWidth > viewportWidth) {
746
- x = x - menuWidth - 10; // Cách cạnh phải 10px
747
- }
748
- if (y + menuHeight > viewportHeight) {
749
- if (y < menuHeight) {
750
- y = 10;
751
- } else {
752
- y = y - 10 - menuHeight; // Cách cạnh dưới 10px
753
- }
754
- }
755
- setPosition(prevState => ({
756
- ...prevState,
757
- x,
758
- y
759
- }));
760
- }, 100);
761
- if (!menuVisible) {
762
- document.addEventListener(`click`, function onClickOutside(e) {
763
- const element = e.target;
764
- const menuContainer = document.querySelector(".popup-context-menu");
765
- const isInsideContainer = element.closest(".popup-context-menu") && menuContainer;
766
- if (isInsideContainer) {
767
- return;
768
- }
769
- setMenuVisible(false);
770
- document.removeEventListener(`click`, onClickOutside);
771
- });
772
- }
773
- };
774
- const handleRowClick = () => {
775
- if (clickRef.current) return;
776
-
777
- // @ts-ignore
778
- clickRef.current = setTimeout(() => {
779
- // console.log("Single Click:", record);
780
- clickRef.current = null;
781
- }, 250);
782
- };
783
- const handleRowDoubleClick = (record, index) => e => {
784
- if (clickRef.current) {
785
- clearTimeout(clickRef.current);
786
- clickRef.current = null;
787
- }
788
- recordDoubleClick?.({
789
- e,
790
- rowIndex: index,
791
- rowData: record
792
- });
793
- };
794
- const onSelectChange = (keys, selectedRows, info, selectedRow) => {
795
- if (info.type === 'all') {
796
- // setSelectedRowKeys(keys)
797
- rowSelected?.({
798
- selected: selectedRows,
799
- type: 'rowSelected',
800
- rowData: {}
801
- });
802
- } else {
803
- if (selectionSettings?.type === 'multiple') {
804
- // setSelectedRowKeys(keys)
805
- rowSelected?.({
806
- selected: selectedRows,
807
- type: 'rowSelected',
808
- rowData: selectedRow
809
- });
810
- } else {
811
- // @ts-ignore
812
- setSelectedRowKeys([selectedRow[rowKey]]);
813
- rowSelected?.({
814
- selected: [selectedRow],
815
- type: 'rowSelected',
816
- rowData: selectedRow
817
- });
818
- }
819
- }
820
- };
821
- return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(ContextMenu, {
822
- open: menuVisible,
823
- pos: position,
824
- setOpen: setMenuVisible,
825
- menuRef: menuRef,
826
- contextMenuItems: contextMenuItems,
827
- contextMenuClick: contextMenuClick,
828
- rowData: selectedRowData
829
- }), /*#__PURE__*/React.createElement(Table, _extends({}, rest, {
830
- dataSource: dataSource
831
- // className={styles.customTable}
832
- ,
833
- className: classNames('', {
834
- 'table-none-column-select': selectionSettings?.mode === undefined && selectionSettings?.type !== 'multiple'
835
- }, styles.customTable),
836
- bordered: true,
837
- virtual: virtual,
838
- columns: resizableColumns,
839
- rowKey: rowKey,
840
- rowHoverable: true,
841
- components: {
842
- header: {
843
- cell: ResizableTitle
844
- }
845
- },
846
- onRow: (data, index) => {
847
- return {
848
- onDoubleClick: handleRowDoubleClick(data, index),
849
- // onClick: handleRowClick(data),
850
- onClick: handleRowClick,
851
- onContextMenu: onContextMenu(data)
852
- };
853
- },
854
- rowSelection: {
855
- type: selectionSettings?.mode === 'checkbox' || selectionSettings?.type === 'multiple' ? 'checkbox' : "radio",
856
- // columnWidth: selectionSettings?.mode === 'checkbox' || selectionSettings?.mode === 'radio' || selectionSettings?.type === 'multiple' ? 50 : 0.000001,
857
- columnWidth: !selectionSettings?.mode ? 0.0000001 : selectionSettings?.columnWidth ?? 50,
858
- onChange: onSelectChange,
859
- // onSelect: (record, selected, selectedRows, nativeEvent)=> {
860
- // // console.log(record, selected, selectedRows, nativeEvent)
861
- // },
862
-
863
- selectedRowKeys: selectionSettings?.mode === 'checkbox' && selectionSettings?.type === 'single' ? selectedRowKeys : undefined,
864
- defaultSelectedRowKeys: selectionSettings?.defaultSelectedRowKeys,
865
- preserveSelectedRowKeys: true,
866
- ...rowSelection,
867
- // hideSelectAll: !selectionSettings?.type || selectionSettings?.type === 'single' || selectionSettings?.mode === 'radio' ? true : rowSelection?.hideSelectAll ?? selectionSettings?.type !== 'multiple',
868
- hideSelectAll: !selectionSettings?.type || selectionSettings?.type === 'single' || selectionSettings?.mode === 'radio' ? true : selectionSettings?.hideSelectAll ?? selectionSettings?.type !== 'multiple'
869
- },
870
- onScroll: () => {
871
- setMenuVisible(false);
872
- },
873
- title: () => {
874
- return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", null, "Header"), toolbarItems && /*#__PURE__*/React.createElement("div", {
875
- style: {
876
- display: 'flex',
877
- justifyContent: 'space-between'
878
- }
879
- }, /*#__PURE__*/React.createElement(Toolbar, {
880
- style: {
881
- width: '100%'
882
- },
883
- items: toolbarItems,
884
- mode: 'responsive'
885
- // mode={'scroll'}
886
- ,
887
- onClick: val => {
888
- console.log(val);
889
- }
890
- }), showColumnChoose && /*#__PURE__*/React.createElement(ColumnsChoose, {
891
- columns: columns,
892
- setColumns: setColumns
893
- }), /*#__PURE__*/React.createElement("div", null)));
894
- },
895
- summary: () => /*#__PURE__*/React.createElement(Table.Summary, {
896
- fixed: true
897
- }, /*#__PURE__*/React.createElement(Table.Summary.Row, null, flatColumns(tmpColumns).filter(col => col.hidden !== true).map((col, index) => {
898
- const thousandSeparator = col.format?.thousandSeparator ? col.format?.thousandSeparator : format?.thousandSeparator;
899
- const decimalSeparator = col.format?.decimalSeparator ? col.format?.decimalSeparator : format?.decimalSeparator;
900
- const dec = col.format?.decimalScale || col.format?.decimalScale === 0 ? col.format?.decimalScale : format?.decimalScale;
901
- const sumValue = col.type === 'number' ? sumDataByField(dataSource, col?.key) : 0;
902
- const value = !isEmpty(sumValue) ? dec || dec === 0 ? parseFloat(Number(sumValue).toFixed(dec)).toString() : sumValue.toString() : '0';
903
- const cellValue = col.type === 'number' && col.isSummary !== false ? value : '';
904
- const numericFormatProps = {
905
- thousandSeparator: checkThousandSeparator(thousandSeparator, decimalSeparator),
906
- decimalSeparator: checkDecimalSeparator(thousandSeparator, decimalSeparator),
907
- allowNegative: (col.format?.allowNegative ? col.format?.allowNegative : format?.allowNegative) ?? false,
908
- prefix: col.format?.prefix ? col.format?.prefix : format?.prefix,
909
- suffix: col.format?.suffix ? col.format?.suffix : format?.suffix,
910
- decimalScale: dec,
911
- fixedDecimalScale: (col.format?.fixedDecimalScale ? col.format?.fixedDecimalScale : format?.fixedDecimalScale) ?? false
912
- };
913
- return (
914
- /*#__PURE__*/
915
- // <Table.Summary.Cell index={index}>{col.summaryTemplate ? col.summaryTemplate(cellValue, (col.key || col.dataIndex) as string) : numericFormatter(cellValue, numericFormatProps)}</Table.Summary.Cell>
916
- React.createElement(Table.Summary.Cell, {
917
- key: index,
918
- index: index
919
- }, col.summaryTemplate ? col.summaryTemplate(cellValue, col.key) : numericFormatter(cellValue, numericFormatProps))
920
- );
921
- }))),
922
- onFilter: val => {
923
- onFilter?.(convertFilters(val));
924
- }
925
- })));
926
- };
927
- export default GridTable;