@addev-be/ui 2.6.0 → 2.7.0

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 (238) hide show
  1. package/assets/icons/arrow-down-1-9.svg +1 -1
  2. package/assets/icons/arrow-down-a-z.svg +1 -1
  3. package/assets/icons/arrow-up-z-a.svg +1 -1
  4. package/assets/icons/check.svg +1 -1
  5. package/assets/icons/circle-check.svg +1 -1
  6. package/assets/icons/down.svg +1 -1
  7. package/assets/icons/filter-full.svg +1 -1
  8. package/assets/icons/filter.svg +1 -1
  9. package/assets/icons/hashtag.svg +1 -1
  10. package/assets/icons/image-slash.svg +1 -1
  11. package/assets/icons/left.svg +1 -1
  12. package/assets/icons/magnifier.svg +1 -1
  13. package/assets/icons/phone.svg +1 -1
  14. package/assets/icons/right.svg +1 -1
  15. package/assets/icons/sort-calendar-ascending.svg +5 -5
  16. package/assets/icons/spinner-third.svg +1 -1
  17. package/assets/icons/table-columns.svg +1 -1
  18. package/assets/icons/table-footer-slash.svg +4 -4
  19. package/assets/icons/table-footer.svg +3 -3
  20. package/assets/icons/up.svg +1 -1
  21. package/assets/icons/user-tie.svg +1 -1
  22. package/assets/icons/x-bar.svg +3 -3
  23. package/dist/components/data/AdvancedRequestDataGrid/helpers/advancedRequests.js +8 -9
  24. package/dist/components/data/AdvancedRequestDataGrid/helpers/columns.js +72 -21
  25. package/dist/components/data/AdvancedRequestDataGrid/index.js +2 -2
  26. package/dist/components/data/AdvancedRequestDataGrid/types.d.ts +1 -1
  27. package/dist/components/data/SqlRequestDataGrid/SqlRequestForeignListEditableCell.d.ts +1 -2
  28. package/dist/components/data/SqlRequestDataGrid/SqlRequestForeignListEditableCell.js +3 -2
  29. package/dist/services/index.js +7 -17
  30. package/eslint.config.js +3 -3
  31. package/package.json +2 -2
  32. package/src/Icons.tsx +138 -138
  33. package/src/components/auth/LoginForm.tsx +86 -86
  34. package/src/components/auth/LoginPage.tsx +32 -32
  35. package/src/components/auth/PasswordRecoveryForm.tsx +53 -53
  36. package/src/components/auth/PasswordResetForm.tsx +112 -112
  37. package/src/components/auth/styles.ts +14 -14
  38. package/src/components/data/DataGrid/DataGridCell.tsx +81 -81
  39. package/src/components/data/DataGrid/DataGridColumnsModal/helpers.ts +9 -9
  40. package/src/components/data/DataGrid/DataGridColumnsModal/hooks.tsx +59 -59
  41. package/src/components/data/DataGrid/DataGridColumnsModal/index.tsx +182 -182
  42. package/src/components/data/DataGrid/DataGridColumnsModal/styles.ts +104 -104
  43. package/src/components/data/DataGrid/DataGridEditableCell/CheckboxEditableCell.tsx +37 -37
  44. package/src/components/data/DataGrid/DataGridEditableCell/DateEditableCell.tsx +38 -38
  45. package/src/components/data/DataGrid/DataGridEditableCell/NumberEditableCell.tsx +71 -71
  46. package/src/components/data/DataGrid/DataGridEditableCell/TextEditableCell.tsx +37 -37
  47. package/src/components/data/DataGrid/DataGridEditableCell/index.tsx +106 -106
  48. package/src/components/data/DataGrid/DataGridEditableCell/styles.ts +35 -35
  49. package/src/components/data/DataGrid/DataGridEditableCell/types.ts +18 -18
  50. package/src/components/data/DataGrid/DataGridFilterMenu/FilterValuesScroller.tsx +129 -129
  51. package/src/components/data/DataGrid/DataGridFilterMenu/hooks.tsx +81 -81
  52. package/src/components/data/DataGrid/DataGridFilterMenu/index.tsx +370 -370
  53. package/src/components/data/DataGrid/DataGridFilterMenu/styles.ts +97 -97
  54. package/src/components/data/DataGrid/DataGridFooter.tsx +47 -47
  55. package/src/components/data/DataGrid/DataGridHeader.tsx +74 -74
  56. package/src/components/data/DataGrid/DataGridHeaderCell.tsx +112 -112
  57. package/src/components/data/DataGrid/DataGridRowTemplate.tsx +83 -83
  58. package/src/components/data/DataGrid/DataGridToolbar.tsx +134 -134
  59. package/src/components/data/DataGrid/FilterModalContent/index.tsx +137 -137
  60. package/src/components/data/DataGrid/FilterModalContent/styles.ts +22 -22
  61. package/src/components/data/DataGrid/constants.ts +6 -6
  62. package/src/components/data/DataGrid/helpers/columns.tsx +449 -449
  63. package/src/components/data/DataGrid/helpers/filters.ts +287 -287
  64. package/src/components/data/DataGrid/helpers/index.ts +2 -2
  65. package/src/components/data/DataGrid/hooks/index.ts +29 -29
  66. package/src/components/data/DataGrid/hooks/useDataGrid.tsx +383 -383
  67. package/src/components/data/DataGrid/hooks/useDataGridChangedRows.ts +97 -97
  68. package/src/components/data/DataGrid/hooks/useDataGridCopy.ts +174 -174
  69. package/src/components/data/DataGrid/hooks/useDataGridSettings.ts +48 -48
  70. package/src/components/data/DataGrid/hooks/useRefreshModal.tsx +48 -48
  71. package/src/components/data/DataGrid/index.tsx +111 -111
  72. package/src/components/data/DataGrid/styles.ts +434 -434
  73. package/src/components/data/DataGrid/types.ts +380 -380
  74. package/src/components/data/SqlRequestDataGrid/helpers/columns.tsx +526 -526
  75. package/src/components/data/SqlRequestDataGrid/helpers/index.ts +2 -2
  76. package/src/components/data/SqlRequestDataGrid/helpers/rows.ts +24 -24
  77. package/src/components/data/SqlRequestDataGrid/helpers/sqlRequests.ts +17 -17
  78. package/src/components/data/SqlRequestDataGrid/index.tsx +417 -417
  79. package/src/components/data/SqlRequestDataGrid/styles.ts +15 -15
  80. package/src/components/data/SqlRequestDataGrid/types.ts +74 -74
  81. package/src/components/data/SqlRequestForeignList/index.tsx +254 -254
  82. package/src/components/data/SqlRequestForeignList/styles.ts +43 -43
  83. package/src/components/data/SqlRequestForeignList/types.ts +32 -32
  84. package/src/components/data/SqlRequestGrid/filters/FiltersSidebar.tsx +108 -108
  85. package/src/components/data/SqlRequestGrid/filters/styles.ts +88 -88
  86. package/src/components/data/SqlRequestGrid/helpers/index.ts +1 -1
  87. package/src/components/data/SqlRequestGrid/helpers/sqlRequests.ts +16 -16
  88. package/src/components/data/SqlRequestGrid/index.tsx +304 -304
  89. package/src/components/data/SqlRequestGrid/styles.ts +20 -20
  90. package/src/components/data/SqlRequestGrid/types.ts +73 -73
  91. package/src/components/data/VirtualScroller/hooks.ts +71 -71
  92. package/src/components/data/VirtualScroller/index.tsx +89 -89
  93. package/src/components/data/VirtualScroller/styles.ts +57 -57
  94. package/src/components/data/VirtualScroller/types.ts +10 -10
  95. package/src/components/forms/AutoTextArea.tsx +48 -48
  96. package/src/components/forms/BillitIdentifier/index.tsx +78 -78
  97. package/src/components/forms/BillitIdentifier/styles.tsx +43 -43
  98. package/src/components/forms/Button.tsx +132 -132
  99. package/src/components/forms/Form/Checkbox.tsx +12 -12
  100. package/src/components/forms/Form/CustomSelect.tsx +86 -86
  101. package/src/components/forms/Form/FormGroup.tsx +33 -33
  102. package/src/components/forms/Form/Input.tsx +16 -16
  103. package/src/components/forms/Form/Row.tsx +28 -28
  104. package/src/components/forms/Form/Select.tsx +99 -99
  105. package/src/components/forms/Form/TextArea.tsx +17 -17
  106. package/src/components/forms/Form/index.tsx +48 -48
  107. package/src/components/forms/Form/styles.ts +148 -148
  108. package/src/components/forms/IconButton.tsx +61 -61
  109. package/src/components/forms/IndeterminateCheckbox.tsx +46 -46
  110. package/src/components/forms/NumberInput.tsx +53 -53
  111. package/src/components/forms/Select.tsx +34 -34
  112. package/src/components/forms/VerticalLabel.tsx +20 -20
  113. package/src/components/forms/styles.ts +42 -42
  114. package/src/components/layout/Columns.ts +28 -28
  115. package/src/components/layout/Dropdown/index.tsx +113 -113
  116. package/src/components/layout/Dropdown/styles.ts +53 -53
  117. package/src/components/layout/Flexbox.ts +21 -21
  118. package/src/components/layout/Grid/index.tsx +8 -8
  119. package/src/components/layout/Grid/styles.ts +34 -34
  120. package/src/components/layout/Loading/index.tsx +29 -29
  121. package/src/components/layout/Loading/styles.ts +29 -29
  122. package/src/components/layout/Masonry/index.tsx +29 -29
  123. package/src/components/layout/Masonry/styles.ts +20 -20
  124. package/src/components/layout/Modal/index.tsx +51 -51
  125. package/src/components/layout/Modal/styles.ts +125 -125
  126. package/src/components/search/HighlightedText.tsx +41 -41
  127. package/src/components/search/QuickSearchBar.tsx +102 -102
  128. package/src/components/search/QuickSearchResults.tsx +86 -86
  129. package/src/components/search/styles.ts +96 -96
  130. package/src/components/search/types.ts +29 -29
  131. package/src/components/ui/Avatar/index.tsx +54 -54
  132. package/src/components/ui/Card/index.tsx +16 -16
  133. package/src/components/ui/Card/styles.ts +41 -41
  134. package/src/components/ui/ContextMenu/index.tsx +79 -79
  135. package/src/components/ui/ContextMenu/styles.ts +119 -119
  136. package/src/components/ui/Ellipsis.tsx +33 -33
  137. package/src/components/ui/Label.tsx +93 -93
  138. package/src/components/ui/Message/index.tsx +57 -57
  139. package/src/components/ui/Message/styles.ts +44 -44
  140. package/src/components/ui/TabsView/TabsList.tsx +49 -49
  141. package/src/components/ui/TabsView/TabsView.tsx +42 -42
  142. package/src/components/ui/TabsView/styles.ts +84 -84
  143. package/src/components/ui/TabsView/types.ts +15 -15
  144. package/src/config/index.ts +10 -10
  145. package/src/helpers/components.ts +9 -9
  146. package/src/helpers/dates.ts +17 -17
  147. package/src/helpers/getScrollbarSize.ts +14 -14
  148. package/src/helpers/numbers.ts +63 -63
  149. package/src/helpers/responsive.ts +83 -83
  150. package/src/helpers/styled/space.ts +114 -114
  151. package/src/helpers/styled/typography.ts +25 -25
  152. package/src/helpers/text.ts +13 -13
  153. package/src/helpers/types.ts +9 -9
  154. package/src/hooks/useContainerMediaQuery.ts +7 -7
  155. package/src/hooks/useElementSize.ts +24 -24
  156. package/src/hooks/useMediaQuery.ts +9 -9
  157. package/src/hooks/useMediaQueryForWidth.ts +35 -35
  158. package/src/hooks/useMutableState.test.ts +410 -410
  159. package/src/hooks/useMutableState.ts +39 -39
  160. package/src/hooks/useShowArchived.ts +28 -28
  161. package/src/hooks/useWindowSize.ts +20 -20
  162. package/src/index.ts +103 -103
  163. package/src/providers/AuthenticationProvider/helpers.ts +3 -3
  164. package/src/providers/AuthenticationProvider/index.tsx +303 -303
  165. package/src/providers/LoadingProvider/index.tsx +47 -47
  166. package/src/providers/PortalsProvider/index.tsx +54 -54
  167. package/src/providers/PortalsProvider/styles.ts +31 -31
  168. package/src/providers/SettingsProvider/index.tsx +70 -70
  169. package/src/providers/ThemeProvider/defaultTheme.ts +471 -471
  170. package/src/providers/ThemeProvider/helpers.ts +84 -84
  171. package/src/providers/ThemeProvider/index.ts +73 -73
  172. package/src/providers/ThemeProvider/types.ts +134 -134
  173. package/src/providers/ToastProvider/index.tsx +93 -93
  174. package/src/providers/TrackingProvider/index.tsx +71 -71
  175. package/src/providers/UiProviders/index.tsx +76 -76
  176. package/src/providers/UiProviders/styles.ts +10 -10
  177. package/src/providers/hooks.ts +14 -14
  178. package/src/services/HttpService.ts +92 -92
  179. package/src/services/WebSocketService.ts +155 -155
  180. package/src/services/advancedRequests.ts +102 -102
  181. package/src/services/base.ts +23 -23
  182. package/src/services/globalSearch.ts +32 -32
  183. package/src/services/hooks.ts +92 -92
  184. package/src/services/requests/auth.ts +44 -44
  185. package/src/services/requests/generic.ts +62 -62
  186. package/src/services/requests/printing.ts +12 -12
  187. package/src/services/requests/tracking.ts +12 -12
  188. package/src/services/requests/userProfiles.ts +35 -35
  189. package/src/services/requests/users.ts +28 -28
  190. package/src/services/smartQueries.ts +122 -122
  191. package/src/services/sqlRequests.ts +119 -119
  192. package/src/services/types/auth.ts +98 -98
  193. package/src/services/types/base.ts +10 -10
  194. package/src/services/types/generic.ts +82 -82
  195. package/src/services/types/printing.ts +10 -10
  196. package/src/services/types/tracking.ts +29 -29
  197. package/src/services/types/userProfiles.ts +79 -79
  198. package/src/services/types/users.ts +74 -74
  199. package/src/services/updateSqlRequests.ts +32 -32
  200. package/src/styles/animations.scss +30 -30
  201. package/src/styles/index.scss +42 -42
  202. package/src/types.ts +8 -8
  203. package/src/typings.d.ts +2 -2
  204. package/tsconfig.json +18 -18
  205. package/dist/components/data/DataGrid/AdvancedRequestDataGrid.d.ts +0 -10
  206. package/dist/components/data/DataGrid/AdvancedRequestDataGrid.js +0 -173
  207. package/dist/components/data/DataGrid/FilterValuesScroller.d.ts +0 -13
  208. package/dist/components/data/DataGrid/FilterValuesScroller.js +0 -73
  209. package/dist/components/data/DataGrid/VirtualScroller.d.ts +0 -11
  210. package/dist/components/data/DataGrid/VirtualScroller.js +0 -41
  211. package/dist/components/data/DataGrid/helpers/advancedRequests.d.ts +0 -12
  212. package/dist/components/data/DataGrid/helpers/advancedRequests.js +0 -53
  213. package/dist/components/data/DataGrid/helpers.d.ts +0 -28
  214. package/dist/components/data/DataGrid/helpers.js +0 -436
  215. package/dist/components/data/SmartQueryDataGrid/helpers/columns.d.ts +0 -20
  216. package/dist/components/data/SmartQueryDataGrid/helpers/columns.js +0 -160
  217. package/dist/components/data/SmartQueryDataGrid/helpers/hooks.d.ts +0 -5
  218. package/dist/components/data/SmartQueryDataGrid/helpers/hooks.js +0 -41
  219. package/dist/components/data/SmartQueryDataGrid/helpers/index.d.ts +0 -2
  220. package/dist/components/data/SmartQueryDataGrid/helpers/index.js +0 -18
  221. package/dist/components/data/SmartQueryDataGrid/helpers/smartQueries.d.ts +0 -3
  222. package/dist/components/data/SmartQueryDataGrid/helpers/smartQueries.js +0 -15
  223. package/dist/components/data/SmartQueryDataGrid/hooks.d.ts +0 -9
  224. package/dist/components/data/SmartQueryDataGrid/hooks.js +0 -63
  225. package/dist/components/data/SmartQueryDataGrid/index.d.ts +0 -12
  226. package/dist/components/data/SmartQueryDataGrid/index.js +0 -242
  227. package/dist/components/data/SmartQueryDataGrid/types.d.ts +0 -22
  228. package/dist/components/data/SmartQueryDataGrid/types.js +0 -2
  229. package/dist/components/forms/Form/InputWithLabel.d.ts +0 -2
  230. package/dist/components/forms/Form/InputWithLabel.js +0 -10
  231. package/dist/components/forms/Form/types.d.ts +0 -7
  232. package/dist/components/forms/Form/types.js +0 -2
  233. package/dist/config/types.d.ts +0 -11
  234. package/dist/config/types.js +0 -2
  235. package/dist/helpers/react.d.ts +0 -2
  236. package/dist/helpers/react.js +0 -8
  237. package/dist/services/requests/userPermissions.d.ts +0 -4
  238. package/dist/services/requests/userPermissions.js +0 -20
