@addev-be/ui 0.14.1 → 0.14.2
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.
- package/assets/icons/floppy-disk.svg +1 -0
- package/package.json +2 -1
- package/src/Icons.tsx +2 -0
- package/src/components/data/DataGrid/DataGridCell.tsx +3 -3
- package/src/components/data/DataGrid/DataGridColumnsModal/helpers.ts +7 -12
- package/src/components/data/DataGrid/DataGridColumnsModal/hooks.tsx +2 -2
- package/src/components/data/DataGrid/DataGridColumnsModal/index.tsx +31 -30
- package/src/components/data/DataGrid/DataGridEditableCell/CheckboxEditableCell.tsx +38 -0
- package/src/components/data/DataGrid/DataGridEditableCell/DateEditableCell.tsx +39 -0
- package/src/components/data/DataGrid/DataGridEditableCell/NumberEditableCell.tsx +68 -0
- package/src/components/data/DataGrid/DataGridEditableCell/TextEditableCell.tsx +38 -0
- package/src/components/data/DataGrid/DataGridEditableCell/index.tsx +60 -0
- package/src/components/data/DataGrid/DataGridEditableCell/types.ts +14 -0
- package/src/components/data/DataGrid/DataGridFilterMenu/hooks.tsx +13 -10
- package/src/components/data/DataGrid/DataGridFilterMenu/index.tsx +27 -29
- package/src/components/data/DataGrid/DataGridFooter.tsx +3 -3
- package/src/components/data/DataGrid/DataGridHeader.tsx +52 -7
- package/src/components/data/DataGrid/DataGridHeaderCell.tsx +16 -2
- package/src/components/data/DataGrid/DataGridRowTemplate.tsx +23 -16
- package/src/components/data/DataGrid/helpers/columns.tsx +238 -236
- package/src/components/data/DataGrid/hooks/index.ts +6 -7
- package/src/components/data/DataGrid/hooks/useDataGrid.tsx +89 -16
- package/src/components/data/DataGrid/hooks/useDataGridChangedRows.ts +56 -0
- package/src/components/data/DataGrid/hooks/useDataGridCopy.ts +18 -19
- package/src/components/data/DataGrid/styles.ts +56 -1
- package/src/components/data/DataGrid/types.ts +69 -17
- package/src/components/data/SqlRequestDataGrid/helpers/columns.tsx +240 -216
- package/src/components/data/SqlRequestDataGrid/index.tsx +58 -43
- package/src/components/data/SqlRequestDataGrid/types.ts +21 -6
- package/src/components/data/SqlRequestForeignList/index.tsx +157 -0
- package/src/components/data/SqlRequestForeignList/styles.ts +38 -0
- package/src/components/data/SqlRequestGrid/filters/FiltersSidebar.tsx +8 -4
- package/src/components/data/SqlRequestGrid/index.tsx +24 -18
- package/src/components/data/SqlRequestGrid/types.ts +25 -3
- package/src/components/data/index.ts +2 -0
- package/src/helpers/numbers.ts +37 -0
- package/src/services/index.ts +1 -0
- package/src/services/updateSqlRequests.ts +34 -0
- package/src/components/data/DataGrid/DataGridEditableCell.tsx +0 -43
- package/src/components/data/SqlRequestDataGrid/index.ts +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M48 96V416c0 8.8 7.2 16 16 16H384c8.8 0 16-7.2 16-16V170.5c0-4.2-1.7-8.3-4.7-11.3l33.9-33.9c12 12 18.7 28.3 18.7 45.3V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96C0 60.7 28.7 32 64 32H309.5c17 0 33.3 6.7 45.3 18.7l74.5 74.5-33.9 33.9L320.8 84.7c-.3-.3-.5-.5-.8-.8V184c0 13.3-10.7 24-24 24H104c-13.3 0-24-10.7-24-24V80H64c-8.8 0-16 7.2-16 16zm80-16v80H272V80H128zm32 240a64 64 0 1 1 128 0 64 64 0 1 1 -128 0z"/></svg>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@addev-be/ui",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"watch": "tsc -b --watch",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"io-ts": "^2.2.21",
|
|
54
54
|
"lodash": "^4.17.21",
|
|
55
55
|
"moment": "^2.30.1",
|
|
56
|
+
"react-number-format": "^5.4.4",
|
|
56
57
|
"react-router-dom": "^7.0.2",
|
|
57
58
|
"rxjs": "^7.8.1",
|
|
58
59
|
"uuid": "^10.0.0"
|
package/src/Icons.tsx
CHANGED
|
@@ -23,6 +23,7 @@ import EllipsisIcon from '../assets/icons/ellipsis.svg?react';
|
|
|
23
23
|
import FilterFullIcon from '../assets/icons/filter-full.svg?react';
|
|
24
24
|
import FilterIcon from '../assets/icons/filter.svg?react';
|
|
25
25
|
import FilterSlashIcon from '../assets/icons/filter-slash.svg?react';
|
|
26
|
+
import FloppyDiskIcon from '../assets/icons/floppy-disk.svg?react';
|
|
26
27
|
import HashtagIcon from '../assets/icons/hashtag.svg?react';
|
|
27
28
|
import ImageSlashIcon from '../assets/icons/image-slash.svg?react';
|
|
28
29
|
import LeftIcon from '../assets/icons/left.svg?react';
|
|
@@ -129,4 +130,5 @@ export {
|
|
|
129
130
|
XBarIcon,
|
|
130
131
|
XMarkIcon,
|
|
131
132
|
XMarkLargeIcon,
|
|
133
|
+
FloppyDiskIcon,
|
|
132
134
|
};
|
|
@@ -10,7 +10,7 @@ import { DataGridEditableCell } from './DataGridEditableCell';
|
|
|
10
10
|
import { useDataGridContext } from './hooks';
|
|
11
11
|
|
|
12
12
|
const defaultRender = <R,>(row: R, col: DataGridColumn<R>) => {
|
|
13
|
-
const value = col.
|
|
13
|
+
const value = col.getter(row);
|
|
14
14
|
return !value ? '' : String(value);
|
|
15
15
|
};
|
|
16
16
|
|
|
@@ -31,8 +31,7 @@ export const DataGridCell = <R,>({
|
|
|
31
31
|
onRowDoubleClick,
|
|
32
32
|
userSelect,
|
|
33
33
|
} = useDataGridContext(context);
|
|
34
|
-
const isEditable =
|
|
35
|
-
!!editable && !!column.editable && column.type && column.getter;
|
|
34
|
+
const isEditable = !!editable && !!column.editable && !!column.editComponent;
|
|
36
35
|
const isEditing =
|
|
37
36
|
isEditable && editingCell[0] === rowIndex && editingCell[1] === columnIndex;
|
|
38
37
|
const DataGridCellComponent = column.component ?? styles.DataGridCell;
|
|
@@ -70,6 +69,7 @@ export const DataGridCell = <R,>({
|
|
|
70
69
|
style={style}
|
|
71
70
|
$userSelect={userSelect}
|
|
72
71
|
$color={column.color}
|
|
72
|
+
$textAlign={column.textAlign}
|
|
73
73
|
>
|
|
74
74
|
{(column.render ?? defaultRender)(row, column)}
|
|
75
75
|
</DataGridCellComponent>
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DataGridColumns } from '../types';
|
|
2
2
|
|
|
3
3
|
export const normalizeColumnsOrders = <R>(
|
|
4
|
-
columns: DataGridColumns<R>
|
|
5
|
-
) =>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
{
|
|
11
|
-
...column,
|
|
12
|
-
order: index,
|
|
13
|
-
},
|
|
14
|
-
]);
|
|
4
|
+
columns: DataGridColumns<R>
|
|
5
|
+
): DataGridColumns<R> =>
|
|
6
|
+
columns.map((column, index) => ({
|
|
7
|
+
...column,
|
|
8
|
+
order: index,
|
|
9
|
+
}));
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { keyBy, mapValues } from 'lodash';
|
|
1
2
|
import { useCallback, useContext, useMemo, useState } from 'react';
|
|
2
3
|
|
|
3
4
|
import { Button } from '../../../forms';
|
|
4
5
|
import { DataGridColumnsEditor } from '.';
|
|
5
6
|
import { DataGridContext } from '../types';
|
|
6
7
|
import { Modal } from '../../../layout/Modal';
|
|
7
|
-
import { mapValues } from 'lodash';
|
|
8
8
|
|
|
9
9
|
export const useDataGridColumnsModal = <R,>(context: DataGridContext<R>) => {
|
|
10
10
|
const [isVisible, setIsVisible] = useState(false);
|
|
@@ -20,7 +20,7 @@ export const useDataGridColumnsModal = <R,>(context: DataGridContext<R>) => {
|
|
|
20
20
|
}, []);
|
|
21
21
|
|
|
22
22
|
const onApplyClicked = useCallback(() => {
|
|
23
|
-
const newSettings = mapValues(currentColumns, (col) => ({
|
|
23
|
+
const newSettings = mapValues(keyBy(currentColumns, 'key'), (col) => ({
|
|
24
24
|
order: col.order ?? 0,
|
|
25
25
|
width: col.width ?? 150,
|
|
26
26
|
}));
|
|
@@ -70,9 +70,10 @@ export const DataGridColumnsEditor = <R,>({
|
|
|
70
70
|
columns: DataGridColumns<R>;
|
|
71
71
|
onColumnsChanged: Dispatch<SetStateAction<DataGridColumns<R>>>;
|
|
72
72
|
}) => {
|
|
73
|
+
console.log('DataGridColumnsEditor columns:', columns);
|
|
73
74
|
const [visibleColumns, hiddenColumns] = useVisibleAndHiddenColumns(columns);
|
|
74
75
|
const sortedVisibleColumnsEntries = normalizeColumnsOrders(
|
|
75
|
-
_.sortBy(
|
|
76
|
+
_.sortBy(visibleColumns, (col) => col.order ?? 0)
|
|
76
77
|
);
|
|
77
78
|
|
|
78
79
|
const onUpButtonClicked = useCallback(
|
|
@@ -84,10 +85,7 @@ export const DataGridColumnsEditor = <R,>({
|
|
|
84
85
|
sortedVisibleColumnsEntries[index - 1],
|
|
85
86
|
...sortedVisibleColumnsEntries.slice(index + 1),
|
|
86
87
|
]);
|
|
87
|
-
onColumnsChanged(() =>
|
|
88
|
-
...Object.fromEntries(newArray),
|
|
89
|
-
...hiddenColumns,
|
|
90
|
-
}));
|
|
88
|
+
onColumnsChanged(() => [...newArray, ...hiddenColumns]);
|
|
91
89
|
}
|
|
92
90
|
},
|
|
93
91
|
[hiddenColumns, onColumnsChanged, sortedVisibleColumnsEntries]
|
|
@@ -102,10 +100,7 @@ export const DataGridColumnsEditor = <R,>({
|
|
|
102
100
|
sortedVisibleColumnsEntries[index],
|
|
103
101
|
...sortedVisibleColumnsEntries.slice(index + 2),
|
|
104
102
|
]);
|
|
105
|
-
onColumnsChanged(() =>
|
|
106
|
-
...Object.fromEntries(newArray),
|
|
107
|
-
...hiddenColumns,
|
|
108
|
-
}));
|
|
103
|
+
onColumnsChanged(() => [...newArray, ...hiddenColumns]);
|
|
109
104
|
}
|
|
110
105
|
},
|
|
111
106
|
[hiddenColumns, onColumnsChanged, sortedVisibleColumnsEntries]
|
|
@@ -113,28 +108,34 @@ export const DataGridColumnsEditor = <R,>({
|
|
|
113
108
|
|
|
114
109
|
const onHideButtonClicked = useCallback(
|
|
115
110
|
(columnKey: string) => {
|
|
116
|
-
onColumnsChanged((prev) =>
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
111
|
+
onColumnsChanged((prev) =>
|
|
112
|
+
prev.map((column) =>
|
|
113
|
+
column.key === columnKey
|
|
114
|
+
? {
|
|
115
|
+
...column,
|
|
116
|
+
order: -1,
|
|
117
|
+
}
|
|
118
|
+
: column
|
|
119
|
+
)
|
|
120
|
+
);
|
|
123
121
|
},
|
|
124
122
|
[onColumnsChanged]
|
|
125
123
|
);
|
|
126
124
|
|
|
127
125
|
const onShowButtonClicked = useCallback(
|
|
128
126
|
(columnKey: string) => {
|
|
129
|
-
onColumnsChanged((prev) =>
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
127
|
+
onColumnsChanged((prev) =>
|
|
128
|
+
prev.map((column) =>
|
|
129
|
+
column.key === columnKey
|
|
130
|
+
? {
|
|
131
|
+
...column,
|
|
132
|
+
order: Object.keys(prev).length,
|
|
133
|
+
}
|
|
134
|
+
: column
|
|
135
|
+
)
|
|
136
|
+
);
|
|
136
137
|
},
|
|
137
|
-
[
|
|
138
|
+
[onColumnsChanged]
|
|
138
139
|
);
|
|
139
140
|
|
|
140
141
|
return (
|
|
@@ -142,10 +143,10 @@ export const DataGridColumnsEditor = <R,>({
|
|
|
142
143
|
<styles.Panel>
|
|
143
144
|
<styles.Title>Colonnes visibles</styles.Title>
|
|
144
145
|
<styles.ColumnsList>
|
|
145
|
-
{sortedVisibleColumnsEntries.map((
|
|
146
|
+
{sortedVisibleColumnsEntries.map((column, index) => (
|
|
146
147
|
<DataGridColumnItem
|
|
147
|
-
key={key}
|
|
148
|
-
columnKey={key}
|
|
148
|
+
key={column.key}
|
|
149
|
+
columnKey={column.key}
|
|
149
150
|
columnIndex={index}
|
|
150
151
|
column={column}
|
|
151
152
|
visible
|
|
@@ -164,10 +165,10 @@ export const DataGridColumnsEditor = <R,>({
|
|
|
164
165
|
<styles.Panel>
|
|
165
166
|
<styles.Title>Colonnes masquées</styles.Title>
|
|
166
167
|
<styles.ColumnsList>
|
|
167
|
-
{
|
|
168
|
+
{hiddenColumns.map((column, index) => (
|
|
168
169
|
<DataGridColumnItem
|
|
169
|
-
key={key}
|
|
170
|
-
columnKey={key}
|
|
170
|
+
key={column.key}
|
|
171
|
+
columnKey={column.key}
|
|
171
172
|
columnIndex={index}
|
|
172
173
|
column={column}
|
|
173
174
|
visible={false}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ForwardedRef, forwardRef, useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
import { DataGridEditableCellProps } from './types';
|
|
4
|
+
|
|
5
|
+
const CheckboxEditableCellInner = <R,>(
|
|
6
|
+
{ value, onChange, onClose }: DataGridEditableCellProps<R, boolean>,
|
|
7
|
+
ref: ForwardedRef<HTMLInputElement>
|
|
8
|
+
) => {
|
|
9
|
+
const onBlur = useCallback(() => {
|
|
10
|
+
onClose(true);
|
|
11
|
+
}, [onClose]);
|
|
12
|
+
|
|
13
|
+
const onKeyDown = useCallback(
|
|
14
|
+
(e: React.KeyboardEvent) => {
|
|
15
|
+
if (e.key === 'Enter') {
|
|
16
|
+
e.preventDefault();
|
|
17
|
+
onClose(true);
|
|
18
|
+
} else if (e.key === 'Escape') {
|
|
19
|
+
e.preventDefault();
|
|
20
|
+
onClose(false);
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
[onClose]
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<input
|
|
28
|
+
ref={ref}
|
|
29
|
+
type="checkbox"
|
|
30
|
+
checked={value}
|
|
31
|
+
onChange={(e) => onChange(e.target.checked)}
|
|
32
|
+
onBlur={onBlur}
|
|
33
|
+
onKeyDown={onKeyDown}
|
|
34
|
+
/>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const CheckboxEditableCell = forwardRef(CheckboxEditableCellInner);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ForwardedRef, forwardRef, useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
import { DataGridEditableCellProps } from './types';
|
|
4
|
+
import moment from 'moment';
|
|
5
|
+
|
|
6
|
+
const DateEditableCellInner = <R,>(
|
|
7
|
+
{ value, onChange, onClose }: DataGridEditableCellProps<R, Date>,
|
|
8
|
+
ref: ForwardedRef<HTMLInputElement>
|
|
9
|
+
) => {
|
|
10
|
+
const onBlur = useCallback(() => {
|
|
11
|
+
onClose(true);
|
|
12
|
+
}, [onClose]);
|
|
13
|
+
|
|
14
|
+
const onKeyDown = useCallback(
|
|
15
|
+
(e: React.KeyboardEvent) => {
|
|
16
|
+
if (e.key === 'Enter') {
|
|
17
|
+
e.preventDefault();
|
|
18
|
+
onClose(true);
|
|
19
|
+
} else if (e.key === 'Escape') {
|
|
20
|
+
e.preventDefault();
|
|
21
|
+
onClose(false);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
[onClose]
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<input
|
|
29
|
+
ref={ref}
|
|
30
|
+
type="date"
|
|
31
|
+
value={moment(value).format('YYYY-MM-DD')}
|
|
32
|
+
onChange={(e) => onChange(moment(e.target.value, 'YYYY-MM-DD').toDate())}
|
|
33
|
+
onBlur={onBlur}
|
|
34
|
+
onKeyDown={onKeyDown}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const DateEditableCell = forwardRef(DateEditableCellInner);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ForwardedRef, forwardRef, useCallback } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
decimalSeparator,
|
|
4
|
+
getCurrencySymbol,
|
|
5
|
+
parseNumber,
|
|
6
|
+
} from '../../../../helpers/numbers';
|
|
7
|
+
|
|
8
|
+
import { DataGridEditableCellProps } from './types';
|
|
9
|
+
import { NumericFormat } from 'react-number-format';
|
|
10
|
+
|
|
11
|
+
const NumberEditableCellInner = <R,>(
|
|
12
|
+
{
|
|
13
|
+
decimals = 0,
|
|
14
|
+
currency,
|
|
15
|
+
row,
|
|
16
|
+
value,
|
|
17
|
+
onChange,
|
|
18
|
+
onClose,
|
|
19
|
+
}: DataGridEditableCellProps<R, number> & {
|
|
20
|
+
decimals?: number;
|
|
21
|
+
currency?: string | ((row: R) => string);
|
|
22
|
+
},
|
|
23
|
+
ref: ForwardedRef<HTMLInputElement>
|
|
24
|
+
) => {
|
|
25
|
+
const currencyName =
|
|
26
|
+
typeof currency === 'function' ? currency(row) : currency;
|
|
27
|
+
|
|
28
|
+
const [prefix, suffix] = currencyName
|
|
29
|
+
? getCurrencySymbol(currencyName)
|
|
30
|
+
: [undefined, undefined];
|
|
31
|
+
|
|
32
|
+
const onBlur = useCallback(() => {
|
|
33
|
+
onClose(true);
|
|
34
|
+
}, [onClose]);
|
|
35
|
+
|
|
36
|
+
const onKeyDown = useCallback(
|
|
37
|
+
(e: React.KeyboardEvent) => {
|
|
38
|
+
if (e.key === 'Enter') {
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
onClose(true);
|
|
41
|
+
} else if (e.key === 'Escape') {
|
|
42
|
+
e.preventDefault();
|
|
43
|
+
onClose(false);
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
[onClose]
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<NumericFormat
|
|
51
|
+
getInputRef={ref}
|
|
52
|
+
value={Number(value)}
|
|
53
|
+
onChange={(e) => {
|
|
54
|
+
console.log('e:', e);
|
|
55
|
+
onChange(parseNumber(e.target.value));
|
|
56
|
+
}}
|
|
57
|
+
onBlur={onBlur}
|
|
58
|
+
onKeyDown={onKeyDown}
|
|
59
|
+
decimalSeparator={decimalSeparator}
|
|
60
|
+
decimalScale={decimals}
|
|
61
|
+
fixedDecimalScale={!!decimals}
|
|
62
|
+
prefix={prefix ? prefix + ' ' : undefined}
|
|
63
|
+
suffix={suffix ? ' ' + suffix : undefined}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const NumberEditableCell = forwardRef(NumberEditableCellInner);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ForwardedRef, forwardRef, useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
import { DataGridEditableCellProps } from './types';
|
|
4
|
+
|
|
5
|
+
const TextEditableCellInner = <R,>(
|
|
6
|
+
{ value, onChange, onClose }: DataGridEditableCellProps<R, string>,
|
|
7
|
+
ref: ForwardedRef<HTMLInputElement>
|
|
8
|
+
) => {
|
|
9
|
+
const onBlur = useCallback(() => {
|
|
10
|
+
onClose(true);
|
|
11
|
+
}, [onClose]);
|
|
12
|
+
|
|
13
|
+
const onKeyDown = useCallback(
|
|
14
|
+
(e: React.KeyboardEvent) => {
|
|
15
|
+
if (e.key === 'Enter') {
|
|
16
|
+
e.preventDefault();
|
|
17
|
+
onClose(true);
|
|
18
|
+
} else if (e.key === 'Escape') {
|
|
19
|
+
e.preventDefault();
|
|
20
|
+
onClose(false);
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
[onClose]
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<input
|
|
28
|
+
ref={ref}
|
|
29
|
+
type="text"
|
|
30
|
+
value={String(value)}
|
|
31
|
+
onChange={(e) => onChange(e.target.value)}
|
|
32
|
+
onBlur={onBlur}
|
|
33
|
+
onKeyDown={onKeyDown}
|
|
34
|
+
/>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const TextEditableCell = forwardRef(TextEditableCellInner);
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unnecessary-type-constraint */
|
|
3
|
+
|
|
4
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
5
|
+
|
|
6
|
+
import { DataGridCellProps } from '../types';
|
|
7
|
+
import { DataGridEditableCellFC } from './types';
|
|
8
|
+
import { EditableCellContainer } from '../styles';
|
|
9
|
+
import { useDataGridContext } from '../hooks';
|
|
10
|
+
|
|
11
|
+
export const DataGridEditableCell = <R,>({
|
|
12
|
+
row,
|
|
13
|
+
columnKey,
|
|
14
|
+
column,
|
|
15
|
+
context,
|
|
16
|
+
}: DataGridCellProps<R>) => {
|
|
17
|
+
const { onCellEdited, setEditingCell } = useDataGridContext(context);
|
|
18
|
+
const initialValue = useMemo(() => column.getter(row) ?? '', [column, row]);
|
|
19
|
+
const [value, setValue] = useState(initialValue);
|
|
20
|
+
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
21
|
+
|
|
22
|
+
const onClose = useCallback(
|
|
23
|
+
(save: boolean, nextEditingCell: [number, number] = [-1, -1]) => {
|
|
24
|
+
if (save && value !== initialValue) {
|
|
25
|
+
onCellEdited?.(row, columnKey, value);
|
|
26
|
+
}
|
|
27
|
+
setEditingCell(nextEditingCell);
|
|
28
|
+
},
|
|
29
|
+
[columnKey, initialValue, onCellEdited, row, setEditingCell, value]
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (inputRef.current) {
|
|
34
|
+
inputRef.current.focus();
|
|
35
|
+
inputRef.current.select();
|
|
36
|
+
}
|
|
37
|
+
}, [inputRef]);
|
|
38
|
+
|
|
39
|
+
const input = useMemo(() => {
|
|
40
|
+
if (!column.editable || !column.editComponent) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const EditComponent = column.editComponent as DataGridEditableCellFC<R>;
|
|
44
|
+
return (
|
|
45
|
+
<EditComponent
|
|
46
|
+
row={row}
|
|
47
|
+
ref={inputRef}
|
|
48
|
+
value={value}
|
|
49
|
+
onChange={setValue}
|
|
50
|
+
onClose={onClose}
|
|
51
|
+
/>
|
|
52
|
+
);
|
|
53
|
+
}, [column.editComponent, column.editable, onClose, row, value]);
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<EditableCellContainer key={columnKey} $textAlign={column.textAlign}>
|
|
57
|
+
{input}
|
|
58
|
+
</EditableCellContainer>
|
|
59
|
+
);
|
|
60
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { FC, ForwardedRef } from 'react';
|
|
2
|
+
|
|
3
|
+
export type DataGridEditableCellProps<R, T> = {
|
|
4
|
+
ref?: ForwardedRef<HTMLInputElement>;
|
|
5
|
+
row: R;
|
|
6
|
+
value: T;
|
|
7
|
+
onChange: (value: T) => void;
|
|
8
|
+
onClose: (save: boolean) => void;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12
|
+
export type DataGridEditableCellFC<R, T = any> = FC<
|
|
13
|
+
DataGridEditableCellProps<R, T>
|
|
14
|
+
>;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
DataGridColumnWithFilter,
|
|
3
|
+
DataGridContext,
|
|
4
|
+
DataGridFilter,
|
|
5
|
+
} from '../types';
|
|
2
6
|
import { FilterIcon, FilterSlashIcon } from '../../../../Icons';
|
|
3
7
|
import { useCallback, useState } from 'react';
|
|
4
8
|
|
|
@@ -8,19 +12,18 @@ import { Modal } from '../../../layout/Modal';
|
|
|
8
12
|
import { useDataGridContext } from '../hooks';
|
|
9
13
|
|
|
10
14
|
export const useFilterModal = <R,>({
|
|
11
|
-
|
|
15
|
+
column,
|
|
12
16
|
context,
|
|
13
17
|
onClose,
|
|
14
18
|
}: {
|
|
15
|
-
|
|
19
|
+
column: DataGridColumnWithFilter<R>;
|
|
16
20
|
context: DataGridContext<R>;
|
|
17
21
|
onClose?: () => void;
|
|
18
22
|
}) => {
|
|
19
23
|
const [isVisible, setIsVisible] = useState(false);
|
|
20
|
-
const { filters = {},
|
|
21
|
-
const column = columns[columnKey];
|
|
24
|
+
const { filters = {}, setFilters } = useDataGridContext<R>(context);
|
|
22
25
|
const [currentFilter, setCurrentFilter] = useState<DataGridFilter>(
|
|
23
|
-
|
|
26
|
+
column.filter
|
|
24
27
|
);
|
|
25
28
|
|
|
26
29
|
const openModal = useCallback(() => {
|
|
@@ -33,15 +36,15 @@ export const useFilterModal = <R,>({
|
|
|
33
36
|
|
|
34
37
|
const onClearClicked = useCallback(() => {
|
|
35
38
|
const newFilters = { ...filters };
|
|
36
|
-
delete newFilters[
|
|
39
|
+
delete newFilters[column.key];
|
|
37
40
|
setFilters(newFilters);
|
|
38
41
|
closeModal();
|
|
39
|
-
}, [closeModal,
|
|
42
|
+
}, [closeModal, column.key, filters, setFilters]);
|
|
40
43
|
|
|
41
44
|
const onApplyClicked = useCallback(() => {
|
|
42
|
-
setFilters({ ...filters, [
|
|
45
|
+
setFilters({ ...filters, [column.key]: currentFilter });
|
|
43
46
|
closeModal();
|
|
44
|
-
}, [closeModal,
|
|
47
|
+
}, [closeModal, column.key, currentFilter, filters, setFilters]);
|
|
45
48
|
|
|
46
49
|
const onCancelClicked = useCallback(() => {
|
|
47
50
|
closeModal();
|