@firecms/core 3.0.0-beta.11 → 3.0.0-beta.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.
Files changed (173) hide show
  1. package/dist/components/ArrayContainer.d.ts +7 -3
  2. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +2 -1
  3. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
  4. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +15 -1
  5. package/dist/components/EntityCollectionTable/index.d.ts +1 -1
  6. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +4 -0
  7. package/dist/components/PropertyIdCopyTooltip.d.ts +1 -1
  8. package/dist/components/SelectableTable/SelectableTable.d.ts +12 -2
  9. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +1 -1
  10. package/dist/components/UnsavedChangesDialog.d.ts +8 -0
  11. package/dist/components/VirtualTable/VirtualTableProps.d.ts +13 -0
  12. package/dist/components/common/default_entity_actions.d.ts +0 -2
  13. package/dist/components/common/index.d.ts +1 -1
  14. package/dist/components/common/useColumnsIds.d.ts +1 -0
  15. package/dist/components/common/{useDataSourceEntityCollectionTableController.d.ts → useDataSourceTableController.d.ts} +10 -2
  16. package/dist/components/common/useDebouncedCallback.d.ts +1 -0
  17. package/dist/components/common/useScrollRestoration.d.ts +14 -0
  18. package/dist/contexts/BreacrumbsContext.d.ts +8 -0
  19. package/dist/core/EntityEditView.d.ts +29 -21
  20. package/dist/core/EntityEditViewFormActions.d.ts +2 -0
  21. package/dist/core/FireCMSRouter.d.ts +4 -0
  22. package/dist/core/NavigationRoutes.d.ts +0 -1
  23. package/dist/core/SideDialogs.d.ts +4 -2
  24. package/dist/core/index.d.ts +2 -1
  25. package/dist/form/EntityForm.d.ts +45 -0
  26. package/dist/form/EntityFormActions.d.ts +17 -0
  27. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  28. package/dist/form/components/FormEntry.d.ts +6 -0
  29. package/dist/form/components/FormLayout.d.ts +5 -0
  30. package/dist/form/components/index.d.ts +2 -0
  31. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  32. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  33. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  34. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  35. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
  36. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  37. package/dist/form/index.d.ts +16 -16
  38. package/dist/hooks/data/useEntityFetch.d.ts +2 -1
  39. package/dist/hooks/useBreadcrumbsController.d.ts +26 -0
  40. package/dist/hooks/useBuildNavigationController.d.ts +4 -1
  41. package/dist/hooks/useModeController.d.ts +1 -2
  42. package/dist/index.es.js +18213 -16819
  43. package/dist/index.es.js.map +1 -1
  44. package/dist/index.umd.js +18164 -16771
  45. package/dist/index.umd.js.map +1 -1
  46. package/dist/internal/useBuildSideEntityController.d.ts +2 -2
  47. package/dist/internal/useUnsavedChangesDialog.d.ts +7 -9
  48. package/dist/routes/CustomCMSRoute.d.ts +4 -0
  49. package/dist/routes/FireCMSRoute.d.ts +1 -0
  50. package/dist/routes/HomePageRoute.d.ts +3 -0
  51. package/dist/types/collections.d.ts +30 -10
  52. package/dist/types/datasource.d.ts +2 -2
  53. package/dist/types/dialogs_controller.d.ts +7 -3
  54. package/dist/types/entities.d.ts +1 -1
  55. package/dist/types/entity_actions.d.ts +10 -0
  56. package/dist/types/fields.d.ts +9 -2
  57. package/dist/types/navigation.d.ts +29 -12
  58. package/dist/types/plugins.d.ts +1 -0
  59. package/dist/types/properties.d.ts +18 -3
  60. package/dist/types/side_entity_controller.d.ts +6 -1
  61. package/dist/util/builders.d.ts +1 -1
  62. package/dist/util/entity_actions.d.ts +2 -0
  63. package/dist/util/entity_cache.d.ts +23 -0
  64. package/dist/util/index.d.ts +1 -0
  65. package/dist/util/navigation_from_path.d.ts +6 -1
  66. package/dist/util/navigation_utils.d.ts +12 -1
  67. package/dist/util/resolutions.d.ts +6 -1
  68. package/package.json +19 -21
  69. package/src/components/ArrayContainer.tsx +48 -29
  70. package/src/components/CircularProgressCenter.tsx +1 -1
  71. package/src/components/DeleteEntityDialog.tsx +1 -1
  72. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +40 -19
  73. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +10 -4
  74. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +18 -1
  75. package/src/components/EntityCollectionTable/index.tsx +1 -1
  76. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -3
  77. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +5 -11
  78. package/src/components/EntityCollectionView/EntityCollectionView.tsx +83 -41
  79. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +4 -2
  80. package/src/components/NotFoundPage.tsx +2 -2
  81. package/src/components/PropertyIdCopyTooltip.tsx +2 -3
  82. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +11 -6
  83. package/src/components/SelectableTable/SelectableTable.tsx +18 -3
  84. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +7 -7
  85. package/src/components/UnsavedChangesDialog.tsx +42 -0
  86. package/src/components/VirtualTable/VirtualTable.tsx +19 -2
  87. package/src/components/VirtualTable/VirtualTableProps.tsx +15 -0
  88. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +1 -1
  89. package/src/components/common/default_entity_actions.tsx +26 -37
  90. package/src/components/common/index.ts +1 -1
  91. package/src/components/common/useColumnsIds.tsx +1 -1
  92. package/src/components/common/useDataSourceTableController.tsx +420 -0
  93. package/src/components/common/useDebouncedCallback.tsx +20 -0
  94. package/src/components/common/useScrollRestoration.tsx +68 -0
  95. package/src/contexts/BreacrumbsContext.tsx +38 -0
  96. package/src/contexts/DialogsProvider.tsx +3 -2
  97. package/src/contexts/ModeController.tsx +1 -3
  98. package/src/core/DefaultAppBar.tsx +44 -14
  99. package/src/core/DefaultDrawer.tsx +1 -1
  100. package/src/core/EntityEditView.tsx +278 -1000
  101. package/src/core/EntityEditViewFormActions.tsx +199 -0
  102. package/src/core/EntitySidePanel.tsx +85 -15
  103. package/src/core/FireCMS.tsx +7 -4
  104. package/src/core/FireCMSRouter.tsx +17 -0
  105. package/src/core/NavigationRoutes.tsx +23 -32
  106. package/src/core/SideDialogs.tsx +20 -11
  107. package/src/core/index.tsx +4 -2
  108. package/src/form/EntityForm.tsx +774 -0
  109. package/src/form/EntityFormActions.tsx +169 -0
  110. package/src/form/PropertyFieldBinding.tsx +13 -11
  111. package/src/form/components/FormEntry.tsx +22 -0
  112. package/src/form/components/FormLayout.tsx +16 -0
  113. package/src/form/components/LabelWithIcon.tsx +6 -3
  114. package/src/form/components/StorageUploadProgress.tsx +1 -1
  115. package/src/form/components/index.tsx +2 -0
  116. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +4 -4
  117. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +4 -2
  118. package/src/form/field_bindings/BlockFieldBinding.tsx +4 -2
  119. package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -0
  120. package/src/form/field_bindings/MapFieldBinding.tsx +14 -16
  121. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +9 -6
  122. package/src/form/field_bindings/MultiSelectFieldBinding.tsx +1 -1
  123. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +2 -2
  124. package/src/form/field_bindings/ReferenceFieldBinding.tsx +1 -1
  125. package/src/form/field_bindings/RepeatFieldBinding.tsx +5 -2
  126. package/src/form/field_bindings/SelectFieldBinding.tsx +1 -1
  127. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +6 -4
  128. package/src/form/field_bindings/SwitchFieldBinding.tsx +1 -0
  129. package/src/form/field_bindings/TextFieldBinding.tsx +1 -0
  130. package/src/form/index.tsx +16 -32
  131. package/src/form/validation.ts +12 -6
  132. package/src/hooks/data/save.ts +1 -1
  133. package/src/hooks/data/useCollectionFetch.tsx +1 -1
  134. package/src/hooks/data/useEntityFetch.tsx +5 -1
  135. package/src/hooks/useBreadcrumbsController.tsx +31 -0
  136. package/src/hooks/useBuildModeController.tsx +15 -28
  137. package/src/hooks/useBuildNavigationController.tsx +70 -24
  138. package/src/hooks/useLargeLayout.tsx +0 -35
  139. package/src/hooks/useModeController.tsx +1 -2
  140. package/src/hooks/useResolvedNavigationFrom.tsx +4 -6
  141. package/src/internal/useBuildSideDialogsController.tsx +3 -2
  142. package/src/internal/useBuildSideEntityController.tsx +124 -83
  143. package/src/internal/useUnsavedChangesDialog.tsx +126 -92
  144. package/src/preview/PropertyPreview.tsx +8 -8
  145. package/src/preview/components/UrlComponentPreview.tsx +17 -18
  146. package/src/preview/property_previews/MapPropertyPreview.tsx +3 -2
  147. package/src/routes/CustomCMSRoute.tsx +21 -0
  148. package/src/routes/FireCMSRoute.tsx +235 -0
  149. package/src/routes/HomePageRoute.tsx +17 -0
  150. package/src/types/collections.ts +38 -13
  151. package/src/types/datasource.ts +2 -1
  152. package/src/types/dialogs_controller.tsx +7 -3
  153. package/src/types/entities.ts +1 -1
  154. package/src/types/entity_actions.tsx +12 -0
  155. package/src/types/fields.tsx +13 -2
  156. package/src/types/navigation.ts +36 -16
  157. package/src/types/plugins.tsx +1 -0
  158. package/src/types/properties.ts +21 -3
  159. package/src/types/side_dialogs_controller.tsx +2 -0
  160. package/src/types/side_entity_controller.tsx +6 -1
  161. package/src/util/builders.ts +5 -3
  162. package/src/util/entity_actions.ts +28 -0
  163. package/src/util/entity_cache.ts +204 -0
  164. package/src/util/index.ts +1 -0
  165. package/src/util/join_collections.ts +3 -0
  166. package/src/util/navigation_from_path.ts +13 -6
  167. package/src/util/navigation_utils.ts +53 -1
  168. package/src/util/objects.ts +4 -1
  169. package/src/util/parent_references_from_path.ts +3 -3
  170. package/src/util/resolutions.ts +26 -5
  171. package/src/util/useStorageUploadController.tsx +39 -21
  172. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +0 -236
  173. /package/src/util/{common.tsx → common.ts} +0 -0
