@firecms/core 3.0.0-beta.12 → 3.0.0-beta.14

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 (120) hide show
  1. package/dist/app/Scaffold.d.ts +4 -0
  2. package/dist/components/ArrayContainer.d.ts +13 -11
  3. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +4 -0
  4. package/dist/components/EntityJsonPreview.d.ts +3 -0
  5. package/dist/components/EntityPreview.d.ts +4 -2
  6. package/dist/components/SelectableTable/SelectableTable.d.ts +1 -1
  7. package/dist/components/VirtualTable/VirtualTableProps.d.ts +0 -4
  8. package/dist/components/index.d.ts +1 -0
  9. package/dist/core/DefaultAppBar.d.ts +8 -2
  10. package/dist/core/EntityEditView.d.ts +8 -1
  11. package/dist/core/FireCMS.d.ts +2 -2
  12. package/dist/form/EntityForm.d.ts +5 -1
  13. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  14. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  15. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +3 -9
  16. package/dist/hooks/data/save.d.ts +1 -1
  17. package/dist/hooks/useBuildNavigationController.d.ts +2 -9
  18. package/dist/index.es.js +9251 -8721
  19. package/dist/index.es.js.map +1 -1
  20. package/dist/index.umd.js +16686 -16160
  21. package/dist/index.umd.js.map +1 -1
  22. package/dist/internal/useBuildDataSource.d.ts +3 -2
  23. package/dist/internal/useBuildSideEntityController.d.ts +3 -3
  24. package/dist/types/collections.d.ts +26 -2
  25. package/dist/types/fields.d.ts +4 -1
  26. package/dist/types/firecms.d.ts +3 -2
  27. package/dist/types/navigation.d.ts +9 -0
  28. package/dist/types/plugins.d.ts +13 -0
  29. package/dist/types/properties.d.ts +22 -1
  30. package/dist/types/side_entity_controller.d.ts +4 -0
  31. package/dist/util/callbacks.d.ts +2 -0
  32. package/dist/util/createFormexStub.d.ts +2 -0
  33. package/dist/util/index.d.ts +1 -0
  34. package/dist/util/navigation_utils.d.ts +2 -1
  35. package/dist/util/objects.d.ts +1 -1
  36. package/dist/util/property_utils.d.ts +2 -2
  37. package/dist/util/references.d.ts +2 -2
  38. package/dist/util/resolutions.d.ts +11 -6
  39. package/package.json +9 -6
  40. package/src/app/Scaffold.tsx +13 -3
  41. package/src/components/ArrayContainer.tsx +414 -282
  42. package/src/components/ClearFilterSortButton.tsx +1 -1
  43. package/src/components/ConfirmationDialog.tsx +9 -9
  44. package/src/components/DeleteEntityDialog.tsx +4 -2
  45. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +8 -6
  46. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +1 -1
  47. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +1 -1
  48. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +13 -2
  49. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +58 -29
  50. package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +9 -9
  51. package/src/components/EntityCollectionView/EntityCollectionView.tsx +26 -6
  52. package/src/components/EntityJsonPreview.tsx +66 -0
  53. package/src/components/EntityPreview.tsx +27 -16
  54. package/src/components/EntityView.tsx +4 -1
  55. package/src/components/ErrorView.tsx +1 -1
  56. package/src/components/HomePage/DefaultHomePage.tsx +2 -1
  57. package/src/components/HomePage/NavigationCardBinding.tsx +3 -1
  58. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +3 -1
  59. package/src/components/SelectableTable/SelectableTable.tsx +140 -143
  60. package/src/components/VirtualTable/VirtualTable.tsx +37 -31
  61. package/src/components/VirtualTable/VirtualTableProps.tsx +0 -5
  62. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +0 -1
  63. package/src/components/common/default_entity_actions.tsx +15 -4
  64. package/src/components/index.tsx +2 -0
  65. package/src/core/DefaultAppBar.tsx +17 -5
  66. package/src/core/EntityEditView.tsx +135 -47
  67. package/src/core/EntitySidePanel.tsx +15 -20
  68. package/src/core/FireCMS.tsx +19 -12
  69. package/src/form/EntityForm.tsx +32 -24
  70. package/src/form/PropertyFieldBinding.tsx +8 -6
  71. package/src/form/components/CustomIdField.tsx +3 -1
  72. package/src/form/components/LabelWithIcon.tsx +1 -1
  73. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +4 -1
  74. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +4 -2
  75. package/src/form/field_bindings/BlockFieldBinding.tsx +1 -1
  76. package/src/form/field_bindings/KeyValueFieldBinding.tsx +1 -1
  77. package/src/form/field_bindings/MapFieldBinding.tsx +5 -4
  78. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +6 -2
  79. package/src/form/field_bindings/MultiSelectFieldBinding.tsx +3 -3
  80. package/src/form/field_bindings/RepeatFieldBinding.tsx +9 -2
  81. package/src/form/field_bindings/SelectFieldBinding.tsx +3 -2
  82. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +227 -156
  83. package/src/hooks/data/save.ts +24 -35
  84. package/src/hooks/useBuildNavigationController.tsx +42 -17
  85. package/src/hooks/useFireCMSContext.tsx +0 -30
  86. package/src/internal/useBuildDataSource.ts +9 -5
  87. package/src/internal/useBuildSideEntityController.tsx +26 -20
  88. package/src/preview/PropertyPreview.tsx +4 -2
  89. package/src/preview/components/ImagePreview.tsx +2 -2
  90. package/src/preview/components/ReferencePreview.tsx +1 -1
  91. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +5 -4
  92. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +4 -3
  93. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +4 -2
  94. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +4 -3
  95. package/src/preview/property_previews/ArrayOneOfPreview.tsx +4 -2
  96. package/src/preview/property_previews/ArrayPropertyPreview.tsx +4 -2
  97. package/src/preview/property_previews/MapPropertyPreview.tsx +1 -1
  98. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +1 -1
  99. package/src/preview/property_previews/StringPropertyPreview.tsx +1 -1
  100. package/src/routes/FireCMSRoute.tsx +15 -4
  101. package/src/types/collections.ts +31 -2
  102. package/src/types/fields.tsx +5 -1
  103. package/src/types/firecms.tsx +3 -3
  104. package/src/types/navigation.ts +11 -0
  105. package/src/types/plugins.tsx +17 -0
  106. package/src/types/properties.ts +27 -1
  107. package/src/types/side_entity_controller.tsx +5 -0
  108. package/src/util/callbacks.ts +119 -0
  109. package/src/util/createFormexStub.tsx +62 -0
  110. package/src/util/index.ts +1 -0
  111. package/src/util/join_collections.ts +3 -1
  112. package/src/util/navigation_from_path.ts +5 -1
  113. package/src/util/navigation_utils.ts +84 -20
  114. package/src/util/objects.ts +54 -17
  115. package/src/util/property_utils.tsx +7 -3
  116. package/src/util/references.ts +8 -6
  117. package/src/util/resolutions.ts +17 -9
  118. package/src/util/useStorageUploadController.tsx +21 -2
  119. package/dist/components/EntityCollectionTable/internal/popup_field/ElementResizeListener.d.ts +0 -5
  120. package/src/components/EntityCollectionTable/internal/popup_field/ElementResizeListener.tsx +0 -59
