@firecms/core 3.0.0-beta.11 → 3.0.0-beta.13

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 (201) hide show
  1. package/dist/app/Scaffold.d.ts +4 -0
  2. package/dist/components/ArrayContainer.d.ts +14 -3
  3. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +2 -1
  4. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
  5. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +15 -1
  6. package/dist/components/EntityCollectionTable/index.d.ts +1 -1
  7. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +8 -0
  8. package/dist/components/EntityJsonPreview.d.ts +3 -0
  9. package/dist/components/PropertyIdCopyTooltip.d.ts +1 -1
  10. package/dist/components/SelectableTable/SelectableTable.d.ts +12 -2
  11. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +1 -1
  12. package/dist/components/UnsavedChangesDialog.d.ts +8 -0
  13. package/dist/components/VirtualTable/VirtualTableProps.d.ts +13 -0
  14. package/dist/components/common/default_entity_actions.d.ts +0 -2
  15. package/dist/components/common/index.d.ts +1 -1
  16. package/dist/components/common/useColumnsIds.d.ts +1 -0
  17. package/dist/components/common/{useDataSourceEntityCollectionTableController.d.ts → useDataSourceTableController.d.ts} +10 -2
  18. package/dist/components/common/useDebouncedCallback.d.ts +1 -0
  19. package/dist/components/common/useScrollRestoration.d.ts +14 -0
  20. package/dist/contexts/BreacrumbsContext.d.ts +8 -0
  21. package/dist/core/DefaultAppBar.d.ts +8 -2
  22. package/dist/core/EntityEditView.d.ts +36 -21
  23. package/dist/core/EntityEditViewFormActions.d.ts +2 -0
  24. package/dist/core/FireCMS.d.ts +2 -2
  25. package/dist/core/FireCMSRouter.d.ts +4 -0
  26. package/dist/core/NavigationRoutes.d.ts +0 -1
  27. package/dist/core/SideDialogs.d.ts +4 -2
  28. package/dist/core/index.d.ts +2 -1
  29. package/dist/form/EntityForm.d.ts +49 -0
  30. package/dist/form/EntityFormActions.d.ts +17 -0
  31. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  32. package/dist/form/components/FormEntry.d.ts +6 -0
  33. package/dist/form/components/FormLayout.d.ts +5 -0
  34. package/dist/form/components/index.d.ts +2 -0
  35. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  36. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  37. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  38. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  39. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
  40. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  41. package/dist/form/index.d.ts +16 -16
  42. package/dist/hooks/data/save.d.ts +1 -1
  43. package/dist/hooks/data/useEntityFetch.d.ts +2 -1
  44. package/dist/hooks/useBreadcrumbsController.d.ts +26 -0
  45. package/dist/hooks/useBuildNavigationController.d.ts +4 -1
  46. package/dist/hooks/useModeController.d.ts +1 -2
  47. package/dist/index.es.js +15842 -14396
  48. package/dist/index.es.js.map +1 -1
  49. package/dist/index.umd.js +15833 -14389
  50. package/dist/index.umd.js.map +1 -1
  51. package/dist/internal/useBuildDataSource.d.ts +3 -2
  52. package/dist/internal/useBuildSideEntityController.d.ts +3 -3
  53. package/dist/internal/useUnsavedChangesDialog.d.ts +7 -9
  54. package/dist/routes/CustomCMSRoute.d.ts +4 -0
  55. package/dist/routes/FireCMSRoute.d.ts +1 -0
  56. package/dist/routes/HomePageRoute.d.ts +3 -0
  57. package/dist/types/collections.d.ts +36 -10
  58. package/dist/types/datasource.d.ts +2 -2
  59. package/dist/types/dialogs_controller.d.ts +7 -3
  60. package/dist/types/entities.d.ts +1 -1
  61. package/dist/types/entity_actions.d.ts +10 -0
  62. package/dist/types/fields.d.ts +13 -3
  63. package/dist/types/firecms.d.ts +1 -1
  64. package/dist/types/navigation.d.ts +33 -12
  65. package/dist/types/plugins.d.ts +2 -0
  66. package/dist/types/properties.d.ts +40 -4
  67. package/dist/types/side_entity_controller.d.ts +6 -1
  68. package/dist/util/builders.d.ts +1 -1
  69. package/dist/util/createFormexStub.d.ts +2 -0
  70. package/dist/util/entity_actions.d.ts +2 -0
  71. package/dist/util/entity_cache.d.ts +23 -0
  72. package/dist/util/index.d.ts +1 -0
  73. package/dist/util/navigation_from_path.d.ts +6 -1
  74. package/dist/util/navigation_utils.d.ts +13 -1
  75. package/dist/util/objects.d.ts +1 -1
  76. package/dist/util/property_utils.d.ts +2 -2
  77. package/dist/util/references.d.ts +2 -2
  78. package/dist/util/resolutions.d.ts +12 -2
  79. package/package.json +20 -21
  80. package/src/app/Scaffold.tsx +13 -3
  81. package/src/components/ArrayContainer.tsx +60 -24
  82. package/src/components/CircularProgressCenter.tsx +1 -1
  83. package/src/components/DeleteEntityDialog.tsx +5 -3
  84. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +46 -23
  85. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +10 -4
  86. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +18 -1
  87. package/src/components/EntityCollectionTable/index.tsx +1 -1
  88. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -3
  89. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +10 -13
  90. package/src/components/EntityCollectionView/EntityCollectionView.tsx +105 -47
  91. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +4 -2
  92. package/src/components/EntityJsonPreview.tsx +66 -0
  93. package/src/components/EntityPreview.tsx +10 -3
  94. package/src/components/EntityView.tsx +4 -1
  95. package/src/components/NotFoundPage.tsx +2 -2
  96. package/src/components/PropertyIdCopyTooltip.tsx +2 -3
  97. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +14 -7
  98. package/src/components/SelectableTable/SelectableTable.tsx +18 -3
  99. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +7 -7
  100. package/src/components/UnsavedChangesDialog.tsx +42 -0
  101. package/src/components/VirtualTable/VirtualTable.tsx +48 -3
  102. package/src/components/VirtualTable/VirtualTableProps.tsx +15 -0
  103. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +1 -1
  104. package/src/components/common/default_entity_actions.tsx +37 -37
  105. package/src/components/common/index.ts +1 -1
  106. package/src/components/common/useColumnsIds.tsx +1 -1
  107. package/src/components/common/useDataSourceTableController.tsx +420 -0
  108. package/src/components/common/useDebouncedCallback.tsx +20 -0
  109. package/src/components/common/useScrollRestoration.tsx +68 -0
  110. package/src/contexts/BreacrumbsContext.tsx +38 -0
  111. package/src/contexts/DialogsProvider.tsx +3 -2
  112. package/src/contexts/ModeController.tsx +1 -3
  113. package/src/core/DefaultAppBar.tsx +59 -17
  114. package/src/core/DefaultDrawer.tsx +1 -1
  115. package/src/core/EntityEditView.tsx +354 -1000
  116. package/src/core/EntityEditViewFormActions.tsx +199 -0
  117. package/src/core/EntitySidePanel.tsx +85 -15
  118. package/src/core/FireCMS.tsx +20 -16
  119. package/src/core/FireCMSRouter.tsx +17 -0
  120. package/src/core/NavigationRoutes.tsx +23 -32
  121. package/src/core/SideDialogs.tsx +20 -11
  122. package/src/core/index.tsx +4 -2
  123. package/src/form/EntityForm.tsx +782 -0
  124. package/src/form/EntityFormActions.tsx +169 -0
  125. package/src/form/PropertyFieldBinding.tsx +21 -16
  126. package/src/form/components/FormEntry.tsx +22 -0
  127. package/src/form/components/FormLayout.tsx +16 -0
  128. package/src/form/components/LabelWithIcon.tsx +6 -3
  129. package/src/form/components/StorageUploadProgress.tsx +1 -1
  130. package/src/form/components/index.tsx +2 -0
  131. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +8 -5
  132. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +5 -2
  133. package/src/form/field_bindings/BlockFieldBinding.tsx +5 -3
  134. package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -0
  135. package/src/form/field_bindings/KeyValueFieldBinding.tsx +1 -1
  136. package/src/form/field_bindings/MapFieldBinding.tsx +14 -16
  137. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +15 -8
  138. package/src/form/field_bindings/MultiSelectFieldBinding.tsx +3 -3
  139. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +2 -2
  140. package/src/form/field_bindings/ReferenceFieldBinding.tsx +1 -1
  141. package/src/form/field_bindings/RepeatFieldBinding.tsx +13 -4
  142. package/src/form/field_bindings/SelectFieldBinding.tsx +2 -2
  143. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +11 -6
  144. package/src/form/field_bindings/SwitchFieldBinding.tsx +1 -0
  145. package/src/form/field_bindings/TextFieldBinding.tsx +1 -0
  146. package/src/form/index.tsx +16 -32
  147. package/src/form/validation.ts +12 -6
  148. package/src/hooks/data/save.ts +25 -30
  149. package/src/hooks/data/useCollectionFetch.tsx +1 -1
  150. package/src/hooks/data/useEntityFetch.tsx +5 -1
  151. package/src/hooks/useBreadcrumbsController.tsx +31 -0
  152. package/src/hooks/useBuildModeController.tsx +15 -28
  153. package/src/hooks/useBuildNavigationController.tsx +81 -24
  154. package/src/hooks/useFireCMSContext.tsx +0 -30
  155. package/src/hooks/useLargeLayout.tsx +0 -35
  156. package/src/hooks/useModeController.tsx +1 -2
  157. package/src/hooks/useResolvedNavigationFrom.tsx +4 -6
  158. package/src/internal/useBuildDataSource.ts +9 -5
  159. package/src/internal/useBuildSideDialogsController.tsx +3 -2
  160. package/src/internal/useBuildSideEntityController.tsx +135 -88
  161. package/src/internal/useUnsavedChangesDialog.tsx +126 -92
  162. package/src/preview/PropertyPreview.tsx +12 -10
  163. package/src/preview/components/UrlComponentPreview.tsx +17 -18
  164. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +4 -3
  165. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +4 -3
  166. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +4 -2
  167. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +4 -3
  168. package/src/preview/property_previews/ArrayOneOfPreview.tsx +4 -2
  169. package/src/preview/property_previews/ArrayPropertyPreview.tsx +4 -2
  170. package/src/preview/property_previews/MapPropertyPreview.tsx +3 -2
  171. package/src/routes/CustomCMSRoute.tsx +21 -0
  172. package/src/routes/FireCMSRoute.tsx +246 -0
  173. package/src/routes/HomePageRoute.tsx +17 -0
  174. package/src/types/collections.ts +45 -13
  175. package/src/types/datasource.ts +2 -1
  176. package/src/types/dialogs_controller.tsx +7 -3
  177. package/src/types/entities.ts +1 -1
  178. package/src/types/entity_actions.tsx +12 -0
  179. package/src/types/fields.tsx +18 -3
  180. package/src/types/firecms.tsx +1 -1
  181. package/src/types/navigation.ts +41 -16
  182. package/src/types/plugins.tsx +2 -0
  183. package/src/types/properties.ts +48 -4
  184. package/src/types/side_dialogs_controller.tsx +2 -0
  185. package/src/types/side_entity_controller.tsx +11 -1
  186. package/src/util/builders.ts +5 -3
  187. package/src/util/createFormexStub.tsx +62 -0
  188. package/src/util/entity_actions.ts +28 -0
  189. package/src/util/entity_cache.ts +204 -0
  190. package/src/util/index.ts +1 -0
  191. package/src/util/join_collections.ts +6 -1
  192. package/src/util/navigation_from_path.ts +18 -7
  193. package/src/util/navigation_utils.ts +115 -14
  194. package/src/util/objects.ts +9 -2
  195. package/src/util/parent_references_from_path.ts +3 -3
  196. package/src/util/property_utils.tsx +7 -3
  197. package/src/util/references.ts +8 -6
  198. package/src/util/resolutions.ts +41 -12
  199. package/src/util/useStorageUploadController.tsx +60 -23
  200. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +0 -236
  201. /package/src/util/{common.tsx → common.ts} +0 -0