@@ -41,6 +41,8 @@ export interface ArrayContainerProps<T> {
41
41
  newDefaultEntry: T;
42
42
  onValueChange: (value: T[]) => void,
43
43
  className?: string;
44
+ min?: number;
45
+ max?: number;
44
46
  }
45
47
 
46
48
  const buildIdsMap = (value: any[]) =>
@@ -67,7 +69,9 @@ export function ArrayContainer<T>({
67
69
  includeAddButton,
68
70
  newDefaultEntry,
69
71
  onValueChange,
70
- className
72
+ className,
73
+ min = 0,
74
+ max = Infinity
71
75
  }: ArrayContainerProps<T>) {
72
76
 
73
77
  const hasValue = value && Array.isArray(value) && value.length > 0;
@@ -78,7 +82,8 @@ export function ArrayContainer<T>({
78
82
  const [internalIds, setInternalIds] = useState<number[]>(
79
83
  hasValue
80
84
  ? Object.values(internalIdsRef.current)
81
- : []);
85
+ : []
86
+ );
82
87
 
83
88
  const itemCustomPropsRef = useRef<Record<number, object>>({});
84
89
 
@@ -104,7 +109,7 @@ export function ArrayContainer<T>({
104
109
 
105
110
  const insertInEnd = (e: React.SyntheticEvent) => {
106
111
  e.preventDefault();
107
- if (disabled) return;
112
+ if (disabled || (value ?? []).length >= max) return;
108
113
  const id = getRandomId();
109
114
  const newIds: number[] = [...internalIds, id];
110
115
  if (onInternalIdAdded)
@@ -114,6 +119,7 @@ export function ArrayContainer<T>({
114
119
  };
115
120
 
116
121
  const remove = (index: number) => {
122
+ if ((value ?? []).length <= min) return;
117
123
  const newIds = [...internalIds];
118
124
  newIds.splice(index, 1);
119
125
  setInternalIds(newIds);
@@ -121,12 +127,14 @@ export function ArrayContainer<T>({
121
127
  };
122
128
 
123
129
  const copy = (index: number) => {
130
+ if ((value ?? []).length >= max) return;
124
131
  const id = getRandomId();
125
132
  const copyingItem = value[index];
126
133
  const newIds: number[] = [
127
- ...internalIds.splice(0, index + 1),
134
+ ...internalIds.slice(0, index + 1),
128
135
  id,
129
- ...internalIds.splice(index + 1, internalIds.length - index - 1)];
136
+ ...internalIds.slice(index + 1)
137
+ ];
130
138
  if (onInternalIdAdded)
131
139
  onInternalIdAdded(id);
132
140
  setInternalIds(newIds);
@@ -135,11 +143,13 @@ export function ArrayContainer<T>({
135
143
  };
136
144
 
137
145
  const addInIndex = (index: number) => {
146
+ if ((value ?? []).length >= max) return;
138
147
  const id = getRandomId();
139
148
  const newIds: number[] = [
140
- ...internalIds.splice(0, index),
149
+ ...internalIds.slice(0, index),
141
150
  id,
142
- ...internalIds.slice(index)];
151
+ ...internalIds.slice(index)
152
+ ];
143
153
  if (onInternalIdAdded)
144
154
  onInternalIdAdded(id);
145
155
  setInternalIds(newIds);
@@ -183,6 +193,7 @@ export function ArrayContainer<T>({
183
193
  storedProps={itemCustomPropsRef.current[internalId]}
184
194
  updateItemCustomProps={updateItemCustomProps}
185
195
  addInIndex={addInIndex}
196
+ includeAddButton={includeAddButton}
186
197
  />
187
198
  );
188
199
  }}
@@ -213,6 +224,7 @@ export function ArrayContainer<T>({
213
224
  storedProps={itemCustomPropsRef.current[internalId]}
214
225
  updateItemCustomProps={updateItemCustomProps}
215
226
  addInIndex={addInIndex}
227
+ includeAddButton={includeAddButton}
216
228
  />
217
229
  )}
218
230
  </Draggable>
@@ -221,17 +233,19 @@ export function ArrayContainer<T>({
221
233
 
222
234
  {droppableProvided.placeholder}
223
235
 
224
- {includeAddButton && <div className="py-4 justify-center text-left">
225
- <Button
226
- variant={"text"}
227
- size={size === "small" ? "small" : "medium"}
228
- color="primary"
229
- disabled={disabled}
230
- startIcon={<AddIcon/>}
231
- onClick={insertInEnd}>
232
- {addLabel ?? "Add"}
233
- </Button>
234
- </div>}
236
+ {includeAddButton && (
237
+ <div className="my-4 justify-center text-left">
238
+ <Button
239
+ variant={"text"}
240
+ size={size === "small" ? "small" : "medium"}
241
+ color="primary"
242
+ disabled={disabled || value?.length >= max}
243
+ startIcon={<AddIcon/>}
244
+ onClick={insertInEnd}>
245
+ {addLabel ?? "Add"}
246
+ </Button>
247
+ </div>
248
+ )}
235
249
  </div>
236
250
  )}
237
251
  </Droppable>
@@ -249,6 +263,7 @@ type ArrayContainerItemProps = {
249
263
  remove: (index: number) => void,
250
264
  copy: (index: number) => void,
251
265
  addInIndex?: (index: number) => void,
266
+ includeAddButton?: boolean,
252
267
  isDragging: boolean,
253
268
  storedProps?: object,
254
269
  updateItemCustomProps: (internalId: number, props: object) => void
@@ -263,6 +278,7 @@ export function ArrayContainerItem({
263
278
  buildEntry,
264
279
  remove,
265
280
  addInIndex,
281
+ includeAddButton,
266
282
  copy,
267
283
  isDragging,
268
284
  storedProps,
@@ -273,7 +289,7 @@ export function ArrayContainerItem({
273
289
  ref={provided.innerRef}
274
290
  {...provided.draggableProps}
275
291
  style={provided.draggableProps.style}
276
- className={`${
292
+ className={`relative ${
277
293
  !isDragging ? "hover:bg-surface-accent-50 dark:hover:bg-surface-800 dark:hover:bg-opacity-20" : ""
278
294
  } rounded-md opacity-100`}
279
295
  >
@@ -295,6 +311,7 @@ export function ArrayContainerItem({
295
311
  index={index}
296
312
  provided={provided}
297
313
  addInIndex={addInIndex}
314
+ includeAddButton={includeAddButton}
298
315
  copy={copy}/>
299
316
  </div>
300
317
  </div>;
@@ -307,6 +324,7 @@ export function ArrayItemOptions({
307
324
  index,
308
325
  provided,
309
326
  copy,
327
+ includeAddButton,
310
328
  addInIndex
311
329
  }: {
312
330
  direction?: "row" | "column",
@@ -315,6 +333,7 @@ export function ArrayItemOptions({
315
333
  index: number,
316
334
  provided: any,
317
335
  copy: (index: number) => void,
336
+ includeAddButton?: boolean,
318
337
  addInIndex?: (index: number) => void
319
338
  }) {
320
339
 
@@ -365,20 +384,20 @@ export function ArrayItemOptions({
365
384
  Copy
366
385
  </MenuItem>
367
386
 
368
- {addInIndex && <MenuItem dense
369
- onClick={() => {
370
- setMenuOpen(false);
371
- addInIndex(index);
372
- }}>
387
+ {includeAddButton && addInIndex && <MenuItem dense
388
+ onClick={() => {
389
+ setMenuOpen(false);
390
+ addInIndex(index);
391
+ }}>
373
392
  <KeyboardArrowUpIcon size={"small"}/>
374
393
  Add on top
375
394
  </MenuItem>}
376
395
 
377
- {addInIndex && <MenuItem dense
378
- onClick={() => {
379
- setMenuOpen(false);
380
- addInIndex(index + 1);
381
- }}>
396
+ {includeAddButton && addInIndex && <MenuItem dense
397
+ onClick={() => {
398
+ setMenuOpen(false);
399
+ addInIndex(index + 1);
400
+ }}>
382
401
  <KeyboardArrowDownIcon size={"small"}/>
383
402
  Add below
384
403
  </MenuItem>}
@@ -13,7 +13,7 @@ export function CircularProgressCenter({ text, ...props }: CircularProgressProps
13
13
  }) {
14
14
  return (
15
15
  <div
16
- className="flex w-full h-screen max-h-full max-w-full bg-surface-50 dark:bg-surface-900 gap-4">
16
+ className="flex w-full h-screen max-h-full max-w-full gap-4">
17
17
  <div className="m-auto flex flex-col gap-2 items-center">
18
18
  <CircularProgress {...props}/>
19
19
  {text && <Typography
@@ -181,7 +181,7 @@ export function DeleteEntityDialog<M extends Record<string, any>>({
181
181
  </DialogContent>
182
182
  <DialogActions>
183
183
 
184
- {loading && <CircularProgress size={"small"}/>}
184
+ {loading && <CircularProgress size={"smallest"}/>}
185
185
 
186
186
  <Button onClick={handleCancel}
187
187
  disabled={loading}
@@ -1,8 +1,20 @@
1
1
  import React, { MouseEvent, useCallback } from "react";
2
2
 
3
3
  import { CollectionSize, Entity, EntityAction, EntityCollection, SelectionController } from "../../types";
4
- import { Checkbox, cls, IconButton, Menu, MenuItem, MoreVertIcon, Skeleton, Tooltip } from "@firecms/ui";
4
+ import {
5
+ Checkbox,
6
+ Chip,
7
+ cls,
8
+ EditIcon,
9
+ IconButton,
10
+ Menu,
11
+ MenuItem,
12
+ MoreVertIcon,
13
+ Skeleton,
14
+ Tooltip
15
+ } from "@firecms/ui";
5
16
  import { useFireCMSContext, useLargeLayout } from "../../hooks";
17
+ import { hasEntityInCache } from "../../util/entity_cache";
6
18
 
7
19
  /**
8
20
  *
@@ -32,23 +44,25 @@ export const EntityCollectionRowActions = function EntityCollectionRowActions({
32
44
  actions = [],
33
45
  hideId,
34
46
  selectionController,
47
+ openEntityMode
35
48
  }:
36
- {
37
- entity: Entity<any>,
38
- collection?: EntityCollection<any>,
39
- fullPath?: string,
40
- width: number,
41
- frozen?: boolean,
42
- size: CollectionSize,
43
- isSelected?: boolean,
44
- selectionEnabled?: boolean,
45
- actions?: EntityAction[],
46
- hideId?: boolean,
47
- onCollectionChange?: () => void,
48
- selectionController?: SelectionController;
49
- highlightEntity?: (entity: Entity<any>) => void;
50
- unhighlightEntity?: (entity: Entity<any>) => void;
51
- }) {
49
+ {
50
+ entity: Entity<any>,
51
+ collection?: EntityCollection<any>,
52
+ fullPath?: string,
53
+ width: number,
54
+ frozen?: boolean,
55
+ size: CollectionSize,
56
+ isSelected?: boolean,
57
+ selectionEnabled?: boolean,
58
+ actions?: EntityAction[],
59
+ hideId?: boolean,
60
+ onCollectionChange?: () => void,
61
+ selectionController?: SelectionController;
62
+ highlightEntity?: (entity: Entity<any>) => void;
63
+ unhighlightEntity?: (entity: Entity<any>) => void;
64
+ openEntityMode: "side_panel" | "full_screen";
65
+ }) {
52
66
 
53
67
  const largeLayout = useLargeLayout();
54
68
 
@@ -63,6 +77,7 @@ export const EntityCollectionRowActions = function EntityCollectionRowActions({
63
77
 
64
78
  const collapsedActions = actions.filter(a => a.collapsed || a.collapsed === undefined);
65
79
  const uncollapsedActions = actions.filter(a => a.collapsed === false);
80
+ const hasDraft = hasEntityInCache(fullPath + "/" + entity.id);
66
81
  return (
67
82
  <div
68
83
  className={cls(
@@ -98,6 +113,7 @@ export const EntityCollectionRowActions = function EntityCollectionRowActions({
98
113
  highlightEntity,
99
114
  unhighlightEntity,
100
115
  onCollectionChange,
116
+ openEntityMode: openEntityMode ?? collection?.openEntityMode
101
117
  });
102
118
  }}
103
119
  size={largeLayout ? "medium" : "small"}>
@@ -126,6 +142,7 @@ export const EntityCollectionRowActions = function EntityCollectionRowActions({
126
142
  highlightEntity,
127
143
  unhighlightEntity,
128
144
  onCollectionChange,
145
+ openEntityMode: openEntityMode ?? collection?.openEntityMode
129
146
  });
130
147
  }}>
131
148
  {action.icon}
@@ -148,11 +165,15 @@ export const EntityCollectionRowActions = function EntityCollectionRowActions({
148
165
 
149
166
  {!hideId && size !== "xs" && (
150
167
  <div
151
- className="w-[138px] text-center overflow-hidden truncate font-mono text-xs text-text-secondary dark:text-text-secondary-dark max-w-full text-ellipsis px-2"
168
+ className="w-[138px] overflow-hidden truncate font-mono text-xs text-text-secondary dark:text-text-secondary-dark max-w-full text-ellipsis px-2 align-center flex items-center justify-center gap-1"
152
169
  onClick={(event) => {
153
170
  event.stopPropagation();
154
171
  }}>
155
-
172
+ {hasDraft && <Tooltip title={"Unsaved changes"} className={"inline"}>
173
+ <Chip colorScheme={"orangeDarker"} className={"p-0.5"}>
174
+ <EditIcon size={12}/>
175
+ </Chip>
176
+ </Tooltip>}
156
177
  {entity
157
178
  ? entity.id
158
179
  : <Skeleton/>
@@ -34,14 +34,14 @@ import { getRowHeight } from "../common/table_height";
34
34
  *
35
35
  * The data displayed in the table is managed by a {@link EntityTableController}.
36
36
  * You can build the default, bound to a path in the datasource, by using the hook
37
- * {@link useDataSourceEntityCollectionTableController}
37
+ * {@link useDataSourceTableController}
38
38
  *
39
39
  * @see EntityCollectionTableProps
40
40
  * @see EntityCollectionView
41
41
  * @see VirtualTable
42
42
  * @group Components
43
43
  */
44
- export const EntityCollectionTable = function EntityCollectionTable<M extends Record<string, any>, USER extends User>
44
+ export const EntityCollectionTable = function EntityCollectionTable<M extends Record<string, any> = any, USER extends User = any>
45
45
  ({
46
46
  className,
47
47
  style,
@@ -57,6 +57,8 @@ export const EntityCollectionTable = function EntityCollectionTable<M extends Re
57
57
  highlightedEntities,
58
58
  onEntityClick,
59
59
  onColumnResize,
60
+ initialScroll,
61
+ onScroll,
60
62
  onSizeChanged,
61
63
  textSearchEnabled = false,
62
64
  hoverRow = true,
@@ -76,7 +78,8 @@ export const EntityCollectionTable = function EntityCollectionTable<M extends Re
76
78
  getIdColumnWidth,
77
79
  onTextSearchClick,
78
80
  textSearchLoading,
79
- enablePopupIcon
81
+ enablePopupIcon,
82
+ openEntityMode = "side_panel"
80
83
  }: EntityCollectionTableProps<M>) {
81
84
 
82
85
  const ref = useRef<HTMLDivElement>(null);
@@ -265,7 +268,8 @@ export const EntityCollectionTable = function EntityCollectionTable<M extends Re
265
268
  width={column.width}
266
269
  frozen={column.frozen}
267
270
  isSelected={false}
268
- size={size}/>;
271
+ size={size}
272
+ openEntityMode={openEntityMode}/>;
269
273
  } else if (additionalFieldsMap[columnKey]) {
270
274
  return additionalCellRenderer(props);
271
275
  } else if (props.columnIndex < columns.length + 1) {
@@ -313,6 +317,8 @@ export const EntityCollectionTable = function EntityCollectionTable<M extends Re
313
317
  highlightedRow={(entity: Entity<M>) => Boolean(selectedEntities?.find(e => e.id === entity.id && e.path === entity.path))}
314
318
  tableController={tableController}
315
319
  onValueChange={onValueChange}
320
+ initialScroll={initialScroll}
321
+ onScroll={onScroll}
316
322
  onColumnResize={onColumnResize}
317
323
  hoverRow={hoverRow}
318
324
  filterable={filterable}
@@ -72,6 +72,21 @@ export type EntityCollectionTableProps<M extends Record<string, any>,
72
72
  */
73
73
  onColumnResize?(params: OnColumnResizeParams): void;
74
74
 
75
+ /**
76
+ * Initial scroll position
77
+ */
78
+ initialScroll?: number;
79
+
80
+ /**
81
+ * Callback when the table is scrolled
82
+ * @param props
83
+ */
84
+ onScroll?: (props: {
85
+ scrollDirection: "forward" | "backward",
86
+ scrollOffset: number,
87
+ scrollUpdateWasRequested: boolean
88
+ }) => void;
89
+
75
90
  /**
76
91
  * Callback when the selected size of the table is changed
77
92
  */
@@ -90,7 +105,7 @@ export type EntityCollectionTableProps<M extends Record<string, any>,
90
105
 
91
106
  /**
92
107
  * Controller holding the logic for the table
93
- * {@link useDataSourceEntityCollectionTableController}
108
+ * {@link useDataSourceTableController}
94
109
  * {@link EntityTableController}
95
110
  */
96
111
  tableController: EntityTableController<M>;
@@ -136,6 +151,8 @@ export type EntityCollectionTableProps<M extends Record<string, any>,
136
151
  textSearchLoading?: boolean;
137
152
 
138
153
  enablePopupIcon: boolean;
154
+
155
+ openEntityMode?: "side_panel" | "full_screen";
139
156
  };
140
157
 
141
158
  export type GetPropertyForProps<M extends Record<string, any>> = {
@@ -8,5 +8,5 @@ export type {
8
8
 
9
9
  export * from "./PropertyTableCell";
10
10
  export * from "./EntityCollectionRowActions";
11
- export * from "../common/useDataSourceEntityCollectionTableController";
11
+ export * from "../common/useDataSourceTableController";
12
12
  export * from "./column_utils";
@@ -56,7 +56,7 @@ export function CollectionTableToolbar({
56
56
  <Select
57
57
  value={size as string}
58
58
  className="w-16 h-10"
59
- size={"medium"}
59
+ size={"small"}
60
60
  onValueChange={(v) => onSizeChanged(v as CollectionSize)}
61
61
  renderValue={(v) => <div className={"font-medium"}>{v.toUpperCase()}</div>}
62
62
  >
@@ -87,9 +87,9 @@ export function CollectionTableToolbar({
87
87
 
88
88
  <div className="flex items-center gap-2">
89
89
 
90
- {largeLayout && <div className="w-[22px]">
90
+ {largeLayout && <div className="w-[22px] mr-4">
91
91
  {loading &&
92
- <CircularProgress size={"small"}/>}
92
+ <CircularProgress size={"smallest"}/>}
93
93
  </div>}
94
94
 
95
95
  {(onTextSearch || onTextSearchClick) &&
@@ -20,10 +20,9 @@ import { useWindowSize } from "./useWindowSize";
20
20
  import { ElementResizeListener } from "./ElementResizeListener";
21
21
  import { getPropertyInPath, isReadOnly, resolveCollection } from "../../../../util";
22
22
  import { Button, CloseIcon, DialogActions, IconButton, Typography } from "@firecms/ui";
23
- import { PropertyFieldBinding } from "../../../../form";
23
+ import { PropertyFieldBinding, yupToFormErrors } from "../../../../form";
24
24
  import { useCustomizationController, useDataSource, useFireCMSContext } from "../../../../hooks";
25
25
  import { OnCellValueChangeParams } from "../../../common";
26
- import { yupToFormErrors } from "../../../../core/EntityEditView";
27
26
 
28
27
  interface PopupFormFieldProps<M extends Record<string, any>> {
29
28
  customFieldValidator?: CustomFieldValidator;
@@ -240,14 +239,7 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
240
239
  validation: (values) => {
241
240
  return validationSchema?.validate(values, { abortEarly: false })
242
241
  .then(() => ({}))
243
- .catch((e) => {
244
- // const errors: Record<string, string> = {};
245
- // e.inner.forEach((error: any) => {
246
- // errors[error.path] = error.message;
247
- // });
248
- // return errors;
249
- return yupToFormErrors(e);
250
- });
242
+ .catch(yupToFormErrors);
251
243
  },
252
244
  validateOnInitialRender: true,
253
245
  onSubmit: (values, actions) => {
@@ -278,7 +270,9 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
278
270
  path,
279
271
  setFieldValue,
280
272
  save: saveValue,
281
- formex
273
+ formex,
274
+ status: "existing",
275
+ openEntityMode: "side_panel",
282
276
  };
283
277
 
284
278
  const property: ResolvedProperty<any> | undefined = propertyKey && getPropertyInPath(collection?.properties ?? {} as ResolvedProperties, propertyKey as string);