@@ -9,6 +9,7 @@ import {
9
9
  EntityCollection,
10
10
  EntityCollectionsBuilder,
11
11
  EntityReference,
12
+ FireCMSPlugin,
12
13
  NavigationBlocker,
13
14
  NavigationController,
14
15
  PermissionsBuilder,
@@ -43,15 +44,7 @@ export type BuildNavigationContextProps<EC extends EntityCollection, USER extend
43
44
  viewsOrder?: string[];
44
45
  userConfigPersistence?: UserConfigurationPersistence;
45
46
  dataSourceDelegate: DataSourceDelegate;
46
- /**
47
- * Use this method to inject collections to the CMS.
48
- * You receive the current collections as a parameter, and you can return
49
- * a new list of collections.
50
- * @see {@link joinCollectionLists}
51
- * @param collections
52
- */
53
- injectCollections?: (collections: EntityCollection[]) => EntityCollection[];
54
-
47
+ plugins?: FireCMSPlugin[];
55
48
  /**
56
49
  * If true, the navigation logic will not be updated until this flag is false
57
50
  */
@@ -68,9 +61,9 @@ export function useBuildNavigationController<EC extends EntityCollection, USER e
68
61
  views: viewsProp,
69
62
  adminViews: adminViewsProp,
70
63
  viewsOrder,
64
+ plugins,
71
65
  userConfigPersistence,
72
66
  dataSourceDelegate,
73
- injectCollections,
74
67
  disabled
75
68
  } = props;
76
69
 
@@ -203,7 +196,7 @@ export function useBuildNavigationController<EC extends EntityCollection, USER e
203
196
  try {
204
197
 
205
198
  const [resolvedCollections = [], resolvedViews, resolvedAdminViews = []] = await Promise.all([
206
- resolveCollections(collectionsProp, collectionPermissions, authController, dataSourceDelegate, injectCollections),
199
+ resolveCollections(collectionsProp, collectionPermissions, authController, dataSourceDelegate, plugins),
207
200
  resolveCMSViews(viewsProp, authController, dataSourceDelegate),
208
201
  resolveCMSViews(adminViewsProp, authController, dataSourceDelegate)
209
202
  ]
@@ -250,8 +243,7 @@ export function useBuildNavigationController<EC extends EntityCollection, USER e
250
243
  disabled,
251
244
  viewsProp,
252
245
  adminViewsProp,
253
- computeTopNavigation,
254
- injectCollections
246
+ computeTopNavigation
255
247
  ]);
