@dashadmin/dash-components 1.3.24 → 1.3.26

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 (111) hide show
  1. package/dist/components/AuditLog/AuditLog.js +345 -1
  2. package/dist/components/AuditLog/index.js +4 -1
  3. package/dist/components/AutoCompleteArrayInput/AutoCompleteCheckBoxInput.js +630 -3
  4. package/dist/components/AutoCompleteArrayInput/AutocompleteCheckBoxArrayInput.js +53 -1
  5. package/dist/components/AutoCompleteArrayInputAutoSearch/AutoCompleteCheckBoxInput.js +647 -3
  6. package/dist/components/AutoCompleteArrayInputAutoSearch/AutocompleteCheckBoxArrayInput.js +53 -1
  7. package/dist/components/Json/Json.js +235 -1
  8. package/dist/components/JsonColorSelector/JsonColorSelector.js +1172 -1
  9. package/dist/components/JsonColorSelector/JsonColorSelectorEnhanced.js +863 -2
  10. package/dist/components/JsonColorSelector/JsonCssVarValues.js +738 -1
  11. package/dist/components/JsonColorSelector/components/ColorEditDialog.js +426 -1
  12. package/dist/components/JsonColorSelector/components/ColorPaletteItem.js +75 -1
  13. package/dist/components/JsonColorSelector/components/ImageColorExtractor.js +283 -1
  14. package/dist/components/JsonColorSelector/helpers/functions.js +101 -1
  15. package/dist/components/JsonColorSelector/useAsyncColorThief.js +105 -1
  16. package/dist/components/ListActive/ListActive.js +126 -1
  17. package/dist/components/ListActive/ListBoolean.js +124 -1
  18. package/dist/components/NotificationPreferences/NotificationPreferences.js +317 -1
  19. package/dist/components/NotificationPreferences/index.js +7 -1
  20. package/dist/components/SearchableSelects/RASearchableSelect.js +236 -1
  21. package/dist/components/SearchableSelects/RASearchableSelectCheckboxes.js +479 -1
  22. package/dist/components/SearchableSelects/RASearchableSelectChips.js +465 -1
  23. package/dist/components/SearchableSelects/RASearchableSelectChipsRecordContext.js +295 -1
  24. package/dist/components/SearchableSelects/SearchableSelect.js +202 -1
  25. package/dist/components/SearchableSelects/SearchableSelectCheckboxes.js +290 -1
  26. package/dist/components/SortableDataGrid/SortableDataGrid.js +72 -1
  27. package/dist/components/SortableDataGrid/SortableDataGridBody.js +167 -1
  28. package/dist/components/SortableDataGrid/SortableDataGridHeader.js +109 -1
  29. package/dist/components/SortableDataGrid/SortableDataGridRow.js +283 -1
  30. package/dist/components/Upload/SingleImageUploader.js +40 -1
  31. package/dist/components/custom/PackageCopyMethod.js +78 -1
  32. package/dist/components/custom/PackageRadioButtonGroup.js +45 -1
  33. package/dist/components/dialog/Basic.js +8 -1
  34. package/dist/components/dialog/Correct.js +14 -1
  35. package/dist/components/dialog/Error.js +14 -1
  36. package/dist/components/dialog/Info.js +14 -1
  37. package/dist/components/dialog/InfoV2.js +21 -1
  38. package/dist/components/dialog/NotFound.js +14 -1
  39. package/dist/components/dialog/QuickSearch.js +117 -1
  40. package/dist/components/notifications/NotificationsCenter.js +597 -1
  41. package/dist/components/notifications/index.js +24 -1
  42. package/dist/components/tables/PaginationComponent.js +36 -1
  43. package/dist/components/theme/AppLoadingFallback.js +38 -2
  44. package/dist/components/theme/ErrorBoundary.js +52 -1
  45. package/dist/components/theme/InitialLoader.js +13 -1
  46. package/dist/components/theme/NotFound.js +136 -1
  47. package/dist/components/theme/NotResults.js +38 -1
  48. package/dist/hooks/useDraggable.js +6 -1
  49. package/dist/hooks/useNotifications.js +8 -1
  50. package/dist/hooks/useQuickSearch.js +26 -1
  51. package/dist/index.js +66 -5567
  52. package/dist/utils/setNativeValue.js +17 -1
  53. package/package.json +149 -132
  54. package/src/components/AuditLog/AuditLog.tsx +476 -0
  55. package/src/components/AuditLog/index.ts +2 -0
  56. package/src/components/AutoCompleteArrayInput/AutoCompleteCheckBoxInput.tsx +917 -0
  57. package/src/components/AutoCompleteArrayInput/AutocompleteCheckBoxArrayInput.tsx +39 -0
  58. package/src/components/AutoCompleteArrayInputAutoSearch/AutoCompleteCheckBoxInput.tsx +916 -0
  59. package/src/components/AutoCompleteArrayInputAutoSearch/AutocompleteCheckBoxArrayInput.tsx +44 -0
  60. package/src/components/Json/Json.tsx +312 -0
  61. package/src/components/JsonColorSelector/JsonColorSelector.tsx +1435 -0
  62. package/src/components/JsonColorSelector/JsonColorSelectorEnhanced.tsx +1029 -0
  63. package/src/components/JsonColorSelector/JsonCssVarValues.tsx +863 -0
  64. package/src/components/JsonColorSelector/components/ColorEditDialog.tsx +491 -0
  65. package/src/components/JsonColorSelector/components/ColorPaletteItem.tsx +80 -0
  66. package/src/components/JsonColorSelector/components/ImageColorExtractor.tsx +328 -0
  67. package/src/components/JsonColorSelector/helpers/functions.tsx +123 -0
  68. package/src/components/JsonColorSelector/interfaces/interfaces.tsx +22 -0
  69. package/src/components/JsonColorSelector/useAsyncColorThief.tsx +97 -0
  70. package/src/components/ListActive/ListActive.tsx +106 -0
  71. package/src/components/ListActive/ListBoolean.tsx +96 -0
  72. package/src/components/NotificationPreferences/NotificationPreferences.tsx +463 -0
  73. package/src/components/NotificationPreferences/index.tsx +2 -0
  74. package/src/components/SearchableSelects/RASearchableSelect.tsx +300 -0
  75. package/src/components/SearchableSelects/RASearchableSelectCheckboxes.tsx +604 -0
  76. package/src/components/SearchableSelects/RASearchableSelectChips.tsx +558 -0
  77. package/src/components/SearchableSelects/RASearchableSelectChipsRecordContext.tsx +362 -0
  78. package/src/components/SearchableSelects/SearchableSelect.tsx +321 -0
  79. package/src/components/SearchableSelects/SearchableSelectCheckboxes.tsx +355 -0
  80. package/src/components/SortableDataGrid/SortableDataGrid.tsx +56 -0
  81. package/src/components/SortableDataGrid/SortableDataGridBody.tsx +175 -0
  82. package/src/components/SortableDataGrid/SortableDataGridHeader.tsx +171 -0
  83. package/src/components/SortableDataGrid/SortableDataGridRow.tsx +247 -0
  84. package/src/components/Upload/SingleImageUploader.tsx +55 -0
  85. package/src/components/custom/PackageCopyMethod.tsx +109 -0
  86. package/src/components/custom/PackageRadioButtonGroup.tsx +47 -0
  87. package/src/components/dialog/Basic.tsx +11 -0
  88. package/src/components/dialog/Correct.tsx +16 -0
  89. package/src/components/dialog/Error.tsx +15 -0
  90. package/src/components/dialog/Info.tsx +15 -0
  91. package/src/components/dialog/InfoV2.tsx +35 -0
  92. package/src/components/dialog/NotFound.tsx +18 -0
  93. package/src/components/dialog/QuickSearch.tsx +115 -0
  94. package/src/components/notifications/NotificationsCenter.tsx +792 -0
  95. package/src/components/notifications/index.ts +42 -0
  96. package/src/components/tables/PaginationComponent.tsx +17 -0
  97. package/src/components/theme/AppLoadingFallback.tsx +42 -0
  98. package/src/components/theme/ErrorBoundary.tsx +57 -0
  99. package/src/components/theme/InitialLoader.tsx +16 -0
  100. package/src/components/theme/NotFound.tsx +124 -0
  101. package/src/components/theme/NotResults.tsx +54 -0
  102. package/src/hooks/useDraggable.ts +11 -0
  103. package/src/hooks/useNotifications.ts +14 -0
  104. package/src/hooks/useQuickSearch.tsx +29 -0
  105. package/src/index.tsx +77 -0
  106. package/src/utils/setNativeValue.tsx +23 -0
  107. package/dist/color-thief-CTwGFhOB.js +0 -272
  108. /package/{dist → src}/components/AutoCompleteArrayInputAutoSearch/AutocompleteCheckBoxArrayAutoSearch.tsx.wip +0 -0
  109. /package/{dist → src}/components/JsonColorSelector/JsonColorSelector.tsx.bkup +0 -0
  110. /package/{dist → src}/components/SortableDataGrid/README.md +0 -0
  111. /package/{dist → src}/styles/index.less +0 -0
