@addev-be/ui 0.1.20 → 0.1.24

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 (25) hide show
  1. package/package.json +1 -1
  2. package/src/components/data/AdvancedRequestDataGrid/helpers/advancedRequests.ts +102 -0
  3. package/src/components/data/AdvancedRequestDataGrid/helpers/columns.tsx +223 -0
  4. package/src/components/data/AdvancedRequestDataGrid/helpers/filters.ts +19 -0
  5. package/src/components/data/AdvancedRequestDataGrid/helpers/index.ts +3 -0
  6. package/src/components/data/{DataGrid/AdvancedRequestDataGrid.tsx → AdvancedRequestDataGrid/index.tsx} +47 -38
  7. package/src/components/data/AdvancedRequestDataGrid/types.ts +44 -0
  8. package/src/components/data/DataGrid/DataGridCell.tsx +3 -6
  9. package/src/components/data/DataGrid/DataGridFilterMenu/index.tsx +2 -2
  10. package/src/components/data/DataGrid/DataGridFooter.tsx +4 -4
  11. package/src/components/data/DataGrid/DataGridHeader.tsx +11 -14
  12. package/src/components/data/DataGrid/VirtualScroller.tsx +2 -7
  13. package/src/components/data/DataGrid/helpers/columns.tsx +33 -94
  14. package/src/components/data/DataGrid/helpers/filters.ts +16 -28
  15. package/src/components/data/DataGrid/helpers/index.ts +1 -2
  16. package/src/components/data/DataGrid/hooks/index.ts +1 -1
  17. package/src/components/data/DataGrid/hooks/useDataGrid.tsx +40 -4
  18. package/src/components/data/DataGrid/index.tsx +15 -27
  19. package/src/components/data/DataGrid/styles.ts +19 -4
  20. package/src/components/data/DataGrid/types.ts +68 -65
  21. package/src/components/data/index.ts +3 -2
  22. package/src/components/forms/IconButton.tsx +0 -1
  23. package/src/components/forms/IndeterminateCheckbox.tsx +1 -1
  24. package/src/services/advancedRequests.ts +1 -0
  25. package/src/components/data/DataGrid/helpers/advancedRequests.tsx +0 -61
@@ -1,12 +1,11 @@
1
1
  import * as styles from './styles';
2
2
 
3
- import { useCallback, useEffect } from 'react';
4
-
5
3
  import { DataGridCell } from './DataGridCell';
6
4
  import { DataGridFooter } from './DataGridFooter';
7
5
  import { DataGridHeader } from './DataGridHeader';
8
6
  import { DataGridProps } from './types';
9
7
  import { VirtualScroller } from './VirtualScroller';
8
+ import { useCallback } from 'react';
10
9
  import { useDataGrid } from './hooks';
11
10
 
12
11
  /* eslint-disable @typescript-eslint/no-explicit-any */