256
248
 
257
249
  useEffect(() => {
@@ -291,6 +283,16 @@ export function useBuildNavigationController<EC extends EntityCollection, USER e
291
283
 
292
284
  }, [userConfigPersistence]);
293
285
 
286
+ const getCollectionById = useCallback((id: string): EC | undefined => {
287
+ const collections = collectionsRef.current;
288
+ if (collections === undefined)
289
+ throw Error("getCollectionById: Collections have not been initialised yet");
290
+ const collection: EntityCollection | undefined = collections.find(c => c.id === id);
291
+ if (!collection)
292
+ return undefined;
293
+ return collection as EC;
294
+ }, []);
295
+
294
296
  const getCollectionFromPaths = useCallback(<EC extends EntityCollection>(pathSegments: string[]): EC | undefined => {
295
297
 
296
298
  const collections = collectionsRef.current;
@@ -398,6 +400,7 @@ export function useBuildNavigationController<EC extends EntityCollection, USER e
398
400
  baseCollectionPath,
399
401
  initialised,
400
402
  getCollection,
403
+ getCollectionById,
401
404
  getCollectionFromPaths,
402
405
  getCollectionFromIds,
403
406
  isUrlCollectionPath,
@@ -410,6 +413,7 @@ export function useBuildNavigationController<EC extends EntityCollection, USER e
410
413
  getParentCollectionIds,
411
414
  convertIdsToPaths,
412
415
  navigate,
416
+ plugins
413
417
  };
414
418
  }
415
419
 
@@ -436,11 +440,24 @@ function filterOutNotAllowedCollections(resolvedCollections: EntityCollection[],
436
440
  });
437
441
  }
438
442
 