@@ -4,7 +4,7 @@ import { useCallback, useState } from "react";
4
4
  export function PropertyIdCopyTooltip({
5
5
  propertyKey,
6
6
  className,
7
- children
7
+ children,
8
8
  }: {
9
9
  propertyKey: string,
10
10
  className?: string,
@@ -13,11 +13,10 @@ export function PropertyIdCopyTooltip({
13
13
  return <Tooltip title={<PropertyIdCopyTooltipContent propertyKey={propertyKey}/>}
14
14
  delayDuration={800}
15
15
  side={"top"}
16
- asChild={false}
17
16
  align={"start"}
18
17
  sideOffset={8}
19
18
  className={className}>
20
- {children}
19
+ {children}
21
20
  </Tooltip>
22
21
 
23
22
  }
@@ -4,7 +4,7 @@ import { CollectionSize, Entity, EntityCollection, FilterValues } from "../../ty
4
4
  import {
5
5
  EntityCollectionRowActions,
6
6
  EntityCollectionTable,
7
- useDataSourceEntityCollectionTableController
7
+ useDataSourceTableController
8
8
  } from "../EntityCollectionTable";
9
9
  import {
10
10
  useAuthController,
@@ -101,13 +101,14 @@ export function ReferenceSelectionTable<M extends Record<string, any>>(
101
101
  maxSelection,
102
102
  }: ReferenceSelectionInnerProps<M>) {
103
103
 
104
+ const authController = useAuthController();
104
105
  const sideDialogContext = useSideDialogContext();
105
106
  const sideEntityController = useSideEntityController();
106
107
  const navigation = useNavigationController();
107
108
  const analyticsController = useAnalyticsController();
108
109
  const customizationController = useCustomizationController();
109
110
 
110
- const fullPath = navigation.resolveAliasesFrom(pathInput);
111
+ const fullPath = navigation.resolveIdsFrom(pathInput);
111
112
 
112
113
  const dataSource = useDataSource(collection);
113
114
 
@@ -233,7 +234,9 @@ export function ReferenceSelectionTable<M extends Record<string, any>>(
233
234
  selectionEnabled={multiselect}
234
235
  hideId={collection?.hideIdFromCollection}
235
236
  fullPath={fullPath}
236
- selectionController={selectionController}/>;
237
+ selectionController={selectionController}
238
+ openEntityMode={"side_panel"}
239
+ />;
237
240
 
238
241
  };
239
242
 
@@ -251,16 +254,18 @@ export function ReferenceSelectionTable<M extends Record<string, any>>(
251
254
  collection: collection,
252
255
  path: fullPath,
253
256
  values: {},
254
- propertyConfigs: customizationController.propertyConfigs
257
+ propertyConfigs: customizationController.propertyConfigs,
258
+ authController
255
259
  }), [collection, customizationController.propertyConfigs, fullPath]);
256
260
 
257
261
  const displayedColumnIds = useColumnIds(resolvedCollection, false);
258
262
 
259
- const tableController = useDataSourceEntityCollectionTableController<M>({
263
+ const tableController = useDataSourceTableController<M>({
260
264
  fullPath,
261
265
  collection,
262
266
  entitiesDisplayedFirst,
263
- forceFilter
267
+ forceFilter,
268
+ updateUrl: false,
264
269
  });
265
270
 
266
271
  const {
@@ -289,12 +294,14 @@ export function ReferenceSelectionTable<M extends Record<string, any>>(
289
294
  tableController={tableController}
290
295
  enablePopupIcon={false}
291
296
  tableRowActionsBuilder={tableRowActionsBuilder}
297
+ openEntityMode={"side_panel"}
292
298
  title={<Typography variant={"subtitle2"} className={"flex flex-row gap-2"}>
293
299
  <IconForView
294
300
  size={"small"}
295
301
  collectionOrView={collection}
296
302
  className={"text-surface-300 dark:text-surface-600"}/>
297
- {collection.singularName ? `Select ${collection.singularName}` : `Select from ${collection.name}`}
303
+ {collection.singularName ? `Select ${collection.singularName}` : `Select
304
+ from ${collection.name}`}
298
305
  </Typography>}
299
306
  defaultSize={collection.defaultSize}
300
307
  properties={resolvedCollection.properties}
@@ -1,5 +1,4 @@
1
1
  import React, { useCallback, useEffect, useRef } from "react";
2
- import equal from "react-fast-compare";
3
2
  import {
4
3
  CollectionSize,
5
4
  Entity,
@@ -60,7 +59,7 @@ export type SelectableTableProps<M extends Record<string, any>> = {
60
59
 
61
60
  /**
62
61
  * Controller holding the logic for the table
63
- * {@link useDataSourceEntityCollectionTableController}
62
+ * {@link useDataSourceTableController}
64
63
  * {@link EntityTableController}
65
64
  */
66
65
  tableController: EntityTableController<M>;
@@ -77,6 +76,18 @@ export type SelectableTableProps<M extends Record<string, any>> = {
77
76
 
78
77
  size?: CollectionSize;
79
78
 
79
+ initialScroll?: number;
80
+
81
+ /**
82
+ * Callback when the table is scrolled
83
+ * @param props
84
+ */
85
+ onScroll?: (props: {
86
+ scrollDirection: "forward" | "backward",
87
+ scrollOffset: number,
88
+ scrollUpdateWasRequested: boolean
89
+ }) => void;
90
+
80
91
  emptyComponent?: React.ReactNode;
81
92
 
82
93
  endAdornment?: React.ReactNode;
@@ -101,7 +112,7 @@ export type SelectableTableProps<M extends Record<string, any>> = {
101
112
  *
102
113
  * The data displayed in the table is managed by a {@link EntityTableController}.
103
114
  * You can build the default, bound to a path in the datasource, by using the hook
104
- * {@link useDataSourceEntityCollectionTableController}
115
+ * {@link useDataSourceTableController}
105
116
  *
106
117
  * @see EntityCollectionTableProps
107
118
  * @see EntityCollectionView
@@ -136,6 +147,8 @@ export const SelectableTable = React.memo<SelectableTableProps<any>>(
136
147
  setPopupCell
137
148
  },
138
149
  filterable = true,
150
+ onScroll,
151
+ initialScroll,
139
152
  emptyComponent,
140
153
  columns,
141
154
  forceFilter,
@@ -229,6 +242,8 @@ export const SelectableTable = React.memo<SelectableTableProps<any>>(
229
242
  sortBy={sortBy}
230
243
  onSortByUpdate={setSortBy as ((sortBy?: [string, "asc" | "desc"]) => void)}
231
244
  hoverRow={hoverRow}
245
+ initialScroll={initialScroll}
246
+ onScroll={onScroll}
232
247
  checkFilterCombination={checkFilterCombination}
233
248
  createFilterField={filterable ? createFilterField : undefined}
234
249
  rowClassName={useCallback((entity: Entity<M>) => {
@@ -35,12 +35,10 @@ const operationLabels = {
35
35
  const multipleSelectOperations = ["array-contains-any", "in", "not-in"];
36
36
 
37
37
  export function ReferenceFilterField({
38
- name,
39
38
  value,
40
39
  setValue,
41
40
  isArray,
42
41
  path,
43
- title,
44
42
  includeId = true,
45
43
  previewProperties,
46
44
  setHidden
@@ -50,9 +48,11 @@ export function ReferenceFilterField({
50
48
  ? ["array-contains"]
51
49
  : ["==", "!=", ">", "<", ">=", "<="];
52
50
 
53
- isArray
54
- ? possibleOperations.push("array-contains-any")
55
- : possibleOperations.push("in", "not-in");
51
+ if (isArray) {
52
+ possibleOperations.push("array-contains-any");
53
+ } else {
54
+ possibleOperations.push("in", "not-in");
55
+ }
56
56
 
57
57
  const [fieldOperation, fieldValue] = value || [possibleOperations[0], undefined];
58
58
  const [operation, setOperation] = useState<VirtualTableWhereFilterOp>(fieldOperation);
@@ -144,7 +144,7 @@ export function ReferenceFilterField({
144
144
 
145
145
  return (
146
146
 
147
- <div className="flex w-[440px] flex-row">
147
+ <div className="flex w-[480px] flex-row">
148
148
  <div className="w-[140px]">
149
149
  <Select value={operation}
150
150
  size={"large"}
@@ -161,7 +161,7 @@ export function ReferenceFilterField({
161
161
  </Select>
162
162
  </div>
163
163
 
164
- <div className="flex-grow ml-2 h-full gap-2 flex flex-col">
164
+ <div className="flex-grow ml-2 h-full gap-2 flex flex-col w-[340px]">
165
165
 
166
166
  {internalValue && Array.isArray(internalValue) && <div>
167
167
  {internalValue.map((ref, index) => buildEntry(ref))}
@@ -0,0 +1,42 @@
1
+ import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Typography } from "@firecms/ui";
2
+
3
+ export interface UnsavedChangesDialogProps {
4
+ open: boolean;
5
+ body?: React.ReactNode;
6
+ title?: string;
7
+ handleOk: () => void;
8
+ handleCancel: () => void;
9
+ }
10
+
11
+ export function UnsavedChangesDialog({
12
+ open,
13
+ handleOk,
14
+ handleCancel,
15
+ body,
16
+ title
17
+ }: UnsavedChangesDialogProps) {
18
+
19
+ return (
20
+ <Dialog
21
+ onEscapeKeyDown={() => {
22
+ handleCancel();
23
+ }}
24
+ open={open}
25
+ >
26
+ <DialogTitle variant={"h6"}>{title}</DialogTitle>
27
+ <DialogContent>
28
+
29
+ {body}
30
+
31
+ <Typography>
32
+ Are you sure you want to leave this page?
33
+ </Typography>
34
+
35
+ </DialogContent>
36
+ <DialogActions>
37
+ <Button variant="text" onClick={handleCancel} autoFocus> Cancel </Button>
38
+ <Button onClick={handleOk}> Ok </Button>
39
+ </DialogActions>
40
+ </Dialog>
41
+ );
42
+ }
@@ -20,6 +20,7 @@ import { VirtualTableHeaderRow } from "./VirtualTableHeaderRow";
20
20
  import { VirtualTableRow } from "./VirtualTableRow";
21
21
  import { VirtualTableCell } from "./VirtualTableCell";
22
22
  import { AssignmentIcon, CenteredView, cls, Typography } from "@firecms/ui";
23
+ import { useDebounceCallback } from "../common/useDebouncedCallback";
23
24
 
24
25
  const VirtualListContext = createContext<VirtualTableContextProps<any>>({} as any);
25
26
  VirtualListContext.displayName = "VirtualListContext";
@@ -103,6 +104,7 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
103
104
  error,
104
105
  emptyComponent,
105
106
  onSortByUpdate,
107
+ onScroll: onScrollProp,
106
108
  loading,
107
109
  cellRenderer,
108
110
  hoverRow,
@@ -112,6 +114,7 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
112
114
  className,
113
115
  endAdornment,
114
116
  AddColumnComponent,
117
+ initialScroll = 0,
115
118
  debug
116
119
  }: VirtualTableProps<T>) {
117
120
 
@@ -123,11 +126,48 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
123
126
  const tableRef = useRef<HTMLDivElement>(null);
124
127
  const endReachCallbackThreshold = useRef<number>(0);
125
128
 
129
+ const debouncedScroll = useDebounceCallback(onScrollProp, 200);
130
+
131
+ // Set initial scroll position
132
+ useEffect(() => {
133
+ if (tableRef.current && initialScroll) {
134
+ tableRef.current.scrollTo(0, initialScroll);
135
+ }
136
+ }, [tableRef, initialScroll]);
137
+
126
138
  useEffect(() => {
127
139
  setColumns(columnsProp);
128
140
  }, [columnsProp]);
129
141
 
130
- const [measureRef, bounds] = useMeasure();
142
+ const [_, setForceUpdate] = useState(false);
143
+ useEffect(() => {
144
+ // Create a ResizeObserver to detect size changes more aggressively
145
+ if (tableRef.current) {
146
+ const resizeObserver = new ResizeObserver(() => {
147
+ // Force a re-render when size changes
148
+ setForceUpdate(prev => !prev);
149
+ });
150
+
151
+ resizeObserver.observe(tableRef.current);
152
+
153
+ return () => {
154
+ if (tableRef.current) {
155
+ resizeObserver.unobserve(tableRef.current);
156
+ }
157
+ resizeObserver.disconnect();
158
+ };
159
+ }
160
+ return () => {
161
+ }
162
+ }, [tableRef]);
163
+
164
+ const [measureRef, bounds] = useMeasure({
165
+ debounce: 50,
166
+ polyfill: ResizeObserver,
167
+ scroll: true,
168
+ // This is important for handling zooming in react-flow
169
+ offsetSize: true
170
+ });
131
171
 
132
172
  const onColumnResizeInternal = useCallback((params: OnVirtualTableColumnResizeParams) => {
133
173
  if (debug)
@@ -158,7 +198,6 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
158
198
  console.log("scrollToTop");
159
199
  endReachCallbackThreshold.current = 0;
160
200
  if (tableRef.current) {
161
- // scrollRef.current = [scrollRef.current[0], 0];
162
201
  tableRef.current.scrollTo(tableRef.current?.scrollLeft, 0);
163
202
  }
164
203
  }, []);
@@ -222,6 +261,13 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
222
261
  scrollOffset,
223
262
  scrollUpdateWasRequested
224
263
  });
264
+ if (onScrollProp) {
265
+ debouncedScroll({
266
+ scrollDirection,
267
+ scrollOffset,
268
+ scrollUpdateWasRequested
269
+ })
270
+ }
225
271
  if (!scrollUpdateWasRequested && (scrollOffset >= maxScroll - endOffset))
226
272
  onEndReachedInternal(scrollOffset);
227
273
  }, [maxScroll, onEndReachedInternal]);
@@ -294,7 +340,6 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
294
340
  if (debug)
295
341
  console.log("VirtualTable render", virtualListController);
296
342
 
297
- // useTraceUpdate(virtualListController);
298
343
  return (
299
344
  <div
300
345
  ref={measureRef}
@@ -82,6 +82,16 @@ export interface VirtualTableProps<T extends Record<string, any>> {
82
82
  */
83
83
  onFilterUpdate?: (filter?: VirtualTableFilterValues<any> | undefined) => void;
84
84
 
85
+ /**
86
+ * Callback when the table is scrolled
87
+ * @param props
88
+ */
89
+ onScroll?: (props: {
90
+ scrollDirection: "forward" | "backward",
91
+ scrollOffset: number,
92
+ scrollUpdateWasRequested: boolean
93
+ }) => void;
94
+
85
95
  /**
86
96
  * Default sort applied to this collection
87
97
  */
@@ -147,6 +157,11 @@ export interface VirtualTableProps<T extends Record<string, any>> {
147
157
  */
148
158
  AddColumnComponent?: React.ComponentType;
149
159
 
160
+ /**
161
+ * Initial scroll position
162
+ */
163
+ initialScroll?: number;
164
+
150
165
  /**
151
166
  * Debug mode
152
167
  */
@@ -66,7 +66,7 @@ export function VirtualTableInput(props: {
66
66
  width: "100%",
67
67
  color: "unset",
68
68
  fontWeight: "unset",
69
- lineHeight: "unset",
69
+ lineHeight: 1.7142857,
70
70
  fontSize: "unset",
71
71
  fontFamily: "unset",
72
72
  background: "unset",
@@ -1,10 +1,12 @@
1
- import { ArchiveIcon, DeleteIcon, EditIcon, FileCopyIcon, OpenInNewIcon } from "@firecms/ui";
1
+ import { DeleteIcon, EditIcon, FileCopyIcon } from "@firecms/ui";
2
2
  import { EntityAction } from "../../types";
3
3
  import { DeleteEntityDialog } from "../DeleteEntityDialog";
4
4
  import { addRecentId } from "../EntityCollectionView/utils";
5
+ import { navigateToEntity, resolveDefaultSelectedView } from "../../util";
5
6
 
6
7
  export const editEntityAction: EntityAction = {
7
8
  icon: <EditIcon/>,
9
+ key: "edit",
8
10
  name: "Edit",
9
11
  collapsed: false,
10
12
  onClick({
@@ -14,23 +16,40 @@ export const editEntityAction: EntityAction = {
14
16
  context,
15
17
  highlightEntity,
16
18
  unhighlightEntity,
19
+ openEntityMode
17
20
  }): Promise<void> {
21
+
18
22
  highlightEntity?.(entity);
23
+
19
24
  context.analyticsController?.onAnalyticsEvent?.("entity_click", {
20
25
  path: entity.path,
21
26
  entityId: entity.id
22
27
  });
28
+
23
29
  if (collection) {
24
30
  addRecentId(collection.id, entity.id);
25
31
  }
26
- const path = collection?.collectionGroup ? entity.path : (fullPath ?? entity.path);
27
- context.sideEntityController.open({
32
+
33
+ const path = collection?.collectionGroup ? collection.id : (fullPath ?? collection?.id ?? entity.path);
34
+ const defaultSelectedView = resolveDefaultSelectedView(
35
+ collection ? collection.defaultSelectedView : undefined,
36
+ {
37
+ status: "existing",
38
+ entityId: entity.id,
39
+ }
40
+ );
41
+ navigateToEntity({
42
+ openEntityMode,
43
+ collection,
28
44
  entityId: entity.id,
29
45
  path,
30
- collection,
31
- updateUrl: true,
46
+ fullIdPath: path,
47
+ sideEntityController: context.sideEntityController,
32
48
  onClose: () => unhighlightEntity?.(entity),
49
+ navigation: context.navigation,
50
+ selectedTab: defaultSelectedView
33
51
  });
52
+
34
53
  return Promise.resolve(undefined);
35
54
  }
36
55
  }
@@ -38,55 +57,35 @@ export const editEntityAction: EntityAction = {
38
57
  export const copyEntityAction: EntityAction = {
39
58
  icon: <FileCopyIcon/>,
40
59
  name: "Copy",
60
+ key: "copy",
41
61
  onClick({
42
62
  entity,
43
63
  collection,
44
64
  context,
65
+ fullPath,
45
66
  highlightEntity,
46
67
  unhighlightEntity,
68
+ openEntityMode
47
69
  }): Promise<void> {
48
70
  highlightEntity?.(entity);
49
71
  context.analyticsController?.onAnalyticsEvent?.("copy_entity_click", {
50
72
  path: entity.path,
51
73
  entityId: entity.id
52
74
  });
53
- context.sideEntityController.open({
75
+
76
+ const path = collection?.collectionGroup ? collection.id : (fullPath ?? collection?.id ?? entity.path);
77
+ navigateToEntity({
78
+ openEntityMode,
79
+ collection,
54
80
  entityId: entity.id,
55
- path: entity.path,
81
+ path,
82
+ fullIdPath: path,
56
83
  copy: true,
57
- collection,
58
- updateUrl: true,
84
+ sideEntityController: context.sideEntityController,
59
85
  onClose: () => unhighlightEntity?.(entity),
86
+ navigation: context.navigation
60
87
  });
61
- return Promise.resolve(undefined);
62
- }
63
- }
64
88
 
65
- export const archiveEntityAction: EntityAction = {
66
- icon: <ArchiveIcon/>,
67
- name: "Archive",
68
- onClick({
69
- entity,
70
- collection,
71
- context: {
72
- dataSource,
73
- }
74
- }): Promise<void> {
75
- // Add your code here
76
- return Promise.resolve(undefined);
77
- }
78
- }
79
-
80
- export const openWebsiteAction: EntityAction = {
81
- icon: <OpenInNewIcon/>,
82
- name: "See in website",
83
- onClick({
84
- entity,
85
- collection,
86
- context,
87
- }): Promise<void> {
88
- // open a new tab
89
- window.open(`https://example.com/${entity.id}`, "_blank");
90
89
  return Promise.resolve(undefined);
91
90
  }
92
91
  }
@@ -94,6 +93,7 @@ export const openWebsiteAction: EntityAction = {
94
93
  export const deleteEntityAction: EntityAction = {
95
94
  icon: <DeleteIcon/>,
96
95
  name: "Delete",
96
+ key: "delete",
97
97
  onClick({
98
98
  entity,
99
99
  fullPath,
@@ -1,6 +1,6 @@
1
1
  export * from "./types";
2
2
  export * from "./useDebouncedData";
3
3
  export * from "./useColumnsIds";
4
- export * from "./useDataSourceEntityCollectionTableController";
4
+ export * from "./useDataSourceTableController";
5
5
  export * from "./useTableSearchHelper";
6
6
  export * from "./default_entity_actions";
@@ -3,7 +3,7 @@ import { EntityCollection, ResolvedEntityCollection, ResolvedProperty } from "..
3
3
  import { getSubcollectionColumnId } from "../EntityCollectionTable/internal/common";
4
4
  import { PropertyColumnConfig } from "../EntityCollectionTable/EntityCollectionTableProps";
5
5
 
6
- const COLLECTION_GROUP_PARENT_ID = "collectionGroupParent";
6
+ export const COLLECTION_GROUP_PARENT_ID = "collectionGroupParent";
7
7
 
8
8
  export function useColumnIds<M extends Record<string, any>>(collection: ResolvedEntityCollection<M>, includeSubcollections: boolean): PropertyColumnConfig[] {
9
9
  return useMemo(() => {