@@ -1,370 +1,370 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
-
3
- import * as styles from './styles';
4
-
5
- import {
6
- ArrowDown19Icon,
7
- ArrowDownAZIcon,
8
- ArrowDownBigSmallIcon,
9
- ArrowUp91Icon,
10
- ArrowUpBigSmallIcon,
11
- ArrowUpZAIcon,
12
- FilterIcon,
13
- FilterSlashIcon,
14
- IconFC,
15
- MagnifierIcon,
16
- SigmaIcon,
17
- SortCalendarAscendingIcon,
18
- SortCalendarDescendingIcon,
19
- TableFooterIcon,
20
- TableFooterSlashIcon,
21
- TallyIcon,
22
- XBarIcon,
23
- } from '../../../../Icons';
24
- import {
25
- DataGridColumnWithFilter,
26
- DataGridContext,
27
- DataGridFilterType,
28
- DataGridFilterValue,
29
- DataGridFooterPredefinedFunction,
30
- } from '../types';
31
- import {
32
- applyFilters,
33
- defaultRendererAndFormatter,
34
- getDateGroups,
35
- } from '../helpers';
36
- import { intersection, without } from 'lodash';
37
- import {
38
- useCallback,
39
- useContext,
40
- useEffect,
41
- useMemo,
42
- useRef,
43
- useState,
44
- } from 'react';
45
-
46
- import { ContextMenu } from '../../../ui/ContextMenu';
47
- import { FilterValuesScroller } from './FilterValuesScroller';
48
- import { Input } from '../../../forms/styles';
49
- import { MenuContainer } from '../../../ui/ContextMenu/styles';
50
- import { sortAvailableValues } from './helpers';
51
- import { useFilterModal } from './hooks';
52
-
53
- type FilterValuesProps<R> = {
54
- column: DataGridColumnWithFilter<R>;
55
- context: DataGridContext<R>;
56
- onClose?: () => void;
57
- contextMenu?: boolean;
58
- showTotalButton?: boolean;
59
- };
60
-
61
- const sortAsc: Record<DataGridFilterType, [string, IconFC]> = {
62
- number: ['Trier du plus petit au plus grand', ArrowDown19Icon],
63
- text: ['Trier de A à Z', ArrowDownAZIcon],
64
- date: ['Trier du plus ancien au plus récent', SortCalendarAscendingIcon],
65
- };
66
- const sortDesc: Record<DataGridFilterType, [string, IconFC]> = {
67
- number: ['Trier du plus grand au plus petit', ArrowUp91Icon],
68
- text: ['Trier de Z à A', ArrowUpZAIcon],
69
- date: ['Trier du plus récent au plus ancien', SortCalendarDescendingIcon],
70
- };
71
-
72
- const footerFunctionsTexts: Record<DataGridFooterPredefinedFunction, string> = {
73
- average: 'Moyenne',
74
- avg: 'Moyenne',
75
- count: 'Nombre',
76
- max: 'Maximum',
77
- min: 'Minimum',
78
- sum: 'Somme',
79
- };
80
- const footerFunctionsIcons: Record<DataGridFooterPredefinedFunction, IconFC> = {
81
- average: XBarIcon,
82
- avg: XBarIcon,
83
- count: TallyIcon,
84
- max: ArrowUpBigSmallIcon,
85
- min: ArrowDownBigSmallIcon,
86
- sum: SigmaIcon,
87
- };
88
-
89
- export const DataGridFilterMenu = <R,>({
90
- column,
91
- context,
92
- onClose,
93
- contextMenu = true,
94
- showTotalButton = true,
95
- }: FilterValuesProps<R>) => {
96
- const { openModal, modal } = useFilterModal({ column, context, onClose });
97
- const {
98
- filters = {},
99
- footers = {},
100
- rows,
101
- setFilters,
102
- filterValuesLoader,
103
- setSorts,
104
- setFooters,
105
- } = useContext(context);
106
- const textFilterInputRef = useRef<HTMLInputElement>(null);
107
- const [textFilter, setTextFilter] = useState('');
108
-
109
- const [availableValues, setAvailableValues] = useState<DataGridFilterValue[]>(
110
- []
111
- );
112
-
113
- useEffect(() => {
114
- if (filterValuesLoader) {
115
- filterValuesLoader(column.key).then((values) => {
116
- setAvailableValues(() => values);
117
- });
118
- } else {
119
- const otherFilters = Object.entries(filters)
120
- .filter(([key]) => key !== column.key)
121
- .map(([, filter]) => filter);
122
- const availableRows = applyFilters(rows, otherFilters);
123
- const values = availableRows.map((row) => column.filter!.getter(row));
124
- setAvailableValues(() => sortAvailableValues(values, column));
125
- }
126
- }, [column, filterValuesLoader, filters, rows]);
127
-
128
- const selectedValues = useMemo(
129
- () => filters?.[column.key]?.values ?? [],
130
- [column.key, filters]
131
- );
132
-
133
- const clearFilter = useCallback(() => {
134
- const newFilters = { ...filters };
135
- delete newFilters[column.key];
136
- setFilters(newFilters);
137
- onClose?.();
138
- }, [filters, column.key, setFilters, onClose]);
139
-
140
- const setValuesChecked = useCallback(
141
- (values: any[], checked?: boolean) => {
142
- setFilters((prevFilters) => {
143
- const newValues = checked
144
- ? [...(prevFilters[column.key]?.values ?? []), ...values]
145
- : without(prevFilters[column.key]?.values ?? [], ...values);
146
- const newFilters = {
147
- ...prevFilters,
148
- };
149
- if (newValues.length === 0) {
150
- delete newFilters[column.key];
151
- } else {
152
- newFilters[column.key] = {
153
- ...(prevFilters[column.key] ?? column.filter),
154
- operator: 'inArray',
155
- values: newValues,
156
- };
157
- }
158
- return newFilters;
159
- });
160
- },
161
- [setFilters, column.key, column.filter]
162
- );
163
-
164
- const toggleValues = useCallback(
165
- (values: DataGridFilterValue[]) => {
166
- const checked =
167
- intersection(selectedValues, values).length === values.length;
168
- setValuesChecked(values, !checked);
169
- },
170
- [setValuesChecked, selectedValues]
171
- );
172
-
173
- const formatter = useMemo(
174
- () => column.filter?.formatter ?? defaultRendererAndFormatter,
175
- [column.filter?.formatter]
176
- );
177
- const renderer = useMemo(
178
- () => column.filter?.renderer ?? defaultRendererAndFormatter,
179
- [column.filter?.renderer]
180
- );
181
-
182
- const filteredAvailableValues = useMemo(
183
- () =>
184
- !textFilter
185
- ? availableValues
186
- : availableValues.filter((value) =>
187
- formatter(value)?.toLowerCase().includes(textFilter.toLowerCase())
188
- ),
189
- [availableValues, formatter, textFilter]
190
- );
191
-
192
- useEffect(() => {
193
- if (textFilterInputRef.current) {
194
- textFilterInputRef.current.focus();
195
- }
196
- }, []);
197
-
198
- const checkboxesComponent = useMemo(() => {
199
- const groups =
200
- column.type === 'date'
201
- ? getDateGroups(filteredAvailableValues)
202
- : undefined;
203
- return (
204
- <FilterValuesScroller
205
- values={filteredAvailableValues}
206
- selectedValues={selectedValues}
207
- onToggle={toggleValues}
208
- formatter={formatter}
209
- renderer={renderer}
210
- groups={groups}
211
- />
212
- );
213
- }, [
214
- column.type,
215
- filteredAvailableValues,
216
- formatter,
217
- renderer,
218
- selectedValues,
219
- toggleValues,
220
- ]);
221
-
222
- const onSortAscClicked = useCallback(() => {
223
- setSorts({ [column.key]: 'asc' });
224
- onClose?.();
225
- }, [column.key, onClose, setSorts]);
226
- const onSortDescClicked = useCallback(() => {
227
- setSorts({ [column.key]: 'desc' });
228
- onClose?.();
229
- }, [column.key, onClose, setSorts]);
230
-
231
- const hasFilters = filters[column.key]?.values.length > 0;
232
- const [[sortAscText, SortAscIcon], [sortDescText, SortDescIcon]] = [
233
- sortAsc[column.filter?.type ?? 'text'],
234
- sortDesc[column.filter?.type ?? 'text'],
235
- ];
236
-
237
- const isFooterVisible =
238
- column.key in footers && footers[column.key] !== undefined;
239
- const showFooter = useCallback(
240
- (key: string) => {
241
- setFooters((prevFooters) => ({
242
- ...prevFooters,
243
- [column.key]: key,
244
- }));
245
- onClose?.();
246
- },
247
- [column.key, onClose, setFooters]
248
- );
249
- const hideFooter = useCallback(() => {
250
- setFooters((prevFooters) => {
251
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
252
- const { [column.key]: _, ...newFooters } = prevFooters;
253
- return newFooters;
254
- });
255
- onClose?.();
256
- }, [column.key, onClose, setFooters]);
257
-
258
- const content = (
259
- <>
260
- {modal}
261
- {column.sortGetter && (
262
- <>
263
- <ContextMenu.Item onClick={onSortAscClicked}>
264
- <SortAscIcon />
265
- {sortAscText}
266
- </ContextMenu.Item>
267
- <ContextMenu.Item onClick={onSortDescClicked}>
268
- <SortDescIcon />
269
- {sortDescText}
270
- </ContextMenu.Item>
271
- <ContextMenu.Divider />
272
- </>
273
- )}
274
- {isFooterVisible && typeof column.footer === 'function' && (
275
- <>
276
- <ContextMenu.Item onClick={hideFooter}>
277
- <TableFooterSlashIcon />
278
- Masquer le total
279
- </ContextMenu.Item>
280
- <ContextMenu.Divider />
281
- </>
282
- )}
283
- {showTotalButton && (
284
- <>
285
- {!isFooterVisible && typeof column.footer === 'function' && (
286
- <>
287
- <ContextMenu.Item onClick={() => showFooter('count')}>
288
- <TableFooterIcon />
289
- Afficher le total
290
- </ContextMenu.Item>
291
- <ContextMenu.Divider />
292
- </>
293
- )}
294
- {showTotalButton && typeof column.footer === 'object' && (
295
- <>
296
- <ContextMenu.ParentItem>
297
- <TableFooterIcon />
298
- Afficher le total
299
- <ContextMenu.SubMenu>
300
- {Object.keys(column.footer).map((key) => {
301
- const TotalIcon =
302
- footerFunctionsIcons[
303
- key as DataGridFooterPredefinedFunction
304
- ] ?? TableFooterIcon;
305
- return (
306
- <ContextMenu.Item
307
- key={key}
308
- onClick={() => showFooter(key)}
309
- >
310
- <TotalIcon />
311
- {key in footerFunctionsTexts
312
- ? footerFunctionsTexts[
313
- key as DataGridFooterPredefinedFunction
314
- ]
315
- : key}
316
- </ContextMenu.Item>
317
- );
318
- })}
319
- <ContextMenu.Divider />
320
- <ContextMenu.Item
321
- onClick={hideFooter}
322
- disabled={!isFooterVisible}
323
- >
324
- <TableFooterSlashIcon />
325
- Masquer le total
326
- </ContextMenu.Item>
327
- </ContextMenu.SubMenu>
328
- </ContextMenu.ParentItem>
329
- <ContextMenu.Divider />
330
- </>
331
- )}
332
- </>
333
- )}
334
- <ContextMenu.Item onClick={openModal}>
335
- <FilterIcon />
336
- Filtrer ...
337
- </ContextMenu.Item>
338
- <ContextMenu.Item
339
- $color="danger"
340
- onClick={clearFilter}
341
- disabled={!hasFilters}
342
- >
343
- <FilterSlashIcon />
344
- Supprimer le filtre
345
- </ContextMenu.Item>
346
- <ContextMenu.Divider />
347
- <styles.InputContainer>
348
- <MagnifierIcon />
349
- <Input
350
- ref={textFilterInputRef}
351
- type="text"
352
- name="search"
353
- id="search"
354
- placeholder="Rechercher ..."
355
- value={textFilter}
356
- onChange={(e) => setTextFilter(e.target.value)}
357
- />
358
- </styles.InputContainer>
359
- <styles.CheckboxesContainer>
360
- {checkboxesComponent}
361
- </styles.CheckboxesContainer>
362
- </>
363
- );
364
-
365
- if (!contextMenu) {
366
- return <MenuContainer>{content}</MenuContainer>;
367
- }
368
-
369
- return <ContextMenu>{content}</ContextMenu>;
370
- };
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+
3
+ import * as styles from './styles';
4
+
5
+ import {
6
+ ArrowDown19Icon,
7
+ ArrowDownAZIcon,
8
+ ArrowDownBigSmallIcon,
9
+ ArrowUp91Icon,
10
+ ArrowUpBigSmallIcon,
11
+ ArrowUpZAIcon,
12
+ FilterIcon,
13
+ FilterSlashIcon,
14
+ IconFC,
15
+ MagnifierIcon,
16
+ SigmaIcon,
17
+ SortCalendarAscendingIcon,
18
+ SortCalendarDescendingIcon,
19
+ TableFooterIcon,
20
+ TableFooterSlashIcon,
21
+ TallyIcon,
22
+ XBarIcon,
23
+ } from '../../../../Icons';
24
+ import {
25
+ DataGridColumnWithFilter,
26
+ DataGridContext,
27
+ DataGridFilterType,
28
+ DataGridFilterValue,
29
+ DataGridFooterPredefinedFunction,
30
+ } from '../types';
31
+ import {
32
+ applyFilters,
33
+ defaultRendererAndFormatter,
34
+ getDateGroups,
35
+ } from '../helpers';
36
+ import { intersection, without } from 'lodash';
37
+ import {
38
+ useCallback,
39
+ useContext,
40
+ useEffect,
41
+ useMemo,
42
+ useRef,
43
+ useState,
44
+ } from 'react';
45
+
46
+ import { ContextMenu } from '../../../ui/ContextMenu';
47
+ import { FilterValuesScroller } from './FilterValuesScroller';
48
+ import { Input } from '../../../forms/styles';
49
+ import { MenuContainer } from '../../../ui/ContextMenu/styles';
50
+ import { sortAvailableValues } from './helpers';
51
+ import { useFilterModal } from './hooks';
52
+
53
+ type FilterValuesProps<R> = {
54
+ column: DataGridColumnWithFilter<R>;
55
+ context: DataGridContext<R>;
56
+ onClose?: () => void;
57
+ contextMenu?: boolean;
58
+ showTotalButton?: boolean;
59
+ };
60
+
61
+ const sortAsc: Record<DataGridFilterType, [string, IconFC]> = {
62
+ number: ['Trier du plus petit au plus grand', ArrowDown19Icon],
63
+ text: ['Trier de A à Z', ArrowDownAZIcon],
64
+ date: ['Trier du plus ancien au plus récent', SortCalendarAscendingIcon],
65
+ };
66
+ const sortDesc: Record<DataGridFilterType, [string, IconFC]> = {
67
+ number: ['Trier du plus grand au plus petit', ArrowUp91Icon],
68
+ text: ['Trier de Z à A', ArrowUpZAIcon],
69
+ date: ['Trier du plus récent au plus ancien', SortCalendarDescendingIcon],
70
+ };
71
+
72
+ const footerFunctionsTexts: Record<DataGridFooterPredefinedFunction, string> = {
73
+ average: 'Moyenne',
74
+ avg: 'Moyenne',
75
+ count: 'Nombre',
76
+ max: 'Maximum',
77
+ min: 'Minimum',
78
+ sum: 'Somme',
79
+ };
80
+ const footerFunctionsIcons: Record<DataGridFooterPredefinedFunction, IconFC> = {
81
+ average: XBarIcon,
82
+ avg: XBarIcon,
83
+ count: TallyIcon,
84
+ max: ArrowUpBigSmallIcon,
85
+ min: ArrowDownBigSmallIcon,
86
+ sum: SigmaIcon,
87
+ };
88
+
89
+ export const DataGridFilterMenu = <R,>({
90
+ column,
91
+ context,
92
+ onClose,
93
+ contextMenu = true,
94
+ showTotalButton = true,
95
+ }: FilterValuesProps<R>) => {
96
+ const { openModal, modal } = useFilterModal({ column, context, onClose });
97
+ const {
98
+ filters = {},
99
+ footers = {},
100
+ rows,
101
+ setFilters,
102
+ filterValuesLoader,
103
+ setSorts,
104
+ setFooters,
105
+ } = useContext(context);
106
+ const textFilterInputRef = useRef<HTMLInputElement>(null);
107
+ const [textFilter, setTextFilter] = useState('');
108
+
109
+ const [availableValues, setAvailableValues] = useState<DataGridFilterValue[]>(
110
+ []
111
+ );
112
+
113
+ useEffect(() => {
114
+ if (filterValuesLoader) {
115
+ filterValuesLoader(column.key).then((values) => {
116
+ setAvailableValues(() => values);
117
+ });
118
+ } else {
119
+ const otherFilters = Object.entries(filters)
120
+ .filter(([key]) => key !== column.key)
121
+ .map(([, filter]) => filter);
122
+ const availableRows = applyFilters(rows, otherFilters);
123
+ const values = availableRows.map((row) => column.filter!.getter(row));
124
+ setAvailableValues(() => sortAvailableValues(values, column));
125
+ }
126
+ }, [column, filterValuesLoader, filters, rows]);
127
+
128
+ const selectedValues = useMemo(
129
+ () => filters?.[column.key]?.values ?? [],
130
+ [column.key, filters]
131
+ );
132
+
133
+ const clearFilter = useCallback(() => {
134
+ const newFilters = { ...filters };
135
+ delete newFilters[column.key];
136
+ setFilters(newFilters);
137
+ onClose?.();
138
+ }, [filters, column.key, setFilters, onClose]);
139
+
140
+ const setValuesChecked = useCallback(
141
+ (values: any[], checked?: boolean) => {
142
+ setFilters((prevFilters) => {
143
+ const newValues = checked
144
+ ? [...(prevFilters[column.key]?.values ?? []), ...values]
145
+ : without(prevFilters[column.key]?.values ?? [], ...values);
146
+ const newFilters = {
147
+ ...prevFilters,
148
+ };
149
+ if (newValues.length === 0) {
150
+ delete newFilters[column.key];
151
+ } else {
152
+ newFilters[column.key] = {
153
+ ...(prevFilters[column.key] ?? column.filter),
154
+ operator: 'inArray',
155
+ values: newValues,
156
+ };
157
+ }
158
+ return newFilters;
159
+ });
160
+ },
161
+ [setFilters, column.key, column.filter]
162
+ );
163
+
164
+ const toggleValues = useCallback(
165
+ (values: DataGridFilterValue[]) => {
166
+ const checked =
167
+ intersection(selectedValues, values).length === values.length;
168
+ setValuesChecked(values, !checked);
169
+ },
170
+ [setValuesChecked, selectedValues]
171
+ );
172
+
173
+ const formatter = useMemo(
174
+ () => column.filter?.formatter ?? defaultRendererAndFormatter,
175
+ [column.filter?.formatter]
176
+ );
177
+ const renderer = useMemo(
178
+ () => column.filter?.renderer ?? defaultRendererAndFormatter,
179
+ [column.filter?.renderer]
180
+ );
181
+
182
+ const filteredAvailableValues = useMemo(
183
+ () =>
184
+ !textFilter
185
+ ? availableValues
186
+ : availableValues.filter((value) =>
187
+ formatter(value)?.toLowerCase().includes(textFilter.toLowerCase())
188
+ ),
189
+ [availableValues, formatter, textFilter]
190
+ );
191
+
192
+ useEffect(() => {
193
+ if (textFilterInputRef.current) {
194
+ textFilterInputRef.current.focus();
195
+ }
196
+ }, []);
197
+
198
+ const checkboxesComponent = useMemo(() => {
199
+ const groups =
200
+ column.type === 'date'
201
+ ? getDateGroups(filteredAvailableValues)
202
+ : undefined;
203
+ return (
204
+ <FilterValuesScroller
205
+ values={filteredAvailableValues}
206
+ selectedValues={selectedValues}
207
+ onToggle={toggleValues}
208
+ formatter={formatter}
209
+ renderer={renderer}
210
+ groups={groups}
211
+ />
212
+ );
213
+ }, [
214
+ column.type,
215
+ filteredAvailableValues,
216
+ formatter,
217
+ renderer,
218
+ selectedValues,
219
+ toggleValues,
220
+ ]);
221
+
222
+ const onSortAscClicked = useCallback(() => {
223
+ setSorts({ [column.key]: 'asc' });
224
+ onClose?.();
225
+ }, [column.key, onClose, setSorts]);
226
+ const onSortDescClicked = useCallback(() => {
227
+ setSorts({ [column.key]: 'desc' });
228
+ onClose?.();
229
+ }, [column.key, onClose, setSorts]);
230
+
231
+ const hasFilters = filters[column.key]?.values.length > 0;
232
+ const [[sortAscText, SortAscIcon], [sortDescText, SortDescIcon]] = [
233
+ sortAsc[column.filter?.type ?? 'text'],
234
+ sortDesc[column.filter?.type ?? 'text'],
235
+ ];
236
+
237
+ const isFooterVisible =
238
+ column.key in footers && footers[column.key] !== undefined;
239
+ const showFooter = useCallback(
240
+ (key: string) => {
241
+ setFooters((prevFooters) => ({
242
+ ...prevFooters,
243
+ [column.key]: key,
244
+ }));
245
+ onClose?.();
246
+ },
247
+ [column.key, onClose, setFooters]
248
+ );
249
+ const hideFooter = useCallback(() => {
250
+ setFooters((prevFooters) => {
251
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
252
+ const { [column.key]: _, ...newFooters } = prevFooters;
253
+ return newFooters;
254
+ });
255
+ onClose?.();
256
+ }, [column.key, onClose, setFooters]);
257
+
258
+ const content = (
259
+ <>
260
+ {modal}
261
+ {column.sortGetter && (
262
+ <>
263
+ <ContextMenu.Item onClick={onSortAscClicked}>
264
+ <SortAscIcon />
265
+ {sortAscText}
266
+ </ContextMenu.Item>
267
+ <ContextMenu.Item onClick={onSortDescClicked}>
268
+ <SortDescIcon />
269
+ {sortDescText}
270
+ </ContextMenu.Item>
271
+ <ContextMenu.Divider />
272
+ </>
273
+ )}
274
+ {isFooterVisible && typeof column.footer === 'function' && (
275
+ <>
276
+ <ContextMenu.Item onClick={hideFooter}>
277
+ <TableFooterSlashIcon />
278
+ Masquer le total
279
+ </ContextMenu.Item>
280
+ <ContextMenu.Divider />
281
+ </>
282
+ )}
283
+ {showTotalButton && (
284
+ <>
285
+ {!isFooterVisible && typeof column.footer === 'function' && (
286
+ <>
287
+ <ContextMenu.Item onClick={() => showFooter('count')}>
288
+ <TableFooterIcon />
289
+ Afficher le total
290
+ </ContextMenu.Item>
291
+ <ContextMenu.Divider />
292
+ </>
293
+ )}
294
+ {showTotalButton && typeof column.footer === 'object' && (
295
+ <>
296
+ <ContextMenu.ParentItem>
297
+ <TableFooterIcon />
298
+ Afficher le total
299
+ <ContextMenu.SubMenu>
300
+ {Object.keys(column.footer).map((key) => {
301
+ const TotalIcon =
302
+ footerFunctionsIcons[
303
+ key as DataGridFooterPredefinedFunction
304
+ ] ?? TableFooterIcon;
305
+ return (
306
+ <ContextMenu.Item
307
+ key={key}
308
+ onClick={() => showFooter(key)}
309
+ >
310
+ <TotalIcon />
311
+ {key in footerFunctionsTexts
312
+ ? footerFunctionsTexts[
313
+ key as DataGridFooterPredefinedFunction
314
+ ]
315
+ : key}
316
+ </ContextMenu.Item>
317
+ );
318
+ })}
319
+ <ContextMenu.Divider />
320
+ <ContextMenu.Item
321
+ onClick={hideFooter}
322
+ disabled={!isFooterVisible}
323
+ >
324
+ <TableFooterSlashIcon />
325
+ Masquer le total
326
+ </ContextMenu.Item>
327
+ </ContextMenu.SubMenu>
328
+ </ContextMenu.ParentItem>
329
+ <ContextMenu.Divider />
330
+ </>
331
+ )}
332
+ </>
333
+ )}
334
+ <ContextMenu.Item onClick={openModal}>
335
+ <FilterIcon />
336
+ Filtrer ...
337
+ </ContextMenu.Item>
338
+ <ContextMenu.Item
339
+ $color="danger"
340
+ onClick={clearFilter}
341
+ disabled={!hasFilters}
342
+ >
343
+ <FilterSlashIcon />
344
+ Supprimer le filtre
345
+ </ContextMenu.Item>
346
+ <ContextMenu.Divider />
347
+ <styles.InputContainer>
348
+ <MagnifierIcon />
349
+ <Input
350
+ ref={textFilterInputRef}
351
+ type="text"
352
+ name="search"
353
+ id="search"
354
+ placeholder="Rechercher ..."
355
+ value={textFilter}
356
+ onChange={(e) => setTextFilter(e.target.value)}
357
+ />
358
+ </styles.InputContainer>
359
+ <styles.CheckboxesContainer>
360
+ {checkboxesComponent}
361
+ </styles.CheckboxesContainer>
362
+ </>
363
+ );
364
+
365
+ if (!contextMenu) {
366
+ return <MenuContainer>{content}</MenuContainer>;
367
+ }
368
+
369
+ return <ContextMenu>{content}</ContextMenu>;
370
+ };