443
+ function applyPluginModifyCollection(resolvedCollections: EntityCollection[], modifyCollection: (collection: EntityCollection) => EntityCollection) {
444
+ return resolvedCollections.map((collection: EntityCollection): EntityCollection => {
445
+ const modifiedCollection = modifyCollection(collection);
446
+ if (modifiedCollection.subcollections) {
447
+ return {
448
+ ...modifiedCollection,
449
+ subcollections: applyPluginModifyCollection(modifiedCollection.subcollections, modifyCollection)
450
+ } satisfies EntityCollection;
451
+ }
452
+ return modifiedCollection;
453
+ });
454
+ }
455
+
439
456
  async function resolveCollections(collections: undefined | EntityCollection[] | EntityCollectionsBuilder<any>,
440
457
  collectionPermissions: PermissionsBuilder | undefined,
441
458
  authController: AuthController,
442
459
  dataSource: DataSourceDelegate,
443
- injectCollections?: (collections: EntityCollection[]) => EntityCollection[]): Promise<EntityCollection[]> {
460
+ plugins: FireCMSPlugin[] | undefined): Promise<EntityCollection[]> {
444
461
  let resolvedCollections: EntityCollection[] = [];
445
462
  if (typeof collections === "function") {
446
463
  resolvedCollections = await collections({
@@ -452,8 +469,16 @@ async function resolveCollections(collections: undefined | EntityCollection[] |
452
469
  resolvedCollections = collections;
453
470
  }
454
471
 
455
- if (injectCollections) {
456
- resolvedCollections = injectCollections(resolvedCollections ?? []);
472
+ if (plugins) {
473
+ for (const plugin of plugins) {
474
+ if (plugin.collection?.modifyCollection) {
475
+ resolvedCollections = applyPluginModifyCollection(resolvedCollections, plugin.collection.modifyCollection);
476
+ }
477
+
478
+ if (plugin.collection?.injectCollections) {
479
+ resolvedCollections = plugin.collection.injectCollections(resolvedCollections ?? []);
480
+ }
481
+ }
457
482
  }
458
483
 
459
484
  resolvedCollections = applyPermissionsFunctionIfEmpty(resolvedCollections, collectionPermissions);
@@ -528,7 +553,7 @@ function useCustomBlocker(): NavigationBlocker {
528
553
  return shouldBlock;
529
554
  });
530
555
  } catch (e) {
531
- console.warn("Blocker not available, navigation will not be blocked");
556
+ // console.warn("Blocker not available, navigation will not be blocked");
532
557
  }
533
558
 
534
559
  const updateBlockListener = (path: string, block: boolean, basePath?: string) => {
@@ -67,33 +67,3 @@ export const useFireCMSContext = <USER extends User = User, AuthControllerType e
67
67
 
68
68
  return fireCMSContextRef.current;
69
69
  }
70
-
71
- // export const useFireCMSContext = <USER extends User = User, AuthControllerType extends AuthController<USER> = AuthController<USER>>(): FireCMSContext<USER, AuthControllerType> => {
72
- //
73
- // const authController = useAuthController<USER, AuthControllerType>();
74
- // const sideDialogsController = useSideDialogsController();
75
- // const sideEntityController = useSideEntityController();
76
- // const navigation = useNavigationController();
77
- // const dataSource = useDataSource();
78
- // const storageSource = useStorageSource();
79
- // const snackbarController = useSnackbarController();
80
- // const userConfigPersistence = useUserConfigurationPersistence();
81
- // const dialogsController = useDialogsController();
82
- // const customizationController = useCustomizationController();
83
- // const analyticsController = useAnalyticsController();
84
- //
85
- // return {
86
- // authController,
87
- // sideDialogsController,
88
- // sideEntityController,
89
- // navigation,
90
- // dataSource,
91
- // storageSource,
92
- // snackbarController,
93
- // userConfigPersistence,
94
- // dialogsController,
95
- // customizationController,
96
- // analyticsController
97
- // };
98
- //
99
- // };
@@ -1,5 +1,6 @@
1
1
  import { useCallback } from "react";
2
2
  import {
3
+ AuthController,
3
4
  DataSource,
4
5
  DataSourceDelegate,
5
6
  DeleteEntityProps,
@@ -27,11 +28,13 @@ import { resolveCollection, updateDateAutoValues } from "../util";
27
28
  export function useBuildDataSource({
28
29
  delegate,
29
30
  propertyConfigs,
30
- navigationController
31
+ navigationController,
32
+ authController
31
33
  }: {
32
34
  delegate: DataSourceDelegate,
33
35
  propertyConfigs?: Record<string, PropertyConfig>;
34
36
  navigationController: NavigationController;
37
+ authController: AuthController;
35
38
  }): DataSource {
36
39
 
37
40
  return {
@@ -209,26 +212,27 @@ export function useBuildDataSource({
209
212
  collection,
210
213
  path,
211
214
  entityId,
212
- propertyConfigs: propertyConfigs
215
+ propertyConfigs: propertyConfigs,
216
+ authController
213
217
  })
214
218
  : undefined;
215
219
 
216
220
  const properties: ResolvedProperties<M> | undefined = resolvedCollection?.properties;
217
221
 
218
- const firestoreValues = usedDelegate.cmsToDelegateModel(
222
+ const delegateValues = usedDelegate.cmsToDelegateModel(
219
223
  values,
220
224
  );
221
225
 
222
226
  const updatedValues: EntityValues<M> = properties
223
227
  ? updateDateAutoValues(
224
228
  {
225
- inputValues: firestoreValues,
229
+ inputValues: delegateValues,
226
230
  properties,
227
231
  status,
228
232
  timestampNowValue: usedDelegate.currentTime?.() ?? new Date(),
229
233
  setDateToMidnight: usedDelegate.setDateToMidnight
230
234
  })
231
- : firestoreValues;
235
+ : delegateValues;
232
236
 
233
237
  return usedDelegate.saveEntity({
234
238
  path,
@@ -1,5 +1,6 @@
1
1
  import { useCallback, useEffect, useRef } from "react";
2
2
  import {
3
+ AuthController,
3
4
  CustomizationController,
4
5
  EntityCollection,
5
6
  EntitySidePanelProps,
@@ -20,18 +21,19 @@ import {
20
21
  import { ADDITIONAL_TAB_WIDTH, CONTAINER_FULL_WIDTH, FORM_CONTAINER_WIDTH } from "./common";
21
22
  import { useCustomizationController, useLargeLayout } from "../hooks";
22
23
  import { EntitySidePanel } from "../core/EntitySidePanel";
24
+ import { JSON_TAB_VALUE } from "../core/EntityEditView";
23
25
 
24
26
  const NEW_URL_HASH = "new_side";
25
27
  const SIDE_URL_HASH = "side";
26
28
 
27
- export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean, customizationController: CustomizationController): string {
29
+ export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean, customizationController: CustomizationController, authController: AuthController): string {
28
30
  if (small) return CONTAINER_FULL_WIDTH;
29
31
 
30
32
  const {
31
33
  selectedSecondaryForm
32
34
  } = resolvedSelectedEntityView(props.collection?.entityViews, customizationController, props.selectedTab);
33
35
 
34
- const shouldUseSmallLayout = !props.selectedTab || Boolean(selectedSecondaryForm);
36
+ const shouldUseSmallLayout = !props.selectedTab || props.selectedTab === JSON_TAB_VALUE || props.selectedTab === "__history" || Boolean(selectedSecondaryForm);
35
37
 
36
38
  let resolvedWidth: string | undefined;
37
39
  if (props.width) {
@@ -48,21 +50,22 @@ export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: bool
48
50
  } else if (!props.collection) {
49
51
  return FORM_CONTAINER_WIDTH;
50
52
  } else {
51
- return calculateCollectionDesiredWidth(props.collection);
53
+ return calculateCollectionDesiredWidth(props.collection, authController);
52
54
  }
53
55
  }
54
56
  }
55
57
 
56
58
  const collectionViewWidthCache: { [key: string]: string } = {};
57
59
 
58
- function calculateCollectionDesiredWidth(collection: EntityCollection<any>): string {
60
+ function calculateCollectionDesiredWidth(collection: EntityCollection<any>, authController: AuthController): string {
59
61
  if (collectionViewWidthCache[collection.id]) {
60
62
  return collectionViewWidthCache[collection.id];
61
63
  }
62
64
  const resolvedCollection = resolveCollection({
63
65
  collection,
64
66
  path: "__ignored",
65
- ignoreMissingFields: true
67
+ ignoreMissingFields: true,
68
+ authController
66
69
  });
67
70
 
68
71
  let result = FORM_CONTAINER_WIDTH
@@ -97,7 +100,9 @@ function getNestedPropertiesDepth(property: ResolvedProperty, accumulator: numbe
97
100
  }
98
101
 
99
102
  export const useBuildSideEntityController = (navigation: NavigationController,
100
- sideDialogsController: SideDialogsController): SideEntityController => {
103
+ sideDialogsController: SideDialogsController,
104
+ authController: AuthController
105
+ ): SideEntityController => {
101
106
 
102
107
  const location = useLocation();
103
108
  const initialised = useRef<boolean>(false);
@@ -105,7 +110,6 @@ export const useBuildSideEntityController = (navigation: NavigationController,
105
110
 
106
111
  const smallLayout = !useLargeLayout();
107
112
 
108
- // only on initialisation, create panels from URL
109
113
  useEffect(() => {
110
114
 
111
115
  const newFlag = location.hash === `#${NEW_URL_HASH}`;
@@ -118,9 +122,9 @@ export const useBuildSideEntityController = (navigation: NavigationController,
118
122
  for (let i = 0; i < panelsFromUrl.length; i++) {
119
123
  const props = panelsFromUrl[i];
120
124
  if (i === 0)
121
- sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController));
125
+ sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController, authController));
122
126
  else
123
- sideDialogsController.open(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController))
127
+ sideDialogsController.open(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController, authController))
124
128
  }
125
129
  }
126
130
  initialised.current = true;
@@ -140,7 +144,7 @@ export const useBuildSideEntityController = (navigation: NavigationController,
140
144
  return;
141
145
  }
142
146
  const lastPanel = panelsFromUrl[panelsFromUrl.length - 1];
143
- const panelProps = propsToSidePanel(lastPanel, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController);
147
+ const panelProps = propsToSidePanel(lastPanel, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController, authController);
144
148
  const lastCurrentPanel = currentPanelKeys.length > 0 ? currentPanelKeys[currentPanelKeys.length - 1] : undefined;
145
149
  if (!lastCurrentPanel || lastCurrentPanel !== panelProps.key) {
146
150
  sideDialogsController.replace(panelProps);
@@ -153,7 +157,7 @@ export const useBuildSideEntityController = (navigation: NavigationController,
153
157
  useEffect(() => {
154
158
  const updatedSidePanels = sideDialogsController.sidePanels.map(sidePanelProps => {
155
159
  if (sidePanelProps.additional) {
156
- return propsToSidePanel(sidePanelProps.additional, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController);
160
+ return propsToSidePanel(sidePanelProps.additional, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController, authController);
157
161
  }
158
162
  return sidePanelProps;
159
163
  });
@@ -186,10 +190,11 @@ export const useBuildSideEntityController = (navigation: NavigationController,
186
190
  navigation.buildUrlCollectionPath,
187
191
  navigation.resolveIdsFrom,
188
192
  smallLayout,
189
- customizationController
193
+ customizationController,
194
+ authController
190
195
  ));
191
196
 
192
- }, [sideDialogsController, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout]);
197
+ }, [sideDialogsController, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, authController.user]);
193
198
 
194
199
  const replace = useCallback((props: EntitySidePanelProps<any>) => {
195
200
 
@@ -197,9 +202,9 @@ export const useBuildSideEntityController = (navigation: NavigationController,
197
202
  throw Error("If you want to copy an entity you need to provide an entityId");
198
203
  }
199
204
 
200
- sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController));
205
+ sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController, authController));
201
206
 
202
- }, [navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, sideDialogsController, smallLayout]);
207
+ }, [navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, sideDialogsController, smallLayout, authController.user]);
203
208
 
204
209
  return {
205
210
  close,
@@ -228,6 +233,7 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
228
233
  if (navigationEntry.type === "entity") {
229
234
  sidePanel = {
230
235
  path: navigationEntry.path,
236
+ // fullIdPath: navigationEntry.path,
231
237
  entityId: navigationEntry.entityId,
232
238
  copy: false,
233
239
  width: navigationEntry.parentCollection?.sideDialogWidth
@@ -249,6 +255,7 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
249
255
  if (newFlag) {
250
256
  sidePanel = {
251
257
  path: lastCollectionPath,
258
+ // fullIdPath: lastCollectionPath,
252
259
  copy: false
253
260
  }
254
261
  }
@@ -260,23 +267,22 @@ const propsToSidePanel = (props: EntitySidePanelProps,
260
267
  buildUrlCollectionPath: (path: string) => string,
261
268
  resolveIdsFrom: (pathWithAliases: string) => string,
262
269
  smallLayout: boolean,
263
- customizationController: CustomizationController): SideDialogPanelProps => {
270
+ customizationController: CustomizationController,
271
+ authController: AuthController
272
+ ): SideDialogPanelProps => {
264
273
 
265
274
  const collectionPath = removeInitialAndTrailingSlashes(props.path);
266
275
 
267
276
  const newPath = props.entityId
268
277
  ? buildUrlCollectionPath(`${collectionPath}/${props.entityId}${props.selectedTab ? "/" + props.selectedTab : ""}#${SIDE_URL_HASH}`)
269
278
  : buildUrlCollectionPath(`${collectionPath}#${NEW_URL_HASH}`);
270
- const resolvedPath = resolveIdsFrom(props.path);
271
279
 
272
280
  const resolvedPanelProps: EntitySidePanelProps<any> = {
273
281
  ...props,
274
- path: resolvedPath,
275
282
  formProps: props.formProps
276
283
  };
277
284
 
278
- const entityViewWidth = getEntityViewWidth(props, smallLayout, customizationController);
279
-
285
+ const entityViewWidth = getEntityViewWidth(props, smallLayout, customizationController, authController);
280
286
  return {
281
287
  key: `${props.path}/${props.entityId}`,
282
288
  component: <EntitySidePanel {...resolvedPanelProps}/>,
@@ -13,7 +13,7 @@ import {
13
13
  import { resolveProperty } from "../util";
14
14
 
15
15
  import { PropertyPreviewProps } from "./PropertyPreviewProps";
16
- import { useCustomizationController } from "../hooks";
16
+ import { useAuthController, useCustomizationController } from "../hooks";
17
17
  import { EmptyValue } from "./components/EmptyValue";
18
18
  import { UrlComponentPreview } from "./components/UrlComponentPreview";
19
19
  import { StorageThumbnail } from "./components/StorageThumbnail";
@@ -37,6 +37,7 @@ import { ErrorView } from "../components";
37
37
  */
38
38
  export const PropertyPreview = React.memo(function PropertyPreview<T extends CMSType>(props: PropertyPreviewProps<T>) {
39
39
 
40
+ const authController = useAuthController();
40
41
  const customizationController = useCustomizationController();
41
42
 
42
43
  let content: React.ReactNode | any;
@@ -53,7 +54,8 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
53
54
  const property = resolveProperty({
54
55
  propertyKey,
55
56
  propertyOrBuilder: inputProperty,
56
- propertyConfigs: customizationController.propertyConfigs
57
+ propertyConfigs: customizationController.propertyConfigs,
58
+ authController
57
59
  });
58
60
 
59
61
  if (property === null) {
@@ -62,7 +62,7 @@ export function ImagePreview({
62
62
  title="Copy url to clipboard" side={"bottom"}>
63
63
  <IconButton
64
64
  variant={"filled"}
65
- size={"small"}
65
+ size={"smallest"}
66
66
  onClick={(e) => {
67
67
  e.stopPropagation();
68
68
  e.preventDefault();
@@ -81,7 +81,7 @@ export function ImagePreview({
81
81
  href={url}
82
82
  rel="noopener noreferrer"
83
83
  target="_blank"
84
- size={"small"}
84
+ size={"smallest"}
85
85
  onClick={(e: any) => e.stopPropagation()}
86
86
  >
87
87
  <OpenInNewIcon className={"text-surface-700 dark:text-surface-300"}
@@ -141,7 +141,7 @@ function ReferencePreviewExisting<M extends Record<string, any> = any>({
141
141
  );
142
142
  }
143
143
  return <EntityPreview size={size}
144
- previewProperties={previewProperties}
144
+ previewKeys={previewProperties}
145
145
  disabled={disabled}
146
146
  entity={usedEntity}
147
147
  collection={collection}
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { ErrorBoundary } from "../../components";
3
- import { useCustomizationController } from "../../hooks";
3
+ import { useAuthController, useCustomizationController } from "../../hooks";
4
4
  import { PropertyPreviewProps } from "../PropertyPreviewProps";
5
5
  import { PropertyPreview } from "../PropertyPreview";
6
6
  import { resolveArrayProperty } from "../../util";
@@ -15,12 +15,13 @@ export function ArrayOfMapsPreview({
15
15
  size,
16
16
  // entity
17
17
  }: PropertyPreviewProps<Record<string, any>[]>) {
18
-
18
+ const authController = useAuthController();
19
19
  const customizationController = useCustomizationController();
20
20
  const property = resolveArrayProperty({
21
21
  propertyKey,
22
22
  property: inputProperty,
23
- propertyConfigs: customizationController.propertyConfigs
23
+ propertyConfigs: customizationController.propertyConfigs,
24
+ authController
24
25
  });
25
26
 
26
27
  if (Array.isArray(property?.of)) {
@@ -36,7 +37,7 @@ export function ArrayOfMapsPreview({
36
37
  throw Error(`You need to specify a 'properties' prop (or specify a custom field) in your map property ${propertyKey}`);
37
38
  }
38
39
  const values = value;
39
- const previewProperties: string[] | undefined = mapProperty.previewProperties;
40
+ const previewProperties: string[] | undefined = mapProperty.previewKeys;
40
41
 
41
42
  if (!values) return null;
42
43
 
@@ -1,6 +1,6 @@
1
1
  import { ResolvedReferenceProperty } from "../../types";
2
2
  import { resolveArrayProperty } from "../../util";
3
- import { useCustomizationController } from "../../hooks";
3
+ import { useAuthController, useCustomizationController } from "../../hooks";
4
4
  import { PreviewSize, PropertyPreviewProps } from "../PropertyPreviewProps";
5
5
  import { ReferencePreview } from "../components/ReferencePreview";
6
6
 
@@ -13,12 +13,13 @@ export function ArrayOfReferencesPreview({
13
13
  property: inputProperty,
14
14
  size
15
15
  }: PropertyPreviewProps<any[]>) {
16
-
16
+ const authController = useAuthController();
17
17
  const customizationController = useCustomizationController();
18
18
  const property = resolveArrayProperty({
19
19
  propertyKey,
20
20
  property: inputProperty,
21
- propertyConfigs: customizationController.propertyConfigs
21
+ propertyConfigs: customizationController.propertyConfigs,
22
+ authController
22
23
  });
23
24
 
24
25
  if (Array.isArray(property?.of)) {
@@ -3,7 +3,7 @@ import React from "react";
3
3
  import { resolveArrayProperty } from "../../util";
4
4
  import { ResolvedProperty } from "../../types";
5
5
 
6
- import { useCustomizationController } from "../../hooks";
6
+ import { useAuthController, useCustomizationController } from "../../hooks";
7
7
  import { PreviewSize, PropertyPreviewProps } from "../PropertyPreviewProps";
8
8
  import { PropertyPreview } from "../PropertyPreview";
9
9
  import { ErrorBoundary } from "../../components";
@@ -19,11 +19,13 @@ export function ArrayOfStorageComponentsPreview({
19
19
  size
20
20
  }: PropertyPreviewProps<any[]>) {
21
21
 
22
+ const authController = useAuthController();
22
23
  const customizationController = useCustomizationController();
23
24
  const property = resolveArrayProperty({
24
25
  propertyKey,
25
26
  property: inputProperty,
26
- propertyConfigs: customizationController.propertyConfigs
27
+ propertyConfigs: customizationController.propertyConfigs,
28
+ authController
27
29
  });
28
30
 
29
31
  if (Array.isArray(property.of)) {
@@ -3,7 +3,7 @@ import { ResolvedStringProperty } from "../../types";
3
3
 
4
4
  import { resolveArrayProperty } from "../../util";
5
5
  import { PropertyPreviewProps, StringPropertyPreview } from "../../preview";
6
- import { useCustomizationController } from "../../hooks";
6
+ import { useAuthController, useCustomizationController } from "../../hooks";
7
7
  import { ErrorBoundary } from "../../components";
8
8
 
9
9
  /**
@@ -16,12 +16,13 @@ export function ArrayOfStringsPreview({
16
16
  // entity,
17
17
  size
18
18
  }: PropertyPreviewProps<string[]>) {
19
-
19
+ const authController = useAuthController();
20
20
  const customizationController = useCustomizationController();
21
21
  const property = resolveArrayProperty({
22
22
  propertyKey,
23
23
  property: inputProperty,
24
- propertyConfigs: customizationController.propertyConfigs
24
+ propertyConfigs: customizationController.propertyConfigs,
25
+ authController
25
26
  });
26
27
 
27
28
  if (Array.isArray(property.of)) {
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import { resolveArrayProperty } from "../../util";
3
3
  import { ResolvedProperty } from "../../types";
4
- import { useCustomizationController } from "../../hooks";
4
+ import { useAuthController, useCustomizationController } from "../../hooks";
5
5
  import { PreviewSize, PropertyPreviewProps } from "../PropertyPreviewProps";
6
6
  import { PropertyPreview } from "../PropertyPreview";
7
7
  import { cls, defaultBorderMixin } from "@firecms/ui";
@@ -19,11 +19,13 @@ export function ArrayOneOfPreview({
19
19
  // entity
20
20
  }: PropertyPreviewProps<any[]>) {
21
21
 
22
+ const authController = useAuthController();
22
23
  const customizationController = useCustomizationController();
23
24
  const property = resolveArrayProperty({
24
25
  propertyKey,
25
26
  property: inputProperty,
26
- propertyConfigs: customizationController.propertyConfigs
27
+ propertyConfigs: customizationController.propertyConfigs,
28
+ authController
27
29
  });
28
30
 
29
31
  if (property?.dataType !== "array")
@@ -2,7 +2,7 @@ import React from "react";
2
2
 
3
3
  import { resolveArrayProperty } from "../../util";
4
4
  import { ResolvedProperty } from "../../types";
5
- import { useCustomizationController } from "../../hooks";
5
+ import { useAuthController, useCustomizationController } from "../../hooks";
6
6
  import { PreviewSize, PropertyPreviewProps } from "../PropertyPreviewProps";
7
7
  import { PropertyPreview } from "../PropertyPreview";
8
8
  import { cls, defaultBorderMixin } from "@firecms/ui";
@@ -19,11 +19,13 @@ export function ArrayPropertyPreview({
19
19
  size
20
20
  }: PropertyPreviewProps<any[]>) {
21
21
 
22
+ const authController = useAuthController();
22
23
  const customizationController = useCustomizationController();
23
24
  const property = resolveArrayProperty({
24
25
  propertyKey,
25
26
  property: inputProperty,
26
- propertyConfigs: customizationController.propertyConfigs
27
+ propertyConfigs: customizationController.propertyConfigs,
28
+ authController
27
29
  });
28
30
 
29
31
  if (!property.of) {
@@ -128,7 +128,7 @@ export function KeyValuePreview({ value }: { value: any }) {
128
128
  </div>
129
129
  <div
130
130
  className="flex-grow max-w-[75%]">
131
- {childValue && <Typography>
131
+ {childValue && typeof childValue !== "object" && <Typography>
132
132
  <ErrorBoundary>
133
133
  {childValue.toString()}
134
134
  </ErrorBoundary>
@@ -46,7 +46,7 @@ export function SkeletonPropertyComponent({
46
46
  content = <>{arrayProperty.of.map((p, i) => renderGenericArrayCell(p, i))} </>;
47
47
  } else {
48
48
  if (arrayProperty.of.dataType === "map" && arrayProperty.of.properties) {
49
- content = renderArrayOfMaps(arrayProperty.of.properties, size, arrayProperty.of.previewProperties);
49
+ content = renderArrayOfMaps(arrayProperty.of.properties, size, arrayProperty.of.previewKeys);
50
50
  } else if (arrayProperty.of.dataType === "string") {
51
51
  if (arrayProperty.of.enumValues) {
52
52
  content = renderArrayEnumTableCell();
@@ -45,7 +45,7 @@ export function StringPropertyPreview({
45
45
  if (!value) return <></>;
46
46
  const lines = value.split("\n");
47
47
  return value && value.includes("\n")
48
- ? <div className={cls("overflow-x-scroll", size === "small" ? "text-sm" : "")}>
48
+ ? <div className={cls("overflow-x-scroll overflow-hidden", size === "small" ? "text-sm" : "")}>
49
49
  {lines.map((str, index) =>
50
50
  <React.Fragment key={`string_preview_${index}`}>
51
51
  <span>{str}</span>