@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.
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@addev-be/ui",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "watch": "tsc -b --watch",
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 './types';
12
- import { debounce, join } from 'lodash';
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 { useElementSize } from '../../../hooks';
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
- type="checkbox"
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: `${values.length * rowHeight}px` }}>
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 '../FilterValuesScroller';
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
- // date: 'Trier du plus ancien au plus récent',
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
- // date: 'Trier du plus récent au plus ancien',
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
- <input
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
- const newValues = [...values];
110
- newValues[0] =
111
- type === 'number'
112
- ? Number(e.target.value)
113
- : (String(e.target.value) as any);
114
- onFilterChanged({
115
- ...filter,
116
- values: newValues,
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
- ...textFilter(key),
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-MM`);
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
- filter: { ...textFilter(key), getter: (value) => value[key] ?? '' },
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: () => '#0.00',
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: () => '#0.00',
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
  &nbsp;
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: {
@@ -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');