@@ -0,0 +1,355 @@
1
+ /**
2
+ * React Auto Admin - SearchableSelect
3
+ *
4
+ * @author Franisco Aranda <francisco.aranda@dash.cl> <faranda@gmail.com>
5
+ */
6
+
7
+ import {
8
+ Autocomplete,
9
+ AutocompleteProps,
10
+ Box,
11
+ Checkbox,
12
+ CircularProgress,
13
+ TextField,
14
+ } from '@mui/material';
15
+ import React, { JSX, useEffect, useState } from 'react';
16
+ import { isArray } from 'lodash';
17
+ import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank';
18
+ import CheckBoxIcon from '@mui/icons-material/CheckBox';
19
+ import { useAxios } from 'dash-axios-hook';
20
+
21
+ export interface ISearchableSelect<
22
+ T,
23
+ //Multiple extends boolean | undefined = false,
24
+ //DisableClearable extends boolean | undefined = false,
25
+ //FreeSolo extends boolean | undefined = false,
26
+ > extends Omit<
27
+ AutocompleteProps<T | string, boolean, boolean, boolean>,
28
+ | 'renderInput'
29
+ | 'options'
30
+ | 'isOptionEqualToValue'
31
+ | 'getOptionLabel'
32
+ | 'renderOption'
33
+ > {
34
+ /** Options are ingored because they are calculated within this component */
35
+ /** renderInput is ignored because is implemented privately within this component */
36
+
37
+ name: string;
38
+ /** url path to the resource, a getList or getForSelect e.g: 'system/user' */
39
+ resource: string;
40
+ /** label for the select */
41
+ selectLabel: string;
42
+ /** Optional function to parse the item and return a string or JSX.Element to show in the selector list*/
43
+ renderText?: (object: any) => string | JSX.Element;
44
+ /** @deprecated Optional function will transform the item at the moment of field.onChange */
45
+ transformData?: (val: any) => any;
46
+ /** Optional defaultValue, or defaultValues array */
47
+ defaultValues?: T | T[];
48
+
49
+ /** @deprecated pagination, must be sent on filters */
50
+ pagination?: boolean,
51
+ /** Min character input to perform search */
52
+ minSearch?: number;
53
+ /** @deprecated searchResults, must be sent on filters as perPage */
54
+ searchResults?: number;
55
+ /** Search after x ms */
56
+ timerSearch?: number;
57
+ /** isEmpty - TODO: this flow is not tested. */
58
+ isEmpty?: boolean;
59
+ /** filter - optional parameters for the axios query */
60
+ filter?: { [x: string]: any };
61
+ /** name of the query parameter, usually just 'q' or 'search' */
62
+ queryFilter?: string;
63
+ /**
64
+ * The default function will compare the raw values equality
65
+ * the edge case is when a transformData is implemented, then the isOptionEqualToValue will have to compare to the transformation output.
66
+ * e.g: isOptionEqualToValue={(option, value) => value === option.id }
67
+ transformData={(data) => data?.id || null}
68
+ */
69
+ isOptionEqualToValue?: (option: T, value: T) => boolean;
70
+ /**
71
+ * if not specified it will render the raw value for options
72
+ * if the response is not just a string or number array, you will have to specify which attribute from the option object you want to render
73
+ */
74
+ renderAttribute?: string;
75
+ /** elementKeyID, Advanced usage, by default id, specify the attribute from the option object representing the key or id */
76
+ elementKeyId?: string;
77
+ /** onChange */
78
+ //onChange?: (value: T | T[]) => void;
79
+ /* renderInputTextFieldProps - Partial<TextFieldProps> */
80
+ renderInputTextFieldProps?: any; // It should be: Partial<TextFieldProps>
81
+ checkboxes?: boolean;
82
+ /**
83
+ * if its not possible to pass the default values according to the option interface, then set selectedIds, only works when multiple.
84
+ * once fetched the options and parsedOptions are available.
85
+ */
86
+ selectedIds?: number[];
87
+ useDefaultSearch?: boolean;
88
+ }
89
+
90
+ const icon = <CheckBoxOutlineBlankIcon fontSize='small' />;
91
+ const checkedIcon = <CheckBoxIcon fontSize='small' />;
92
+
93
+ const SearchableSelectCheckboxes = function WrappedAutoComplete<
94
+ T,
95
+ >({ ...props }: ISearchableSelect<T>) {
96
+ const {
97
+ multiple,
98
+ freeSolo,
99
+ minSearch = 3,
100
+ timerSearch = 500,
101
+ checkboxes = false,
102
+ resource,
103
+ selectLabel,
104
+ renderText,
105
+ queryFilter = 'q',
106
+ defaultValues = null,
107
+ elementKeyId = 'id',
108
+ isEmpty = false,
109
+ filter,
110
+ isOptionEqualToValue = (option, value) => value === option,
111
+ renderAttribute = null,
112
+ name,
113
+ onChange,
114
+ renderInputTextFieldProps,
115
+ selectedIds,
116
+ useDefaultSearch = false,
117
+ ...rest
118
+ } = props;
119
+
120
+ const [open, setOpen] = useState(false);
121
+ const [parsedOptions, setParsedOptions] = useState<T[]>(null);
122
+ const [q, setQ] = useState(null);
123
+
124
+ const [resourceData, setResourceData] = useState(null);
125
+ const [isLoading, setIsLoading] = useState(false);
126
+
127
+ const [initialSelectedIds, setInitalSelectedIds] = useState(null);
128
+
129
+ const initialIncludes =
130
+ defaultValues && Array.isArray(defaultValues)
131
+ ? defaultValues.map((element: any) =>
132
+ element[elementKeyId]
133
+ ? element[elementKeyId]
134
+ : element)
135
+ : multiple && initialSelectedIds
136
+ ? initialSelectedIds
137
+ : defaultValues;
138
+
139
+
140
+ const [includes, setIncludes] = useState(initialIncludes);
141
+
142
+ const [controlledValue, setControlledValue] = useState<T | T[]>(null);
143
+ const axios = useAxios();
144
+
145
+ useEffect(() => {
146
+ setInitalSelectedIds(selectedIds);
147
+ }, []);
148
+
149
+ const updateControlledValue = (val: T | T[], origin?: string) => {
150
+ if (Array.isArray(val)) {
151
+ setControlledValue(val as T[]);
152
+ if ( origin === 'onChange') { setIncludes(val.map((v: any) => v[elementKeyId])); }
153
+ } else {
154
+ setControlledValue(val as T);
155
+ if ( origin === 'onChange') { setIncludes((val as any)[elementKeyId]); }
156
+ }
157
+ };
158
+
159
+ const search = async () => {
160
+ setIsLoading(true);
161
+
162
+ try {
163
+ const params = { [queryFilter]: q, ...filter, includes: includes };
164
+
165
+ const { data } = await axios.get(resource, {
166
+ params,
167
+ });
168
+
169
+ setResourceData(data.data);
170
+ } catch (e: any) {
171
+ console.error(e);
172
+ } finally {
173
+ setIsLoading(false);
174
+ }
175
+ };
176
+
177
+ useEffect(() => {
178
+ search();
179
+ }, []);
180
+
181
+ useEffect(() => {
182
+ if (q && q !== '' && !useDefaultSearch) {
183
+ search();
184
+ }
185
+ }, [q]);
186
+
187
+ useEffect(() => {
188
+ if (resourceData && !isLoading) {
189
+ if (parsedOptions)
190
+ setParsedOptions([
191
+ ...parsedOptions,
192
+ ...resourceData.map((ele: any) => {
193
+ return { ...ele, key: 'option' + ele.id };
194
+ }),
195
+ ]);
196
+ setParsedOptions(
197
+ resourceData.map((ele: any) => {
198
+ return { ...ele, key: 'option' + ele.id };
199
+ }),
200
+ );
201
+ }
202
+ return () => setParsedOptions([]);
203
+ }, [resourceData, isLoading]);
204
+
205
+ const [timeOutSearch, setTimeOutSearch] = useState(undefined);
206
+
207
+ const debounce = (fn: Function, delay = 500) => {
208
+ clearTimeout(timeOutSearch);
209
+ setTimeOutSearch(
210
+ setTimeout(() => {
211
+ fn();
212
+ }, delay),
213
+ );
214
+ };
215
+
216
+ const checkboxRenderOptions = (p, option, { selected }) => {
217
+ const { key, ...r } = p as any;
218
+ return (
219
+ <li key={option.key} {...r}>
220
+ <Checkbox
221
+ icon={icon}
222
+ checkedIcon={checkedIcon}
223
+ style={{ marginRight: 8 }}
224
+ checked={selected}
225
+ />
226
+
227
+ {renderAttribute && !renderText
228
+ ? option[renderAttribute]
229
+ : renderText(option)}
230
+ </li>
231
+ );
232
+ };
233
+
234
+ const boxRenderOptions = (p, option: any) => {
235
+ const { key, ...newProps } = p as any;
236
+ return (
237
+ <Box
238
+ key={option.key}
239
+ component='li'
240
+ sx={{ '& > img': { mr: 2, flexShrink: 0 } }}
241
+ {...newProps}
242
+ >
243
+ {renderAttribute && !renderText
244
+ ? option[renderAttribute]
245
+ : renderText(option)}
246
+ </Box>
247
+ );
248
+ };
249
+
250
+ const _renderOption = checkboxes ? checkboxRenderOptions : boxRenderOptions;
251
+
252
+ useEffect(() => {
253
+ if (multiple && parsedOptions && initialSelectedIds) {
254
+ const values = parsedOptions.filter((option: any) =>
255
+ initialSelectedIds.includes(option[elementKeyId]),
256
+ );
257
+ updateControlledValue(values, 'selectedIds');
258
+ }
259
+ }, [parsedOptions, initialSelectedIds, multiple]);
260
+
261
+ useEffect(() => {
262
+ if (onChange &&
263
+ controlledValue) {
264
+ onChange(null, controlledValue as T | T[], null);
265
+ }
266
+ }, [controlledValue]);
267
+ return (
268
+ <>
269
+ {isLoading && !parsedOptions ? (
270
+ <CircularProgress color='inherit' size={20} />
271
+ ) : (
272
+ <></>
273
+ )}
274
+ {parsedOptions && (
275
+ <Autocomplete
276
+ key={'autocomplete-' + name}
277
+ multiple={multiple}
278
+ freeSolo={freeSolo}
279
+ loading={isLoading && open}
280
+ {...(checkboxes && { disableCloseOnSelect: true })}
281
+ options={parsedOptions}
282
+ open={open}
283
+ onOpen={() => setOpen(true)}
284
+ onClose={() => setOpen(false)}
285
+ value={controlledValue ? controlledValue : multiple ? [] : null}
286
+
287
+
288
+ /* @ts-ignore */
289
+ isOptionEqualToValue={isOptionEqualToValue}
290
+
291
+ autoHighlight
292
+ getOptionLabel={(option: any) => {
293
+ return renderAttribute && !renderText
294
+ ? option[renderAttribute]
295
+ : (renderText ? renderText(option) : option)
296
+ }
297
+ }
298
+ renderOption={_renderOption}
299
+ onChange={(event: any, rawValue, _reason) => {
300
+ updateControlledValue(rawValue as T | T[], 'onChange');
301
+ }}
302
+ renderInput={(params) => {
303
+ return (
304
+ <TextField
305
+ key={params.id}
306
+ {...params}
307
+ label={selectLabel}
308
+ variant='outlined'
309
+ onChange={(ev) => {
310
+
311
+ if(useDefaultSearch !== true) {
312
+ const searchValue = ev.target.value;
313
+
314
+ if (
315
+ searchValue &&
316
+ searchValue !== '' &&
317
+ searchValue.length >= minSearch
318
+ ) {
319
+
320
+ debounce(() => setQ(searchValue), timerSearch);
321
+ }
322
+
323
+ }
324
+ }}
325
+ InputProps={{
326
+ ...params.InputProps,
327
+ autoComplete: 'new-password',
328
+ endAdornment: (
329
+ <>
330
+ {isLoading ? (
331
+ <CircularProgress color='inherit' size={20} />
332
+ ) : null}
333
+ {params.InputProps.endAdornment}
334
+ </>
335
+ ),
336
+ }}
337
+ {...renderInputTextFieldProps}
338
+ />
339
+ );
340
+ }}
341
+ {...rest}
342
+ />
343
+ )}
344
+ </>
345
+ );
346
+ };
347
+ export const MemoizedSearchableSelectCheckboxes = React.memo(
348
+ SearchableSelectCheckboxes,
349
+ () => {
350
+ // never refresh
351
+ return true;
352
+ },
353
+ ) as typeof SearchableSelectCheckboxes;
354
+
355
+ export default SearchableSelectCheckboxes;
@@ -0,0 +1,56 @@
1
+ import {
2
+ FC,
3
+ PropsWithChildren,
4
+ memo,
5
+ useRef,
6
+ } from 'react';
7
+
8
+ import { Datagrid } from 'react-admin';
9
+ import { DatagridProps } from 'react-admin';
10
+ import SortableDatagridBody from './SortableDataGridBody';
11
+ import { SortableDatagridHeader } from './SortableDataGridHeader';
12
+ import SortableDatagridRow from './SortableDataGridRow';
13
+ import React from 'react';
14
+
15
+ interface ISortableDatagrid extends DatagridProps, PropsWithChildren {
16
+ onOrderUpdate?: (data: any) => void;
17
+ }
18
+
19
+ const SortableDatagrid: FC<ISortableDatagrid> = (props) => {
20
+ const { children, onOrderUpdate, ...rest } = props;
21
+ const bodyRef = React.useRef(null);
22
+ //const [tableEl, setTableEl] = useState(null);
23
+
24
+ const _onOrderUpdate = (d: any[]) => {
25
+ if (onOrderUpdate) { onOrderUpdate(d); }
26
+ };
27
+
28
+ const SortableRootDatagrid = (p) => (
29
+ <Datagrid
30
+ {...p}
31
+ header={<SortableDatagridHeader />}
32
+ body={
33
+ <SortableDatagridBody
34
+ /* @ts-ignore : Expected */
35
+ onOrderUpdate={_onOrderUpdate}
36
+ ref={bodyRef}
37
+ //{...props}
38
+ row={<SortableDatagridRow />}
39
+ />
40
+ }
41
+ />
42
+ );
43
+
44
+ const SortableRootDatagridPure = memo(
45
+ SortableRootDatagrid,
46
+ () => true,
47
+ );
48
+
49
+ return (
50
+ <div id='sortable-list'>
51
+ <SortableRootDatagridPure {...rest}>{children}</SortableRootDatagridPure>
52
+ </div>
53
+ );
54
+ };
55
+
56
+ export default SortableDatagrid;
@@ -0,0 +1,175 @@
1
+ import * as React from 'react';
2
+ import { cloneElement, memo, FC, forwardRef } from 'react';
3
+ import { TableBody } from '@mui/material';
4
+
5
+ import {
6
+ DatagridBody,
7
+ DatagridBodyProps,
8
+ DatagridRow,
9
+ PureDatagridRow,
10
+ } from 'react-admin';
11
+
12
+ import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd';
13
+
14
+ export interface ISortableDatagridBodyProps extends DatagridBodyProps {
15
+ onOrderUpdate?: (data: any[]) => void;
16
+ }
17
+
18
+ const defaultChildren = <DatagridRow />;
19
+ const defaultData = [];
20
+
21
+
22
+ const SortableDatagridBody: FC<ISortableDatagridBodyProps> = forwardRef(
23
+ (
24
+ {
25
+ children,
26
+ className,
27
+ data = defaultData,
28
+ expand,
29
+ hasBulkActions = false,
30
+ hover,
31
+ onToggleItem,
32
+ resource,
33
+ row = defaultChildren,
34
+ rowClick,
35
+ rowStyle,
36
+ selectedIds,
37
+ isRowSelectable,
38
+ onOrderUpdate,
39
+ ...rest
40
+ },
41
+ _ref,
42
+ ) => {
43
+ React.useEffect(() => {
44
+ console.log('data has been updated');
45
+ }, [data]);
46
+
47
+ const [orderedData, setOrderedData] = React.useState(data);
48
+
49
+ /*const updateOrderedData = (data) => {
50
+ onOrderUpdate && onOrderUpdate(orderedData);
51
+ setOrderedData(data);
52
+ };*/
53
+
54
+ const reorder = (list, startIndex, endIndex) => {
55
+ const result = Array.from(list);
56
+ const [removed] = result.splice(startIndex, 1);
57
+ result.splice(endIndex, 0, removed);
58
+
59
+ return result;
60
+ };
61
+
62
+ const getItemStyle = (isDragging, draggableStyle) => ({
63
+ border: isDragging ? '1px dashed #ccc' : 'none',
64
+ ...draggableStyle,
65
+ });
66
+
67
+ const onDragEnd = (result) => {
68
+ if (!result.destination) {
69
+ return;
70
+ }
71
+
72
+ const movedItems = reorder(
73
+ orderedData,
74
+ result.source.index,
75
+ result.destination.index,
76
+ );
77
+ setOrderedData(movedItems);
78
+ if (onOrderUpdate) { onOrderUpdate(movedItems); }
79
+ };
80
+
81
+ return (
82
+ (<DragDropContext onDragEnd={onDragEnd}>
83
+ <Droppable droppableId='droppable'>
84
+ {(provided) => (
85
+ /* @ts-ignore Expected KnownIssue1 */
86
+ (<TableBody
87
+ ref={provided.innerRef}
88
+ className={'datagrid-body'}
89
+ {...rest}
90
+ >
91
+ {orderedData.map((record, rowIndex) => {
92
+ return (
93
+ <Draggable
94
+ key={record.id}
95
+ draggableId={'q-' + record.id}
96
+ index={rowIndex}
97
+ >
98
+ {(p, snapshot) => {
99
+ const defaultStyles = rowStyle
100
+ ? rowStyle(record, rowIndex)
101
+ : {};
102
+ return cloneElement(
103
+ row,
104
+ {
105
+ ref: p.innerRef,
106
+ ...p.draggableProps,
107
+ ...p.dragHandleProps,
108
+
109
+ /*className: clsx(DatagridClasses.row, {
110
+ [DatagridClasses.rowEven]: rowIndex % 2 === 0,
111
+ [DatagridClasses.rowOdd]: rowIndex % 2 !== 0,
112
+ }),*/
113
+ expand,
114
+ hasBulkActions: hasBulkActions && !!selectedIds,
115
+ hover,
116
+ id: record.id ?? `row${rowIndex}`,
117
+ key: record.id ?? `row${rowIndex}`,
118
+ onToggleItem,
119
+ record,
120
+ resource,
121
+ rowClick,
122
+ selectable:
123
+ !isRowSelectable || isRowSelectable(record),
124
+ selected: selectedIds?.includes(record.id),
125
+ style: {
126
+ ...defaultStyles,
127
+ ...getItemStyle(
128
+ snapshot.isDragging,
129
+ p.draggableProps.style,
130
+ ),
131
+ },
132
+ },
133
+ children,
134
+ );
135
+ }}
136
+ </Draggable>
137
+ );
138
+ })}
139
+ </TableBody>)
140
+ )}
141
+ </Droppable>
142
+ </DragDropContext>)
143
+ );
144
+ },
145
+ );
146
+
147
+
148
+
149
+ // @ts-ignore Trick Material UI Table into thinking this is one of the child type it supports.
150
+ SortableDatagridBody.muiName = 'TableBody';
151
+
152
+ export const PureSortableDatagridBody = memo(
153
+ (props) => <SortableDatagridBody row={<PureDatagridRow />} {...props} />,
154
+ () => true,
155
+ ); // Memo the sortable table, to avoid data updates.
156
+
157
+ // @ts-ignore Trick Material UI Table into thinking this is one of the child type it supports
158
+ PureSortableDatagridBody.muiName = 'TableBody';
159
+
160
+ export default PureSortableDatagridBody;
161
+
162
+
163
+ /* KnownIssue1 = No overload matches this call.
164
+ Overload 1 of 2, '(props: { component: ElementType<any>; } & TableBodyOwnProps & CommonProps & Omit<any, "className" | "style" | "classes" | "children" | "sx">): Element', gave the following error.
165
+ Type '{ children: Element[]; record?: RaRecord<Identifier>; rowSx?: (record: RaRecord<Identifier>, index: number) => SxProps; ... 262 more ...; className: string; }' is not assignable to type '{ component: ElementType<any>; }'.
166
+ Property 'component' is optional in type '{ children: Element[]; record?: RaRecord<Identifier>; rowSx?: (record: RaRecord<Identifier>, index: number) => SxProps; ... 262 more ...; className: string; }' but required in type '{ component: ElementType<any>; }'.
167
+ Overload 2 of 2, '(props: DefaultComponentProps<TableBodyTypeMap<{}, "tbody">>): Element', gave the following error.
168
+ Types of property 'sx' are incompatible.
169
+ Type 'import("/node_modules/@mui/system/styleFunctionSx/styleFunctionSx").SxProps<import("/node_modules/react-admin/node_modules/@mui/material/styles/createTheme").Theme>' is not assignable to type 'import("/node_modules/@mui/system/styleFunctionSx/styleFunctionSx").SxProps<import("/node_modules/@mui/material/styles/createTheme").Theme>'.
170
+ Type 'SystemCssProperties<Theme>' is not assignable to type 'SxProps<Theme>'.
171
+ Type 'SystemCssProperties<Theme>' is not assignable to type 'CSSSelectorObjectOrCssVariables<Theme>'.
172
+ Property 'clipPath' is incompatible with index signature.
173
+ Type 'SystemStyleObject<Theme> | ResponsiveStyleValue<ClipPath | string[]> | ((theme: Theme) => ResponsiveStyleValue<ClipPath | string[]>)' is not assignable to type 'CssVariableType | SystemStyleObject<Theme> | ((theme: Theme) => string | number | SystemStyleObject<Theme>)'.
174
+ Type 'SystemCssProperties<Theme>' is not assignable to type 'CssVariableType | SystemStyleObject<Theme> | ((theme: Theme) => string | number | SystemStyleObject<Theme>)'.ts(2769)
175
+ */