@@ -16,40 +15,36 @@ export const DataGrid = <R,>(props: DataGridProps<R>) => {
16
15
  const {
17
16
  className,
18
17
  // onRowDoubleClick,
19
- onSelectionChange,
20
18
  onVisibleRowsChange,
21
- rowKey,
22
19
  } = props;
23
20
  const [contextProps, DataGridContext] = useDataGrid(props);
24
21
  const {
25
- selectedRows,
26
- setSelectedRows,
22
+ selectedKeys,
23
+ setSelectedKeys,
27
24
  columns,
28
25
  visibleColumns,
29
26
  rowHeight = 32,
30
27
  headerRowHeight = 40,
31
28
  scrollableRef,
32
29
  onScroll,
30
+ rowKeyGetter,
33
31
  } = contextProps;
34
32
 
35
33
  const hasFooter = Object.values(columns).some((col) => col.footer);
36
34
 
37
35
  const setRowSelection = useCallback(
38
36
  (row: R, selected: boolean) => {
37
+ const key = rowKeyGetter(row);
39
38
  if (selected) {
40
- if (!selectedRows.includes(row))
41
- setSelectedRows([...selectedRows, row]);
39
+ if (!selectedKeys.includes(key))
40
+ setSelectedKeys([...selectedKeys, key]);
42
41
  } else {
43
- setSelectedRows(selectedRows.filter((p) => p !== row));
42
+ setSelectedKeys(selectedKeys.filter((p) => p !== key));
44
43
  }
45
44
  },
46
- [selectedRows, setSelectedRows]
45
+ [rowKeyGetter, selectedKeys, setSelectedKeys]
47
46
  );
48
47
 
49
- useEffect(() => {
50
- onSelectionChange?.(selectedRows);
51
- }, [onSelectionChange, selectedRows]);
52
-
53
48
  const rowTemplate = useCallback(
54
49
  (row: R, rowIndex: number) => {
55
50
  const { className, style } = props.rowClassNameGetter?.(row) ?? {
@@ -61,9 +56,7 @@ export const DataGrid = <R,>(props: DataGridProps<R>) => {
61
56
  <styles.DataGridRow key={`loading-row-${rowIndex}`}>
62
57
  {!!props.selectable && (
63
58
  <styles.LoadingCell className="animate-pulse">
64
- <div
65
- // className="bg-gray-200 rounded-full dark:bg-gray-700 w-full h-full"
66
- />
59
+ <div />
67
60
  </styles.LoadingCell>
68
61
  )}
69
62
  {visibleColumns.map((_, index) => (
@@ -71,26 +64,21 @@ export const DataGrid = <R,>(props: DataGridProps<R>) => {
71
64
  className="animate-pulse"
72
65
  key={`loading-${rowIndex}-${index}`}
73
66
  >
74
- <div
75
- // className="bg-gray-200 rounded-full dark:bg-gray-700 w-full h-full"
76
- />
67
+ <div />
77
68
  </styles.LoadingCell>
78
69
  ))}
79
70
  </styles.DataGridRow>
80
71
  );
81
72
  }
82
- const key = String(
83
- typeof rowKey === 'function' ? rowKey(row) : row[rowKey]
84
- );
73
+ const key = rowKeyGetter(row);
85
74
  return (
86
75
  <styles.DataGridRow key={key}>
87
76
  {!!props.selectable && (
88
77
  <styles.SelectionCell key="__select_checkbox__">
89
78
  <input
90
79
  type="checkbox"
91
- // className="h-4 w-4 rounded border-gray-300 text-green-600 focus:ring-green-600"
92
80
  value={key as string}
93
- checked={selectedRows.includes(row)}
81
+ checked={selectedKeys.includes(key)}
94
82
  onChange={(e) => setRowSelection(row, e.target.checked)}
95
83
  />
96
84
  </styles.SelectionCell>
@@ -114,8 +102,8 @@ export const DataGrid = <R,>(props: DataGridProps<R>) => {
114
102
  [
115
103
  DataGridContext,
116
104
  props,
117
- rowKey,
118
- selectedRows,
105
+ rowKeyGetter,
106
+ selectedKeys,
119
107
  setRowSelection,
120
108
  visibleColumns,
121
109
  ]
@@ -204,6 +204,7 @@ export const DataGridHeaderRow = styled.div.attrs<{
204
204
  z-index: 10;
205
205
  position: sticky;
206
206
  top: ${TOOLBAR_HEIGHT}px;
207
+ align-items: center;
207
208
 
208
209
  ${({ $headerColor }) =>
209
210
  $headerColor
@@ -225,15 +226,29 @@ DataGridRow.displayName = 'DataGridRow';
225
226
 
226
227
  export const LoadingCell = styled(DataGridCell)`
227
228
  padding: var(--space-2);
229
+ box-sizing: border-box;
230
+
231
+ &.animate-pulse > div {
232
+ background-color: var(--color-neutral-200);
233
+ border-radius: var(--rounded-full);
234
+ width: 100%;
235
+ height: 100%;
236
+ }
228
237
  `;
229
238
  LoadingCell.displayName = 'LoadingCell';
230
239
 
231
- export const SelectionCell = styled.div`
240
+ export const SelectionCell = styled(DataGridCell)`
232
241
  /* inline-flex items-center justify-center w-12 select-none text-center whitespace-nowrap */
242
+ display: flex;
243
+ align-items: center;
244
+ justify-content: center;
245
+ width: var(--space-6);
246
+ padding: 0 var(--space-1);
247
+
233
248
  & > input[type='checkbox'] {
234
- height: 1rem;
235
- width: 1rem;
236
- border-radius: 0.25rem;
249
+ height: var(--space-6);
250
+ width: var(--space-6);
251
+ border-radius: var(--rounded-sm);
237
252
  border: 1px solid var(--color-neutral-300);
238
253
  color: var(--color-sky-600);
239
254
  }
@@ -15,25 +15,25 @@ import { FieldDTO } from '../../../services/advancedRequests';
15
15
  import { SettingsContextProps } from '../../../providers/SettingsProvider';
16
16
  import { ThemeColor } from '../../../providers/ThemeProvider/types';
17
17
 
18
- export type DataGridColumn<
19
- R,
20
- T extends DataGridFilterType | undefined = DataGridFilterType
21
- > = {
18
+ export type MysqlJsonObject = Record<string, string | number | null>;
19
+
20
+ export type DataGridColumn<R> = {
22
21
  bodyClassName?: string;
23
22
  className?: string;
24
23
  editable?: boolean;
25
24
  excelFormatter?: (value: any) => string;
26
25
  excelValue?: (value: any) => string;
27
26
  field?: FieldDTO;
28
- filter?: T extends undefined ? never : AnyDataGridFilter<R>;
27
+ filterField?: FieldDTO;
28
+ filter?: DataGridFilter;
29
29
  footer?: (allRows: R[], filteredRows: R[], selectedRows: R[]) => ReactNode;
30
30
  footerClassName?: string;
31
- getter?: (row: R) => string | number;
31
+ getter?: (row: R) => string | number | MysqlJsonObject;
32
32
  headerClassName?: string;
33
33
  name: string;
34
34
  order?: number;
35
35
  propertyName?: keyof R;
36
- render?: (column: DataGridColumn<R, T>, row: R) => ReactNode | string;
36
+ render?: (row: R, column: DataGridColumn<R>) => ReactNode | string;
37
37
  resizable?: boolean;
38
38
  sortGetter?: (row: R) => string | number;
39
39
  type?: 'text' | 'number' | 'date';
@@ -41,14 +41,11 @@ export type DataGridColumn<
41
41
  settingsContext?: Context<SettingsContextProps>;
42
42
  };
43
43
 
44
- export type DataGridColumns<R> = Record<
45
- string,
46
- DataGridColumn<R, DataGridFilterType | undefined>
47
- >;
44
+ export type DataGridColumns<R> = Record<string, DataGridColumn<R>>;
48
45
 
49
- export type DataGridFilters<R> = Record<
46
+ export type DataGridFilters = Record<
50
47
  string,
51
- DataGridFilter<R, DataGridFilterType>
48
+ DataGridFilter<DataGridFilterType>
52
49
  >;
53
50
 
54
51
  export type DataGridProps<R> = {
@@ -61,7 +58,7 @@ export type DataGridProps<R> = {
61
58
  editable?: boolean;
62
59
  onRowDoubleClick?: (row: R, e: MouseEvent) => void;
63
60
  onSelectionChange?: (selectedRows: R[]) => void;
64
- onFiltersChanged?: (filters: DataGridFilters<R>) => void;
61
+ onFiltersChanged?: (filters: DataGridFilters) => void;
65
62
  onSortsChanged?: (sorts: Record<string, DataGridSort>) => void;
66
63
  onVisibleRowsChange?: (startIndex: number, length: number) => void;
67
64
  onCellEdited?: (row: R, columnKey: string, value: any) => void;
@@ -75,7 +72,7 @@ export type DataGridProps<R> = {
75
72
  sort?: boolean;
76
73
  filterValuesLoader?: (
77
74
  columnKey: string
78
- ) => Promise<(string | number | null)[]>;
75
+ ) => Promise<(string | number | null | MysqlJsonObject)[]>;
79
76
  // copyTableHandler?: (
80
77
  // includeHeaders?: boolean,
81
78
  // includeFooters?: boolean
@@ -90,11 +87,12 @@ export type DataGridContextProps<R> = DataGridProps<R> & {
90
87
  setEditingCell: Dispatch<SetStateAction<[number, number]>>;
91
88
  sortedRows: R[];
92
89
  selectedRows: R[];
93
- setSelectedRows: (selection: R[]) => void;
90
+ selectedKeys: string[];
91
+ setSelectedKeys: (selection: string[]) => void;
94
92
  sorts?: Record<string, DataGridSort>;
95
93
  setSorts: (sorts: Record<string, DataGridSort>) => void;
96
- filters?: DataGridFilters<R>;
97
- setFilters: Dispatch<SetStateAction<DataGridFilters<R>>>;
94
+ filters?: DataGridFilters;
95
+ setFilters: Dispatch<SetStateAction<DataGridFilters>>;
98
96
  visibleColumns: DataGridColumnKeyValuePair<R>[];
99
97
  copyTable: (
100
98
  includeHeaders?: boolean,
@@ -109,6 +107,8 @@ export type DataGridContextProps<R> = DataGridProps<R> & {
109
107
  onScroll: (e: React.UIEvent<HTMLDivElement>) => void;
110
108
  index: number;
111
109
  length: number;
110
+ rowKeyGetter: (row: R) => string;
111
+ gridTemplateColumns: string;
112
112
  };
113
113
 
114
114
  export type DataGridContext<R> = Context<DataGridContextProps<R>>;
@@ -138,7 +138,7 @@ export type DataGridSettingsByName = t.TypeOf<
138
138
  >;
139
139
  export type DataGridSettingsTuple = [string, DataGridSetting];
140
140
  export type DataGridSettingsArray = DataGridSettingsTuple[];
141
- export type DataGridColumnKeyValuePair<R> = [string, DataGridColumn<R, any>];
141
+ export type DataGridColumnKeyValuePair<R> = [string, DataGridColumn<R>];
142
142
 
143
143
  export type DataGridCellProps<R> = {
144
144
  row: R;
@@ -162,62 +162,65 @@ export type DataGridHeaderCellProps<R> = {
162
162
 
163
163
  export type DataGridSort = 'asc' | 'desc';
164
164
 
165
- export type DataGridFilterType = 'text' | 'number';
166
- export type DataGridFilterDataType<T extends DataGridFilterType> =
167
- T extends 'text' ? string : number;
168
-
169
165
  export type DataGridFilterPredicate<T> = (valueToVerify: T) => boolean;
170
166
  export type DataGridFilterPredicateBuilder<T> = (
171
- row: any,
172
167
  ...filterValues: T[]
173
168
  ) => DataGridFilterPredicate<T>;
174
169
 
175
- export type DataGridFilterGetter<R, T extends DataGridFilterType> = (
176
- row: R
177
- ) => DataGridFilterDataType<T> | null;
178
- export type DataGridFilterFormatter = (
179
- value: string | number | null
180
- ) => string | null;
170
+ export type DataGridFilterOperators<K extends string, T> = {
171
+ [key in K]: DataGridFilterPredicateBuilder<T>;
172
+ };
181
173
 
182
174
  export type DataGridFilterPredicates = {
183
- text: {
184
- contains: DataGridFilterPredicateBuilder<string>;
185
- notContains: DataGridFilterPredicateBuilder<string>;
186
- equals: DataGridFilterPredicateBuilder<string>;
187
- notEquals: DataGridFilterPredicateBuilder<string>;
188
- startsWith: DataGridFilterPredicateBuilder<string>;
189
- endsWith: DataGridFilterPredicateBuilder<string>;
190
- inArray: DataGridFilterPredicateBuilder<string>;
191
- };
192
- number: {
193
- equals: DataGridFilterPredicateBuilder<number>;
194
- notEquals: DataGridFilterPredicateBuilder<number>;
195
- lessThan: DataGridFilterPredicateBuilder<number>;
196
- lessThanOrEqual: DataGridFilterPredicateBuilder<number>;
197
- greaterThan: DataGridFilterPredicateBuilder<number>;
198
- greaterThanOrEqual: DataGridFilterPredicateBuilder<number>;
199
- inRange: DataGridFilterPredicateBuilder<number>;
200
- inArray: DataGridFilterPredicateBuilder<number>;
201
- };
175
+ text: DataGridFilterOperators<
176
+ | 'contains'
177
+ | 'notContains'
178
+ | 'equals'
179
+ | 'notEquals'
180
+ | 'startsWith'
181
+ | 'endsWith'
182
+ | 'inArray',
183
+ string
184
+ >;
185
+ number: DataGridFilterOperators<
186
+ | 'equals'
187
+ | 'notEquals'
188
+ | 'lessThan'
189
+ | 'lessThanOrEqual'
190
+ | 'greaterThan'
191
+ | 'greaterThanOrEqual'
192
+ | 'inRange'
193
+ | 'inArray',
194
+ number
195
+ >;
202
196
  };
203
197
 
204
- export type DataGridFilterOperator<T extends DataGridFilterType> =
205
- keyof DataGridFilterPredicates[T];
206
-
207
- export type DataGridFilter<
208
- R,
209
- T extends DataGridFilterType = DataGridFilterType
210
- > = {
211
- type: T;
212
- operator: keyof DataGridFilterPredicates[T];
213
- getter: DataGridFilterGetter<R, T>;
214
- formatter?: DataGridFilterFormatter;
215
- values: (DataGridFilterDataType<T> | null)[];
216
- };
198
+ export type DataGridFilterType = keyof DataGridFilterPredicates;
199
+ export type DataGridFilterDataType<T extends DataGridFilterType> =
200
+ DataGridFilterPredicates[T] extends DataGridFilterOperators<string, infer U>
201
+ ? U
202
+ : never;
217
203
 
218
- export type AnyDataGridFilter<R> =
219
- | DataGridFilter<R, 'text'>
220
- | DataGridFilter<R, 'number'>;
204
+ export type DataGridFilterGetter<T extends DataGridFilterType> = (
205
+ value: any
206
+ ) => DataGridFilterDataType<T> | null;
207
+ export type DataGridFilterFormatter = (value: any) => string | null;
208
+
209
+ export type DataGridFilterOperator<T extends DataGridFilterType> =
210
+ DataGridFilterPredicates[T] extends DataGridFilterOperators<infer K, any>
211
+ ? K
212
+ : never;
213
+
214
+ export type DataGridFilter<T extends string = DataGridFilterType> =
215
+ T extends DataGridFilterType
216
+ ? {
217
+ type: T;
218
+ operator: DataGridFilterOperator<T>;
219
+ getter: DataGridFilterGetter<T>;
220
+ formatter?: DataGridFilterFormatter;
221
+ values: (DataGridFilterDataType<T> | null)[];
222
+ }
223
+ : never;
221
224
 
222
225
  export type DataGridFilterGroup<R> = {
223
226
  name: string;
@@ -1,3 +1,4 @@
1
1
  export * from './DataGrid';
2
- export * from './DataGrid/AdvancedRequestDataGrid';
3
- export * from './DataGrid/helpers/columns';
2
+ export * from './DataGrid/helpers';
3
+ export * from './AdvancedRequestDataGrid';
4
+ export * from './AdvancedRequestDataGrid/helpers';
@@ -13,7 +13,6 @@ const styles = {
13
13
  IconButton: styled(Button).attrs({
14
14
  className: 'IconButton',
15
15
  })<Omit<IconButtonProps, 'icon'>>`
16
- border-radius: 100%;
17
16
  &.small {
18
17
  padding: var(--space-1);
19
18
  height: var(--space-6);
@@ -38,7 +38,7 @@ export const IndeterminateCheckbox: FC<IndeterminateCheckboxProps> = ({
38
38
  ' '
39
39
  )}
40
40
  ref={checkbox}
41
- checked={checked}
41
+ checked={!!checked}
42
42
  onChange={onChange}
43
43
  {...props}
44
44
  />
@@ -35,6 +35,7 @@ export type ConditionDTO = {
35
35
  | 'greaterThan'
36
36
  | 'like'
37
37
  | 'contains'
38
+ | 'notContains'
38
39
  | 'startsWith'
39
40
  | 'endsWith'
40
41
  | 'notLike'
@@ -1,61 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
-
3
- import {
4
- AdvancedRequestDTO,
5
- ConditionDTO,
6
- OrderByDTO,
7
- } from '../../../../services/advancedRequests';
8
-
9
- import { DataGridColumns } from '../types';
10
-
11
- export const getAdvancedRequestDto = <R,>({
12
- type,
13
- columns,
14
- conditions = [],
15
- orderBy = [],
16
- start = 0,
17
- length = 100,
18
- getTotal = false,
19
- addIdColumn = true,
20
- }: {
21
- type: string;
22
- columns: DataGridColumns<R>;
23
- conditions?: ConditionDTO[];
24
- orderBy?: OrderByDTO[];
25
- start?: number;
26
- length?: number;
27
- getTotal?: boolean;
28
- addIdColumn?: boolean;
29
- }): AdvancedRequestDTO => ({
30
- fields: [
31
- ...(Object.keys(columns).includes('Id') || addIdColumn === false
32
- ? []
33
- : [{ fieldName: 'Id' }]),
34
- ...Object.keys(columns).map((key) =>
35
- columns[key].field
36
- ? {
37
- ...columns[key].field,
38
- fieldName: columns[key].field?.fieldName ?? key,
39
- fieldAlias: key,
40
- }
41
- : {
42
- fieldName: key,
43
- fieldAlias: key,
44
- }
45
- ),
46
- ],
47
- conditions: [
48
- ...conditions,
49
- {
50
- field: {
51
- fieldName: 'DeletedAt',
52
- },
53
- operator: 'isNull' as const,
54
- },
55
- ],
56
- orderBy,
57
- type,
58
- start,
59
- length,
60
- getTotal,
61
- });