@addev-be/ui 0.2.10 → 0.2.12
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/sort-calendar-ascending.svg +6 -0
- package/assets/icons/sort-calendar-descending.svg +1 -0
- package/package.json +1 -1
- package/src/Icons.tsx +4 -0
- package/src/components/data/DataGrid/{FilterValuesScroller.tsx → DataGridFilterMenu/FilterValuesScroller.tsx} +7 -26
- package/src/components/data/DataGrid/DataGridFilterMenu/index.tsx +5 -3
- package/src/components/data/DataGrid/DataGridFilterMenu/styles.ts +47 -0
- package/src/components/data/DataGrid/FilterModalContent/index.tsx +23 -11
- package/src/components/data/DataGrid/helpers/columns.tsx +9 -5
- package/src/components/data/DataGrid/helpers/filters.ts +58 -1
- package/src/components/data/DataGrid/hooks/useDataGridCopy.ts +5 -0
- package/src/components/data/DataGrid/styles.ts +0 -44
- package/src/components/data/DataGrid/types.ts +5 -0
- package/src/components/data/SqlRequestDataGrid/helpers/columns.tsx +22 -5
- package/src/helpers/numbers.ts +6 -0
- package/src/services/globalSearch.ts +27 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M 8 16 L 11 16 L 11 13 L 8 13 L 8 16 Z M 13 5 L 12 5 L 12 3 L 10 3 L 10 5 L 6 5 L 6 3 L 4 3 L 4 5 L 3 5 C 1.89 5 1 5.89 1 7 L 1 18 C 1 19.11 1.89 20 3 20 L 13 20 C 14.11 20 15 19.11 15 18 L 15 7 C 15 5.89 14.11 5 13 5 M 3 18 L 3 11 L 13 11 L 13 18 L 3 18 Z" style=""/>
|
|
4
|
+
<path d="M 18.5 7.5 L 15.5 7.5 L 15.5 18 C 15.478 18.657 15.194 19.345 14.77 19.77 C 14.345 20.194 13.657 20.478 13 20.5 L 3 20.5 C 2.343 20.478 1.655 20.194 1.23 19.77 C 0.806 19.345 0.522 18.657 0.5 18 L 0.5 7 C 0.522 6.343 0.806 5.655 1.23 5.23 C 1.655 4.806 2.343 4.522 3 4.5 L 3.5 4.5 L 3.5 2.5 L 6.5 2.5 L 6.5 4.5 L 9.5 4.5 L 9.5 2.5 L 12.5 2.5 L 12.5 4.5 L 13 4.5 C 13.657 4.522 14.345 4.806 14.77 5.23 C 15.153 5.613 15.422 6.211 15.486 6.807 L 20 2.293 L 25.207 7.5 L 21.5 7.5 L 21.5 21.5 L 18.5 21.5 Z M 19.5 6.5 L 19.5 20.5 L 20.5 20.5 L 20.5 6.5 L 22.793 6.5 L 20 3.707 L 17.207 6.5 Z M 11.5 12.5 L 11.5 16.5 L 7.5 16.5 L 7.5 12.5 Z M 8.5 15.5 L 10.5 15.5 L 10.5 13.5 L 8.5 13.5 Z M 11.5 5.5 L 11.5 3.5 L 10.5 3.5 L 10.5 5.5 L 5.5 5.5 L 5.5 3.5 L 4.5 3.5 L 4.5 5.5 L 3 5.5 C 2.547 5.478 2.235 5.639 1.937 5.937 C 1.639 6.235 1.478 6.547 1.5 7 L 1.5 18 C 1.478 18.453 1.639 18.765 1.937 19.063 C 2.235 19.361 2.547 19.522 3 19.5 L 13 19.5 C 13.453 19.522 13.765 19.361 14.063 19.063 C 14.361 18.765 14.522 18.453 14.5 18 L 14.5 7 C 14.522 6.547 14.361 6.235 14.063 5.937 C 13.765 5.639 13.453 5.478 13 5.5 Z M 2.5 10.5 L 13.5 10.5 L 13.5 18.5 L 2.5 18.5 Z M 12.5 17.5 L 12.5 11.5 L 3.5 11.5 L 3.5 17.5 Z" style="fill: none;"/>
|
|
5
|
+
<path d="M 19 17 L 16 17 L 20 21 L 24 17 L 21 17 L 21 3 L 19 3 L 19 17 Z" style=""/>
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m19 7h-3l4-4 4 4h-3v14h-2zm-11 9h3v-3h-3zm5-11h-1v-2h-2v2h-4v-2h-2v2h-1c-1.11 0-2 .89-2 2v11c0 1.11.89 2 2 2h10c1.11 0 2-.89 2-2v-11c0-1.11-.89-2-2-2m-10 13v-7h10v7z"/></svg>
|
package/package.json
CHANGED
package/src/Icons.tsx
CHANGED
|
@@ -24,6 +24,8 @@ import PhoneIcon from '../assets/icons/phone.svg?react';
|
|
|
24
24
|
import PlusIcon from '../assets/icons/plus.svg?react';
|
|
25
25
|
import RightIcon from '../assets/icons/right.svg?react';
|
|
26
26
|
import SigmaIcon from '../assets/icons/sigma.svg?react';
|
|
27
|
+
import SortCalendarAscendingIcon from '../assets/icons/sort-calendar-ascending.svg?react';
|
|
28
|
+
import SortCalendarDescendingIcon from '../assets/icons/sort-calendar-descending.svg?react';
|
|
27
29
|
import SpinnerIcon from '../assets/icons/spinner-third.svg?react';
|
|
28
30
|
import TableColumnsIcon from '../assets/icons/table-columns.svg?react';
|
|
29
31
|
import TableFooterIcon from '../assets/icons/table-footer.svg?react';
|
|
@@ -92,6 +94,8 @@ export {
|
|
|
92
94
|
PlusIcon,
|
|
93
95
|
RightIcon,
|
|
94
96
|
SigmaIcon,
|
|
97
|
+
SortCalendarAscendingIcon,
|
|
98
|
+
SortCalendarDescendingIcon,
|
|
95
99
|
SpinnerIcon,
|
|
96
100
|
TableColumnsIcon,
|
|
97
101
|
TableFooterIcon,
|
|
@@ -8,25 +8,23 @@ import {
|
|
|
8
8
|
DataGridFilterGroup,
|
|
9
9
|
DataGridFilterRenderer,
|
|
10
10
|
DataGridFilterValue,
|
|
11
|
-
} from '
|
|
12
|
-
import {
|
|
13
|
-
import { defaultRendererAndFormatter, getCheckboxes } from './helpers';
|
|
11
|
+
} from '../types';
|
|
12
|
+
import { defaultRendererAndFormatter, getCheckboxes } from '../helpers';
|
|
14
13
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
15
14
|
|
|
16
|
-
import {
|
|
15
|
+
import { debounce } from 'lodash';
|
|
16
|
+
import { useElementSize } from '../../../../hooks';
|
|
17
17
|
|
|
18
18
|
const CheckboxTemplate = ({
|
|
19
19
|
selectedValues,
|
|
20
20
|
value,
|
|
21
21
|
index,
|
|
22
|
-
className,
|
|
23
22
|
style,
|
|
24
23
|
onToggle,
|
|
25
24
|
}: {
|
|
26
25
|
selectedValues: DataGridFilterValue[];
|
|
27
26
|
value: DataGridFilterCheckbox;
|
|
28
27
|
index: number;
|
|
29
|
-
className?: string;
|
|
30
28
|
style?: React.CSSProperties;
|
|
31
29
|
onToggle?: (values: DataGridFilterValue[]) => void;
|
|
32
30
|
}) => {
|
|
@@ -37,28 +35,12 @@ const CheckboxTemplate = ({
|
|
|
37
35
|
return (
|
|
38
36
|
<styles.FilterValueContainer
|
|
39
37
|
key={index}
|
|
40
|
-
className={join(
|
|
41
|
-
[
|
|
42
|
-
// 'absolute left-0 right-0 flex flex-row cursor-pointer hover:bg-gray-50',
|
|
43
|
-
className,
|
|
44
|
-
],
|
|
45
|
-
' '
|
|
46
|
-
)}
|
|
47
38
|
style={{ ...style, paddingLeft: `${value.level}rem` }}
|
|
48
39
|
title={value.title}
|
|
49
40
|
onClick={() => onToggle?.(value.values)}
|
|
50
41
|
>
|
|
51
|
-
<input
|
|
52
|
-
|
|
53
|
-
checked={checked}
|
|
54
|
-
readOnly
|
|
55
|
-
// className="inline-block mr-2"
|
|
56
|
-
/>
|
|
57
|
-
<span
|
|
58
|
-
// className="mr-2 truncate"
|
|
59
|
-
>
|
|
60
|
-
{value.displayValue || '(Vides)'}
|
|
61
|
-
</span>
|
|
42
|
+
<input type="checkbox" checked={checked} readOnly />
|
|
43
|
+
<span>{value.displayValue || '(Vides)'}</span>
|
|
62
44
|
</styles.FilterValueContainer>
|
|
63
45
|
);
|
|
64
46
|
};
|
|
@@ -121,10 +103,9 @@ export const FilterValuesScroller = ({
|
|
|
121
103
|
onScroll={onScroll}
|
|
122
104
|
$rowHeight={rowHeight}
|
|
123
105
|
>
|
|
124
|
-
<div style={{ height: `${
|
|
106
|
+
<div style={{ height: `${checkboxes.length * rowHeight}px` }}>
|
|
125
107
|
{visibleCheckboxes.map((value, index) => (
|
|
126
108
|
<CheckboxTemplate
|
|
127
|
-
className="checkbox"
|
|
128
109
|
style={{ top: firstCheckboxTop + index * rowHeight + 'px' }}
|
|
129
110
|
key={index}
|
|
130
111
|
selectedValues={selectedValues}
|
|
@@ -15,6 +15,8 @@ import {
|
|
|
15
15
|
IconFC,
|
|
16
16
|
MagnifierIcon,
|
|
17
17
|
SigmaIcon,
|
|
18
|
+
SortCalendarAscendingIcon,
|
|
19
|
+
SortCalendarDescendingIcon,
|
|
18
20
|
TableFooterIcon,
|
|
19
21
|
TableFooterSlashIcon,
|
|
20
22
|
TallyIcon,
|
|
@@ -42,7 +44,7 @@ import {
|
|
|
42
44
|
} from 'react';
|
|
43
45
|
|
|
44
46
|
import { ContextMenu } from '../../../ui/ContextMenu';
|
|
45
|
-
import { FilterValuesScroller } from '
|
|
47
|
+
import { FilterValuesScroller } from './FilterValuesScroller';
|
|
46
48
|
import { Input } from '../../../forms';
|
|
47
49
|
import { useFilterModal } from './hooks';
|
|
48
50
|
|
|
@@ -56,12 +58,12 @@ type FilterValuesProps<R> = {
|
|
|
56
58
|
const sortAsc: Record<DataGridFilterType, [string, IconFC]> = {
|
|
57
59
|
number: ['Trier du plus petit au plus grand', ArrowDown19Icon],
|
|
58
60
|
text: ['Trier de A à Z', ArrowDownAZIcon],
|
|
59
|
-
|
|
61
|
+
date: ['Trier du plus ancien au plus récent', SortCalendarAscendingIcon],
|
|
60
62
|
};
|
|
61
63
|
const sortDesc: Record<DataGridFilterType, [string, IconFC]> = {
|
|
62
64
|
number: ['Trier du plus grand au plus petit', ArrowUp91Icon],
|
|
63
65
|
text: ['Trier de Z à A', ArrowUpZAIcon],
|
|
64
|
-
|
|
66
|
+
date: ['Trier du plus récent au plus ancien', SortCalendarDescendingIcon],
|
|
65
67
|
};
|
|
66
68
|
|
|
67
69
|
const footerFunctionsTexts: Record<DataGridFooterPredefinedFunction, string> = {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import styled from 'styled-components';
|
|
2
2
|
|
|
3
|
+
export const DEFAULT_FILTER_ROW_HEIGHT = 24;
|
|
4
|
+
|
|
3
5
|
export const InputContainer = styled.div.attrs({
|
|
4
6
|
className: 'InputContainer',
|
|
5
7
|
})`
|
|
@@ -47,3 +49,48 @@ export const Separator = styled.div.attrs({
|
|
|
47
49
|
border-top: 1px solid var(--color-neutral-200);
|
|
48
50
|
margin: var(--space-1) 0;
|
|
49
51
|
`;
|
|
52
|
+
|
|
53
|
+
export const FilterValueContainer = styled.div.attrs({
|
|
54
|
+
className: 'FilterValueContainer',
|
|
55
|
+
})`
|
|
56
|
+
position: absolute;
|
|
57
|
+
left: 0;
|
|
58
|
+
right: 0;
|
|
59
|
+
display: flex;
|
|
60
|
+
flex-direction: row;
|
|
61
|
+
align-items: center;
|
|
62
|
+
cursor: pointer;
|
|
63
|
+
&:hover {
|
|
64
|
+
background-color: var(--color-neutral-50);
|
|
65
|
+
}
|
|
66
|
+
`;
|
|
67
|
+
|
|
68
|
+
export const FilterValuesScrollerContainer = styled.div.attrs({
|
|
69
|
+
className: 'FilterValuesScrollerContainer',
|
|
70
|
+
})<{
|
|
71
|
+
$rowHeight?: number;
|
|
72
|
+
}>`
|
|
73
|
+
display: block;
|
|
74
|
+
font-size: var(--text-base);
|
|
75
|
+
background-color: var(--color-neutral-0);
|
|
76
|
+
overflow-y: scroll;
|
|
77
|
+
overflow-x: hidden;
|
|
78
|
+
height: 100%;
|
|
79
|
+
|
|
80
|
+
& > div {
|
|
81
|
+
position: relative;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
& ${FilterValueContainer} {
|
|
85
|
+
position: absolute;
|
|
86
|
+
display: flex;
|
|
87
|
+
flex-direction: row;
|
|
88
|
+
align-items: center;
|
|
89
|
+
height: ${({ $rowHeight = DEFAULT_FILTER_ROW_HEIGHT }) =>
|
|
90
|
+
`${$rowHeight}px`};
|
|
91
|
+
|
|
92
|
+
input[type='checkbox'] {
|
|
93
|
+
margin-right: var(--space-1);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
`;
|
|
@@ -19,6 +19,13 @@ const filterOperators: {
|
|
|
19
19
|
[K2 in DataGridFilterOperator<K>]: string;
|
|
20
20
|
}>;
|
|
21
21
|
} = {
|
|
22
|
+
date: {
|
|
23
|
+
after: 'Après',
|
|
24
|
+
before: 'Avant',
|
|
25
|
+
equals: 'Égal à',
|
|
26
|
+
notEquals: 'Différent de',
|
|
27
|
+
inRange: "Dans l'intervalle",
|
|
28
|
+
},
|
|
22
29
|
number: {
|
|
23
30
|
equals: 'Égal à',
|
|
24
31
|
notEquals: 'Différent de',
|
|
@@ -100,21 +107,26 @@ export const FilterModalContent = ({
|
|
|
100
107
|
{operator === 'inRange' && (
|
|
101
108
|
<label htmlFor="filterValue2">
|
|
102
109
|
<span>et</span>
|
|
103
|
-
<
|
|
110
|
+
<Input
|
|
104
111
|
name="filterValue2"
|
|
105
112
|
type={filter.type}
|
|
106
113
|
value={values[1] ?? ''}
|
|
107
|
-
// className="text-sm w-24"
|
|
108
114
|
onChange={(e) => {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
if (type === 'number') {
|
|
116
|
+
const newValues = [...values];
|
|
117
|
+
newValues[1] = Number(e.target.value);
|
|
118
|
+
onFilterChanged({
|
|
119
|
+
...filter,
|
|
120
|
+
values: newValues,
|
|
121
|
+
});
|
|
122
|
+
} else {
|
|
123
|
+
const newValues = [...values];
|
|
124
|
+
newValues[1] = String(e.target.value) as any;
|
|
125
|
+
onFilterChanged({
|
|
126
|
+
...filter,
|
|
127
|
+
values: newValues,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
118
130
|
}}
|
|
119
131
|
/>
|
|
120
132
|
</label>
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
|
|
3
3
|
import { DataGridColumn, DataGridColumns, DataGridSettings } from '../types';
|
|
4
|
+
import { dateFilter, numberFilter, textFilter } from './filters';
|
|
4
5
|
import {
|
|
5
6
|
formatMoney,
|
|
6
7
|
formatNumber,
|
|
8
|
+
formatNumberInvariant,
|
|
7
9
|
formatPercentage,
|
|
8
10
|
} from '../../../../helpers/numbers';
|
|
9
|
-
import { numberFilter, textFilter } from './filters';
|
|
10
11
|
|
|
11
12
|
import moment from 'moment';
|
|
12
13
|
import { repeat } from 'lodash';
|
|
@@ -15,7 +16,7 @@ export const isColumnVisible = <R,>(
|
|
|
15
16
|
obj: DataGridColumn<R> | DataGridSettings
|
|
16
17
|
): boolean => obj?.order !== -1;
|
|
17
18
|
|
|
18
|
-
const buildExcelFormat = (decimals = 2, suffix = '') =>
|
|
19
|
+
export const buildExcelFormat = (decimals = 2, suffix = '') =>
|
|
19
20
|
`#0${decimals > 0 ? `.${repeat('0', decimals)}` : ''}${suffix}`;
|
|
20
21
|
|
|
21
22
|
export const textColumn = <R extends Record<string, any>>(
|
|
@@ -93,7 +94,7 @@ export const dateColumn = <R extends Record<string, any>>(
|
|
|
93
94
|
sortGetter: (row) => row[key] ?? '',
|
|
94
95
|
footer: (_, filteredRows) => `${filteredRows.length} éléments`,
|
|
95
96
|
filter: {
|
|
96
|
-
...
|
|
97
|
+
...dateFilter(key),
|
|
97
98
|
renderer: (value) => moment(value).format('DD/MM/YYYY') ?? '',
|
|
98
99
|
},
|
|
99
100
|
...options,
|
|
@@ -125,7 +126,8 @@ export const numberColumn = <R extends Record<string, any>>(
|
|
|
125
126
|
[key]: {
|
|
126
127
|
name: title,
|
|
127
128
|
render: (row) => formatNumber(row[key], decimals) ?? '',
|
|
128
|
-
excelFormatter: () =>
|
|
129
|
+
excelFormatter: () => buildExcelFormat(decimals),
|
|
130
|
+
excelValue: (value) => formatNumberInvariant(value, decimals),
|
|
129
131
|
getter: (row) => row[key] ?? '',
|
|
130
132
|
sortGetter: (row) => row[key] ?? '',
|
|
131
133
|
footer: {
|
|
@@ -170,6 +172,7 @@ export const moneyColumn = <R extends Record<string, any>>(
|
|
|
170
172
|
name: title,
|
|
171
173
|
render: (row) => formatMoney(row[key], decimals) ?? '',
|
|
172
174
|
excelFormatter: () => buildExcelFormat(decimals, ' €'),
|
|
175
|
+
excelValue: (value) => formatNumberInvariant(value, decimals),
|
|
173
176
|
getter: (row) => row[key] ?? '',
|
|
174
177
|
sortGetter: (row) => row[key] ?? '',
|
|
175
178
|
filter: {
|
|
@@ -213,7 +216,8 @@ export const percentageColumn = <R extends Record<string, any>>(
|
|
|
213
216
|
[key]: {
|
|
214
217
|
name: title,
|
|
215
218
|
render: (row) => formatPercentage(row[key]) ?? '',
|
|
216
|
-
excelFormatter: () => buildExcelFormat(decimals),
|
|
219
|
+
excelFormatter: () => buildExcelFormat(decimals, '%'),
|
|
220
|
+
excelValue: (value) => formatNumberInvariant(value, decimals),
|
|
217
221
|
getter: (row) => row[key] ?? '',
|
|
218
222
|
sortGetter: (row) => row[key] ?? '',
|
|
219
223
|
filter: numberFilter(key),
|
|
@@ -95,7 +95,55 @@ const numberInArrayPredicate: DataGridFilterPredicateBuilder<number> = (
|
|
|
95
95
|
return (valueToVerify: number) => filterValues.includes(valueToVerify);
|
|
96
96
|
};
|
|
97
97
|
|
|
98
|
+
const dateBeforePredicate: DataGridFilterPredicateBuilder<string> = (
|
|
99
|
+
...filterValues
|
|
100
|
+
) => {
|
|
101
|
+
const limitDate = moment(filterValues[0]);
|
|
102
|
+
return (valueToVerify) => moment(valueToVerify).isBefore(limitDate);
|
|
103
|
+
};
|
|
104
|
+
const dateAfterPredicate: DataGridFilterPredicateBuilder<string> = (
|
|
105
|
+
...filterValues
|
|
106
|
+
) => {
|
|
107
|
+
const limitDate = moment(filterValues[0]);
|
|
108
|
+
return (valueToVerify) => moment(valueToVerify).isAfter(limitDate);
|
|
109
|
+
};
|
|
110
|
+
const dateEqualsPredicate: DataGridFilterPredicateBuilder<string> = (
|
|
111
|
+
...filterValues
|
|
112
|
+
) => {
|
|
113
|
+
const date = moment(filterValues[0]);
|
|
114
|
+
return (valueToVerify) => moment(valueToVerify).isSame(date);
|
|
115
|
+
};
|
|
116
|
+
const dateNotEqualsPredicate: DataGridFilterPredicateBuilder<string> = (
|
|
117
|
+
...filterValues
|
|
118
|
+
) => {
|
|
119
|
+
const date = moment(filterValues[0]);
|
|
120
|
+
return (valueToVerify) => !moment(valueToVerify).isSame(date);
|
|
121
|
+
};
|
|
122
|
+
const dateInRangePredicate: DataGridFilterPredicateBuilder<string> = (
|
|
123
|
+
...filterValues
|
|
124
|
+
) => {
|
|
125
|
+
const date1 = moment(filterValues[0]);
|
|
126
|
+
const date2 = moment(filterValues[1]);
|
|
127
|
+
const startDate = date1.isBefore(date2) ? date1 : date2;
|
|
128
|
+
const endDate = date1.isBefore(date2) ? date2 : date1;
|
|
129
|
+
return (valueToVerify) =>
|
|
130
|
+
moment(valueToVerify).isBetween(startDate, endDate, 'days', '[]');
|
|
131
|
+
};
|
|
132
|
+
const dateInArrayPredicate: DataGridFilterPredicateBuilder<string> = (
|
|
133
|
+
...filterValues
|
|
134
|
+
) => {
|
|
135
|
+
return (valueToVerify) => filterValues.includes(valueToVerify);
|
|
136
|
+
};
|
|
137
|
+
|
|
98
138
|
export const filtersPredicates: DataGridFilterPredicates = {
|
|
139
|
+
date: {
|
|
140
|
+
before: dateBeforePredicate,
|
|
141
|
+
after: dateAfterPredicate,
|
|
142
|
+
equals: dateEqualsPredicate,
|
|
143
|
+
notEquals: dateNotEqualsPredicate,
|
|
144
|
+
inRange: dateInRangePredicate,
|
|
145
|
+
inArray: dateInArrayPredicate,
|
|
146
|
+
},
|
|
99
147
|
text: {
|
|
100
148
|
contains: textContainsPredicate,
|
|
101
149
|
notContains: textNotContainsPredicate,
|
|
@@ -139,6 +187,7 @@ export const defaultFilterGetter = (row: any, columnKey: string) =>
|
|
|
139
187
|
export const defaultFilterValues: {
|
|
140
188
|
[K in DataGridFilterType]: DataGridFilterDataType<K>;
|
|
141
189
|
} = {
|
|
190
|
+
date: '',
|
|
142
191
|
text: '',
|
|
143
192
|
number: 0,
|
|
144
193
|
};
|
|
@@ -146,6 +195,7 @@ export const defaultFilterValues: {
|
|
|
146
195
|
export const defaultValueParsers: {
|
|
147
196
|
[K in DataGridFilterType]: (value: string) => DataGridFilterDataType<K>;
|
|
148
197
|
} = {
|
|
198
|
+
date: (value) => moment(value).format('YYYY-MM-DD'),
|
|
149
199
|
text: (value) => value,
|
|
150
200
|
number: (value) => parseFloat(value),
|
|
151
201
|
};
|
|
@@ -156,7 +206,7 @@ export const groupDatesByYearAndMonth = (dates: any[]) =>
|
|
|
156
206
|
if (!acc[year]) {
|
|
157
207
|
acc[year] = {};
|
|
158
208
|
}
|
|
159
|
-
const yearAndMonth = moment(date).format(`YYYY
|
|
209
|
+
const yearAndMonth = moment(date).format(`MM/YYYY`);
|
|
160
210
|
if (!acc[year][yearAndMonth]) {
|
|
161
211
|
acc[year][yearAndMonth] = [];
|
|
162
212
|
}
|
|
@@ -215,6 +265,13 @@ export const getCheckboxes = (
|
|
|
215
265
|
level,
|
|
216
266
|
}));
|
|
217
267
|
|
|
268
|
+
export const dateFilter = (key: string): DataGridFilter<'date'> => ({
|
|
269
|
+
type: 'date',
|
|
270
|
+
operator: 'before',
|
|
271
|
+
values: [''],
|
|
272
|
+
getter: (row) => row[key] ?? '',
|
|
273
|
+
});
|
|
274
|
+
|
|
218
275
|
export const textFilter = (key: string): DataGridFilter<'text'> => ({
|
|
219
276
|
type: 'text',
|
|
220
277
|
operator: 'contains',
|
|
@@ -67,6 +67,11 @@ export const useDataGridCopy = <R>({
|
|
|
67
67
|
? "mso-number-format: '" + col.excelFormatter(col) + "';"
|
|
68
68
|
: ''
|
|
69
69
|
}
|
|
70
|
+
${
|
|
71
|
+
col.excelBackgroundColor
|
|
72
|
+
? "background-color: '" + col.excelBackgroundColor(value) + "';"
|
|
73
|
+
: ''
|
|
74
|
+
}
|
|
70
75
|
white-space: nowrap;
|
|
71
76
|
">
|
|
72
77
|
${generateCellText(col, value)}
|
|
@@ -7,7 +7,6 @@ export const TOOLBAR_HEIGHT = 40;
|
|
|
7
7
|
export const DEFAULT_HEADER_ROW_HEIGHT = 40;
|
|
8
8
|
export const DEFAULT_FOOTER_ROW_HEIGHT = 40;
|
|
9
9
|
export const DEFAULT_ROW_HEIGHT = 32;
|
|
10
|
-
export const DEFAULT_FILTER_ROW_HEIGHT = 24;
|
|
11
10
|
|
|
12
11
|
export const TopPaddingRow = styled.div``;
|
|
13
12
|
export const BottomPaddingRow = styled.div``;
|
|
@@ -322,46 +321,3 @@ export const ResizeBackdrop = styled.div.attrs({
|
|
|
322
321
|
cursor: col-resize;
|
|
323
322
|
`;
|
|
324
323
|
ResizeBackdrop.displayName = 'ResizeBackdrop';
|
|
325
|
-
|
|
326
|
-
export const FilterValuesScrollerContainer = styled.div.attrs({
|
|
327
|
-
className: 'FilterValuesScrollerContainer',
|
|
328
|
-
})<{
|
|
329
|
-
$rowHeight?: number;
|
|
330
|
-
}>`
|
|
331
|
-
display: block;
|
|
332
|
-
font-size: var(--text-base);
|
|
333
|
-
background-color: var(--color-neutral-0);
|
|
334
|
-
overflow-y: scroll;
|
|
335
|
-
overflow-x: hidden;
|
|
336
|
-
height: 100%;
|
|
337
|
-
|
|
338
|
-
& > div {
|
|
339
|
-
position: relative;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
& .checkbox {
|
|
343
|
-
position: absolute;
|
|
344
|
-
display: flex;
|
|
345
|
-
flex-direction: row;
|
|
346
|
-
align-items: center;
|
|
347
|
-
height: ${({ $rowHeight = DEFAULT_FILTER_ROW_HEIGHT }) =>
|
|
348
|
-
`${$rowHeight}px`};
|
|
349
|
-
|
|
350
|
-
input[type='checkbox'] {
|
|
351
|
-
margin-right: var(--space-1);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
`;
|
|
355
|
-
|
|
356
|
-
export const FilterValueContainer = styled.div.attrs({
|
|
357
|
-
className: 'FilterValueContainer',
|
|
358
|
-
})`
|
|
359
|
-
position: absolute;
|
|
360
|
-
display: flex;
|
|
361
|
-
flex-direction: row;
|
|
362
|
-
align-items: center;
|
|
363
|
-
cursor: pointer;
|
|
364
|
-
&:hover {
|
|
365
|
-
background-color: var(--color-neutral-50);
|
|
366
|
-
}
|
|
367
|
-
`;
|
|
@@ -38,6 +38,7 @@ export type DataGridColumn<R> = {
|
|
|
38
38
|
component?: DataGridCellFC;
|
|
39
39
|
editable?: boolean;
|
|
40
40
|
excelFormatter?: (value: any) => string;
|
|
41
|
+
excelBackgroundColor?: (value: any) => string;
|
|
41
42
|
excelValue?: (value: any) => string;
|
|
42
43
|
filter?: DataGridFilter;
|
|
43
44
|
footer?:
|
|
@@ -193,6 +194,10 @@ export type DataGridFilterOperators<K extends string, T> = {
|
|
|
193
194
|
};
|
|
194
195
|
|
|
195
196
|
export type DataGridFilterPredicates = {
|
|
197
|
+
date: DataGridFilterOperators<
|
|
198
|
+
'before' | 'after' | 'equals' | 'notEquals' | 'inRange' | 'inArray',
|
|
199
|
+
string
|
|
200
|
+
>;
|
|
196
201
|
text: DataGridFilterOperators<
|
|
197
202
|
| 'contains'
|
|
198
203
|
| 'notContains'
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
|
|
3
3
|
import { SqlRequestDataGridColumn, SqlRequestDataGridColumns } from '../types';
|
|
4
|
+
import {
|
|
5
|
+
buildExcelFormat,
|
|
6
|
+
numberFilter,
|
|
7
|
+
textFilter,
|
|
8
|
+
} from '../../DataGrid/helpers';
|
|
4
9
|
import {
|
|
5
10
|
formatMoney,
|
|
6
11
|
formatNumber,
|
|
12
|
+
formatNumberInvariant,
|
|
7
13
|
formatPercentage,
|
|
8
14
|
} from '../../../../helpers/numbers';
|
|
9
|
-
import { numberFilter, textFilter } from '../../DataGrid/helpers';
|
|
10
15
|
|
|
11
16
|
import { formatDate } from '../../../../helpers/dates';
|
|
12
17
|
|
|
@@ -103,7 +108,14 @@ export const sqlDateColumn = <R extends Record<string, any>>(
|
|
|
103
108
|
render: (row) => formatDate(row[key]),
|
|
104
109
|
getter: (row) => row[key] ?? '',
|
|
105
110
|
sortGetter: (row) => row[key] ?? '',
|
|
106
|
-
|
|
111
|
+
excelFormatter: () => 'dd/mm/yyyy',
|
|
112
|
+
excelValue: (value) => formatDate(value, 'YYYY-MM-DD'),
|
|
113
|
+
filter: {
|
|
114
|
+
...textFilter(key),
|
|
115
|
+
getter: (value) => value[key] ?? '',
|
|
116
|
+
formatter: (value) => formatDate(value),
|
|
117
|
+
renderer: (value) => formatDate(value),
|
|
118
|
+
},
|
|
107
119
|
footer: (rows) => `${rows[0][key]} éléments`,
|
|
108
120
|
...options,
|
|
109
121
|
},
|
|
@@ -134,7 +146,8 @@ export const sqlNumberColumn = <R extends Record<string, any>>(
|
|
|
134
146
|
[key]: {
|
|
135
147
|
name: title,
|
|
136
148
|
render: (row) => formatNumber(row[key], decimals) ?? '',
|
|
137
|
-
excelFormatter: () =>
|
|
149
|
+
excelFormatter: () => buildExcelFormat(decimals),
|
|
150
|
+
excelValue: (value) => formatNumberInvariant(value, decimals),
|
|
138
151
|
getter: (row) => row[key] ?? '',
|
|
139
152
|
sortGetter: (row) => row[key] ?? '',
|
|
140
153
|
filter: {
|
|
@@ -163,7 +176,8 @@ export const sqlMoneyColumn = <R extends Record<string, any>>(
|
|
|
163
176
|
name: title,
|
|
164
177
|
type: 'number',
|
|
165
178
|
render: (row) => formatMoney(row[key], decimals) ?? '',
|
|
166
|
-
excelFormatter: () => '
|
|
179
|
+
excelFormatter: () => buildExcelFormat(decimals, ' €'),
|
|
180
|
+
excelValue: (value) => formatNumberInvariant(value, decimals),
|
|
167
181
|
getter: (row) => row[key] ?? '',
|
|
168
182
|
sortGetter: (row) => row[key] ?? '',
|
|
169
183
|
filter: {
|
|
@@ -191,7 +205,8 @@ export const sqlPercentageColumn = <R extends Record<string, any>>(
|
|
|
191
205
|
[key]: {
|
|
192
206
|
name: title,
|
|
193
207
|
render: (row) => formatPercentage(row[key]) ?? '',
|
|
194
|
-
excelFormatter: () => '
|
|
208
|
+
excelFormatter: () => buildExcelFormat(decimals, '%'),
|
|
209
|
+
excelValue: (value) => formatNumberInvariant(value, decimals),
|
|
195
210
|
getter: (row) => row[key] ?? '',
|
|
196
211
|
sortGetter: (row) => row[key] ?? '',
|
|
197
212
|
filter: {
|
|
@@ -238,6 +253,8 @@ export const sqlColorColumn = <R extends Record<string, any>>(
|
|
|
238
253
|
|
|
239
254
|
</div>
|
|
240
255
|
),
|
|
256
|
+
excelValue: () => '',
|
|
257
|
+
excelBackgroundColor: (value) => value,
|
|
241
258
|
getter: (row) => row[key] ?? '',
|
|
242
259
|
sortGetter: (row) => row[key] ?? '',
|
|
243
260
|
filter: {
|
package/src/helpers/numbers.ts
CHANGED
|
@@ -18,3 +18,9 @@ export const formatNumber = (number: number, decimals = 2) =>
|
|
|
18
18
|
minimumFractionDigits: decimals,
|
|
19
19
|
maximumFractionDigits: decimals,
|
|
20
20
|
}).format(number);
|
|
21
|
+
|
|
22
|
+
export const formatNumberInvariant = (number: number, decimals = 2) =>
|
|
23
|
+
new Intl.NumberFormat('es-US', {
|
|
24
|
+
minimumFractionDigits: decimals,
|
|
25
|
+
maximumFractionDigits: decimals,
|
|
26
|
+
}).format(number);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SqlRequestRow } from './sqlRequests';
|
|
2
|
+
import { useWebSocketRequestHandler } from './hooks';
|
|
3
|
+
|
|
4
|
+
export type GlobalSearchRequestDTO = {
|
|
5
|
+
types: string[];
|
|
6
|
+
searchTerm: string;
|
|
7
|
+
limit?: number;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11
|
+
export type GlobalSearchResponseDTO<T = any> = {
|
|
12
|
+
data: Record<string, SqlRequestRow<T>[]>;
|
|
13
|
+
count?: number;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
type GlobalSearchRequestHandler<T> = (
|
|
17
|
+
request: GlobalSearchRequestDTO
|
|
18
|
+
) => Promise<GlobalSearchResponseDTO<T>>;
|
|
19
|
+
|
|
20
|
+
export const useGlobalSearchRequestHandler = <
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
+
T = any
|
|
23
|
+
>(): GlobalSearchRequestHandler<T> =>
|
|
24
|
+
useWebSocketRequestHandler<
|
|
25
|
+
GlobalSearchRequestDTO,
|
|
26
|
+
GlobalSearchResponseDTO<T>
|
|
27
|
+
>('GlobalSearch');
|