@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
@@ -1,4 +1,4 @@
1
- import { EntityCollection, EntitySidePanelProps, NavigationController, SideDialogsController, SideEntityController } from "../types";
2
- export declare function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean): string;
1
+ import { CustomizationController, EntityCollection, EntitySidePanelProps, NavigationController, SideDialogsController, SideEntityController } from "../types";
2
+ export declare function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean, customizationController: CustomizationController): string;
3
3
  export declare const useBuildSideEntityController: (navigation: NavigationController, sideDialogsController: SideDialogsController) => SideEntityController;
4
4
  export declare function buildSidePanelsFromUrl(path: string, collections: EntityCollection[], newFlag: boolean): EntitySidePanelProps<any>[];
@@ -1,14 +1,12 @@
1
- import React from "react";
1
+ /**
2
+ * Custom hook to handle navigation blocking when there are unsaved changes.
3
+ *
4
+ * @param when - Indicates whether to block navigation.
5
+ * @param onSuccess - Callback invoked when navigation is confirmed.
6
+ * @returns An object containing the state of navigation blocking and handlers.
7
+ */
2
8
  export declare function useNavigationUnsavedChangesDialog(when: boolean, onSuccess: () => void): {
3
9
  navigationWasBlocked: boolean;
4
10
  handleCancel: () => void;
5
11
  handleOk: () => void;
6
12
  };
7
- export interface UnsavedChangesDialogProps {
8
- open: boolean;
9
- body?: React.ReactNode;
10
- title?: string;
11
- handleOk: () => void;
12
- handleCancel: () => void;
13
- }
14
- export declare function UnsavedChangesDialog({ open, handleOk, handleCancel, body, title }: UnsavedChangesDialogProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,4 @@
1
+ import { CMSView } from "../types";
2
+ export declare function CustomCMSRoute({ cmsView }: {
3
+ cmsView: CMSView;
4
+ }): import("react").ReactNode;
@@ -0,0 +1 @@
1
+ export declare function FireCMSRoute(): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,3 @@
1
+ export declare function HomePageRoute({ children }: {
2
+ children: React.ReactNode;
3
+ }): import("react").ReactNode;
@@ -72,6 +72,10 @@ export interface EntityCollection<M extends Record<string, any> = any, USER exte
72
72
  * Set of properties that compose an entity
73
73
  */
74
74
  properties: PropertiesOrBuilders<M>;
75
+ /**
76
+ * Default preview properties displayed when this collection is referenced to.
77
+ */
78
+ previewProperties?: string[];
75
79
  /**
76
80
  * Title property of the entity. This is the property that will be used
77
81
  * as the title in entity related views and references.
@@ -79,11 +83,10 @@ export interface EntityCollection<M extends Record<string, any> = any, USER exte
79
83
  */
80
84
  titleProperty?: keyof M;
81
85
  /**
82
- * Can this collection be edited by the end user.
83
- * Defaults to `true`.
84
- * Keep in mind that you can also set this prop to individual properties.
86
+ * When editing an entity, you can choose to open the entity in a side dialog
87
+ * or in a full screen dialog. Defaults to `full_screen`.
85
88
  */
86
- editable?: boolean;
89
+ openEntityMode?: "side_panel" | "full_screen";
87
90
  /**
88
91
  * Order in which the properties are displayed.
89
92
  * If you are specifying your collection as code, the order is the same as the
@@ -105,7 +108,7 @@ export interface EntityCollection<M extends Record<string, any> = any, USER exte
105
108
  * `hidden` in the property definition,will be ignored.
106
109
  * `propertiesOrder` has precedence over `hidden`.
107
110
  */
108
- propertiesOrder?: (Extract<keyof M, string> | `subcollection:${string}`)[];
111
+ propertiesOrder?: (Extract<keyof M, string> | string | `subcollection:${string}` | "collectionGroupParent")[];
109
112
  /**
110
113
  * If enabled, content is loaded in batches. If `false` all entities in the
111
114
  * collection are loaded.
@@ -272,9 +275,18 @@ export interface EntityCollection<M extends Record<string, any> = any, USER exte
272
275
  */
273
276
  sideDialogWidth?: number | string;
274
277
  /**
275
- * Default preview properties displayed when this collection is referenced to.
278
+ * Can this collection configuration be edited by the end user.
279
+ * Defaults to `true`.
280
+ * Keep in mind that you can also set this prop to individual properties.
281
+ * This prop has only effect if you are using the collection editor.
276
282
  */
277
- previewProperties?: string[];
283
+ editable?: boolean;
284
+ /**
285
+ * If set to true, the default values of the properties will be applied
286
+ * to the entity every time the entity is updated (not only when created).
287
+ * Defaults to false.
288
+ */
289
+ alwaysApplyDefaultValues?: boolean;
278
290
  }
279
291
  /**
280
292
  * Parameter passed to the `Actions` prop in the collection configuration.
@@ -420,10 +432,12 @@ export type EntityCustomView<M extends Record<string, any> = any> = {
420
432
  */
421
433
  name: string;
422
434
  /**
423
- * If set to true, the actions of the entity will be included in the
424
- * bottom of the panel (save buttons, delete buttons, etc.)
435
+ * If set to true, the actions of the entity (save, discard,delete) will be
436
+ * included in the view. By default the actions are located in the right or bottom,
437
+ * based on the screen size. You can force the actions to be located at the bottom
438
+ * by setting this prop to "bottom".
425
439
  */
426
- includeActions?: boolean;
440
+ includeActions?: boolean | "bottom";
427
441
  /**
428
442
  * Builder for rendering the custom view
429
443
  */
@@ -485,6 +499,12 @@ export type EntityTableController<M extends Record<string, any> = any> = {
485
499
  clearFilter?: () => void;
486
500
  itemCount?: number;
487
501
  setItemCount?: (itemCount: number) => void;
502
+ initialScroll?: number;
503
+ onScroll?: (props: {
504
+ scrollDirection: "forward" | "backward";
505
+ scrollOffset: number;
506
+ scrollUpdateWasRequested: boolean;
507
+ }) => void;
488
508
  paginationEnabled?: boolean;
489
509
  pageSize?: number;
490
510
  checkFilterCombination?: (filterValues: FilterValues<any>, sortBy?: [string, "asc" | "desc"]) => boolean;
@@ -8,13 +8,13 @@ import { FireCMSContext } from "./firecms_context";
8
8
  export interface FetchEntityProps<M extends Record<string, any> = any> {
9
9
  path: string;
10
10
  entityId: string;
11
+ databaseId?: string;
11
12
  collection?: EntityCollection<M, any>;
12
13
  }
13
14
  /**
14
15
  * @group Datasource
15
16
  */
16
17
  export type ListenEntityProps<M extends Record<string, any> = any> = FetchEntityProps<M> & {
17
- databaseId?: string;
18
18
  onUpdate: (entity: Entity<M>) => void;
19
19
  onError?: (error: Error) => void;
20
20
  };
@@ -99,7 +99,7 @@ export interface DataSource {
99
99
  * @param entityId
100
100
  * @param collection
101
101
  */
102
- fetchEntity<M extends Record<string, any> = any>({ path, entityId, collection }: FetchEntityProps<M>): Promise<Entity<M> | undefined>;
102
+ fetchEntity<M extends Record<string, any> = any>({ path, entityId, databaseId, collection }: FetchEntityProps<M>): Promise<Entity<M> | undefined>;
103
103
  /**
104
104
  * Get realtime updates on one entity.
105
105
  * @param path
@@ -12,7 +12,7 @@ export interface DialogsController {
12
12
  * Open a dialog
13
13
  * @param props
14
14
  */
15
- open: (props: DialogControllerEntryProps) => {
15
+ open: <T extends object = object>(props: DialogControllerEntryProps<T>) => {
16
16
  closeDialog: () => void;
17
17
  };
18
18
  }
@@ -20,7 +20,7 @@ export interface DialogsController {
20
20
  * Props used to open a side dialog
21
21
  * @group Hooks and utilities
22
22
  */
23
- export interface DialogControllerEntryProps {
23
+ export interface DialogControllerEntryProps<T extends object = object> {
24
24
  key: string;
25
25
  /**
26
26
  * The component type that will be rendered
@@ -28,5 +28,9 @@ export interface DialogControllerEntryProps {
28
28
  Component: React.ComponentType<{
29
29
  open: boolean;
30
30
  closeDialog: () => void;
31
- }>;
31
+ } & T>;
32
+ /**
33
+ * Props to pass to the dialog component
34
+ */
35
+ props?: T;
32
36
  }
@@ -7,7 +7,7 @@ export type EntityStatus = "new" | "existing" | "copy";
7
7
  * Representation of an entity fetched from the datasource
8
8
  * @group Models
9
9
  */
10
- export interface Entity<M extends object> {
10
+ export interface Entity<M extends object = any> {
11
11
  /**
12
12
  * ID of the entity
13
13
  */
@@ -13,6 +13,15 @@ export type EntityAction<M extends object = any, USER extends User = User> = {
13
13
  * Title of the action
14
14
  */
15
15
  name: string;
16
+ /**
17
+ * Key of the action. You only need to provide this if you want to
18
+ * override the default actions.
19
+ * The default actions are:
20
+ * - edit
21
+ * - delete
22
+ * - copy
23
+ */
24
+ key?: string;
16
25
  /**
17
26
  * Icon of the action
18
27
  */
@@ -46,4 +55,5 @@ export type EntityActionClickProps<M extends object, USER extends User = User> =
46
55
  * If this actions is being called from a side dialog
47
56
  */
48
57
  sideEntityController?: SideEntityController;
58
+ openEntityMode: "side_panel" | "full_screen";
49
59
  };
@@ -1,6 +1,7 @@
1
1
  import { CMSType, Property, PropertyOrBuilder } from "./properties";
2
2
  import { ResolvedEntityCollection, ResolvedProperty } from "./resolved_entities";
3
3
  import { FormexController } from "@firecms/formex";
4
+ import { Entity } from "./entities";
4
5
  /**
5
6
  * When building a custom field you need to create a React component that takes
6
7
  * this interface as props.
@@ -67,7 +68,8 @@ export interface FieldProps<T extends CMSType = any, CustomProps = any, M extend
67
68
  */
68
69
  partOfArray?: boolean;
69
70
  /**
70
- * Should this field render with the minimal amount of UI elements
71
+ * Display the child properties directly, without being wrapped in an
72
+ * extendable panel. Note that this will also hide the title of this property.
71
73
  */
72
74
  minimalistView?: boolean;
73
75
  /**
@@ -131,6 +133,10 @@ export interface FormContext<M extends Record<string, any> = any> {
131
133
  * Path this entity is located at
132
134
  */
133
135
  path?: string;
136
+ status: "new" | "existing" | "copy";
137
+ entity?: Entity<M>;
138
+ savingError?: Error;
139
+ openEntityMode: "side_panel" | "full_screen";
134
140
  /**
135
141
  * This is the underlying formex controller that powers the form
136
142
  */
@@ -170,7 +176,8 @@ export interface PropertyFieldBindingProps<T extends CMSType, M extends Record<s
170
176
  */
171
177
  partOfArray?: boolean;
172
178
  /**
173
- * Is this field part of a block (oneOf array)
179
+ * Display the child properties directly, without being wrapped in an
180
+ * extendable panel. Note that this will also hide the title of this property.
174
181
  */
175
182
  minimalistView?: boolean;
176
183
  /**
@@ -4,6 +4,7 @@ import { EntityReference } from "./entities";
4
4
  /**
5
5
  * Controller that includes the resolved navigation and utility methods and
6
6
  * attributes.
7
+ * This controller holds the state of the navigation including the collections.
7
8
  * @group Models
8
9
  */
9
10
  export type NavigationController<EC extends EntityCollection = EntityCollection<any>> = {
@@ -57,11 +58,13 @@ export type NavigationController<EC extends EntityCollection = EntityCollection<
57
58
  */
58
59
  getCollectionFromPaths: (pathSegments: string[]) => EC | undefined;
59
60
  /**
60
- * Default path under the navigation routes of the CMS will be created
61
+ * Default path under the navigation routes of the CMS will be created.
62
+ * Defaults to '/'. You may want to change this `basepath` to 'admin' for example.
61
63
  */
62
64
  basePath: string;
63
65
  /**
64
- * Default path under the collection routes of the CMS will be created
66
+ * Default path under the collection routes of the CMS will be created.
67
+ * It defaults to '/c'
65
68
  */
66
69
  baseCollectionPath: string;
67
70
  /**
@@ -72,14 +75,6 @@ export type NavigationController<EC extends EntityCollection = EntityCollection<
72
75
  * @param cmsPath
73
76
  */
74
77
  urlPathToDataPath: (cmsPath: string) => string;
75
- /**
76
- * Convert a collection or entity path to a URL path
77
- * @param path
78
- */
79
- buildCMSUrlPath: (path: string) => string;
80
- buildUrlEditCollectionPath: (props: {
81
- path: string;
82
- }) => string;
83
78
  /**
84
79
  * Base url path for the home screen
85
80
  */
@@ -97,10 +92,11 @@ export type NavigationController<EC extends EntityCollection = EntityCollection<
97
92
  */
98
93
  buildUrlCollectionPath: (path: string) => string;
99
94
  /**
100
- * Turn a path with aliases into a resolved path
95
+ * Turn a path with collection ids into a resolved path.
96
+ * The ids (typically used in urls) will be replaced with relative paths (typically used in database paths)
101
97
  * @param pathWithAliases
102
98
  */
103
- resolveAliasesFrom: (pathWithAliases: string) => string;
99
+ resolveIdsFrom: (pathWithAliases: string) => string;
104
100
  /**
105
101
  * Call this method to recalculate the navigation
106
102
  */
@@ -120,6 +116,27 @@ export type NavigationController<EC extends EntityCollection = EntityCollection<
120
116
  * @param ids
121
117
  */
122
118
  convertIdsToPaths: (ids: string[]) => string[];
119
+ /**
120
+ * A function to navigate to a specified route or URL.
121
+ *
122
+ * @param {string} to - The target route or URL to navigate to.
123
+ * @param {NavigateOptions} [options] - Optional configuration settings for navigation, such as replace behavior or state data.
124
+ */
125
+ navigate: (to: string, options?: NavigateOptions) => void;
126
+ };
127
+ export interface NavigateOptions {
128
+ replace?: boolean;
129
+ state?: any;
130
+ preventScrollReset?: boolean;
131
+ relative?: "route" | "path";
132
+ flushSync?: boolean;
133
+ viewTransition?: boolean;
134
+ }
135
+ export type NavigationBlocker = {
136
+ updateBlockListener: (path: string, block: boolean, basePath?: string) => () => void;
137
+ isBlocked: (path: string) => boolean;
138
+ proceed?: () => void;
139
+ reset?: () => void;
123
140
  };
124
141
  /**
125
142
  * Custom additional views created by the developer, added to the main
@@ -162,6 +162,7 @@ export interface PluginFormActionProps<USER extends User = User, EC extends Enti
162
162
  formContext?: FormContext<any>;
163
163
  context: FireCMSContext<USER>;
164
164
  currentEntityId?: string;
165
+ openEntityMode: "side_panel" | "full_screen";
165
166
  }
166
167
  export type PluginFieldBuilderParams<T extends CMSType = CMSType, M extends Record<string, any> = any, EC extends EntityCollection<M> = EntityCollection<M>> = {
167
168
  fieldConfigId: string;
@@ -103,6 +103,11 @@ export interface BaseProperty<T extends CMSType, CustomProps = any> {
103
103
  * save the new config. The saved config will then become the source of truth.
104
104
  */
105
105
  editable?: boolean;
106
+ /**
107
+ * A number between 0 and 100 that indicates the width of the field in the form view.
108
+ * It defaults to 100, but you can set it to 50 to have two fields in the same row.
109
+ */
110
+ widthPercentage?: number;
106
111
  }
107
112
  /**
108
113
  * @group Entity properties
@@ -211,11 +216,11 @@ export type PropertyBuilder<T extends CMSType = any, M extends Record<string, an
211
216
  /**
212
217
  * @group Entity properties
213
218
  */
214
- export type PropertyOrBuilder<T extends CMSType = CMSType, M extends Record<string, any> = Record<string, any>> = Property<T> | PropertyBuilder<T, M>;
219
+ export type PropertyOrBuilder<T extends CMSType = CMSType, M extends Record<string, any> = any> = Property<T> | PropertyBuilder<T, M>;
215
220
  /**
216
221
  * @group Entity properties
217
222
  */
218
- export type PropertiesOrBuilders<M extends Record<string, any> = Record<string, any>> = {
223
+ export type PropertiesOrBuilders<M extends Record<string, any> = any> = {
219
224
  [k in keyof M]: PropertyOrBuilder<M[k], M>;
220
225
  };
221
226
  /**
@@ -278,7 +283,7 @@ export interface StringProperty extends BaseProperty<string> {
278
283
  enumValues?: EnumValues;
279
284
  /**
280
285
  * You can specify a `Storage` configuration. It is used to
281
- * indicate that this string refers to a path in Google Cloud Storage.
286
+ * indicate that this string refers to a path in your storage provider.
282
287
  */
283
288
  storage?: StorageConfig;
284
289
  /**
@@ -361,6 +366,11 @@ export interface ArrayProperty<T extends ArrayT[] = any[], ArrayT extends CMSTyp
361
366
  * Should the field be initially expanded. Defaults to `true`
362
367
  */
363
368
  expanded?: boolean;
369
+ /**
370
+ * Display the child properties directly, without being wrapped in an
371
+ * extendable panel.
372
+ */
373
+ minimalistView?: boolean;
364
374
  }
365
375
  /**
366
376
  * @group Entity properties
@@ -400,6 +410,11 @@ export interface MapProperty<T extends Record<string, CMSType> = Record<string,
400
410
  * view
401
411
  */
402
412
  spreadChildren?: boolean;
413
+ /**
414
+ * Display the child properties directly, without being wrapped in an
415
+ * extendable panel. Note that this will also hide the title of this property.
416
+ */
417
+ minimalistView?: boolean;
403
418
  /**
404
419
  * Should the field be initially expanded. Defaults to `true`
405
420
  */
@@ -1,6 +1,7 @@
1
1
  import { EntityCollection } from "./collections";
2
2
  import { ResolvedEntityCollection } from "./resolved_entities";
3
3
  import { Entity } from "./entities";
4
+ import { EntityFormProps } from "../form";
4
5
  /**
5
6
  * Props used to open a side dialog
6
7
  * @group Hooks and utilities
@@ -22,7 +23,7 @@ export interface EntitySidePanelProps<M extends Record<string, any> = any> {
22
23
  * Open the entity with a selected sub-collection view. If the panel for this
23
24
  * entity was already open, it is replaced.
24
25
  */
25
- selectedSubPath?: string;
26
+ selectedTab?: string;
26
27
  /**
27
28
  * Use this prop to override the width of the form view.
28
29
  * e.g. "600px"
@@ -55,6 +56,10 @@ export interface EntitySidePanelProps<M extends Record<string, any> = any> {
55
56
  * Should this panel close when saving
56
57
  */
57
58
  closeOnSave?: boolean;
59
+ /**
60
+ * Override some form properties
61
+ */
62
+ formProps?: Partial<EntityFormProps<M>>;
58
63
  }
59
64
  /**
60
65
  * Controller to open the side dialog displaying entity forms
@@ -12,7 +12,7 @@ export declare function buildCollection<M extends Record<string, any> = any, USE
12
12
  * @param property
13
13
  * @group Builder
14
14
  */
15
- export declare function buildProperty<T extends CMSType = CMSType, P extends PropertyOrBuilder<T> = PropertyOrBuilder<T>, M extends Record<string, any> = Record<string, any>>(property: P): P extends StringProperty ? StringProperty : P extends NumberProperty ? NumberProperty : P extends BooleanProperty ? BooleanProperty : P extends DateProperty ? DateProperty : P extends GeopointProperty ? GeopointProperty : P extends ReferenceProperty ? ReferenceProperty : P extends ArrayProperty ? ArrayProperty : P extends MapProperty ? MapProperty : P extends PropertyBuilder<T, M> ? PropertyBuilder<T, M> : never;
15
+ export declare function buildProperty<T extends CMSType = CMSType, P extends PropertyOrBuilder<T> = PropertyOrBuilder<T>, M extends Record<string, any> = any>(property: P): P extends StringProperty ? StringProperty : P extends NumberProperty ? NumberProperty : P extends BooleanProperty ? BooleanProperty : P extends DateProperty ? DateProperty : P extends GeopointProperty ? GeopointProperty : P extends ReferenceProperty ? ReferenceProperty : P extends ArrayProperty ? ArrayProperty : P extends MapProperty ? MapProperty : P extends PropertyBuilder<T, M> ? PropertyBuilder<T, M> : never;
16
16
  /**
17
17
  * Identity function we use to defeat the type system of Typescript and preserve
18
18
  * the properties keys.
@@ -0,0 +1,2 @@
1
+ import { EntityAction } from "../types";
2
+ export declare function mergeEntityActions(currentActions: EntityAction[], newActions: EntityAction[]): EntityAction[];
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Saves data to the in-memory cache and persists it individually in `localStorage`.
3
+ * @param path - The unique path/key for the data.
4
+ * @param data - The data to cache and persist.
5
+ */
6
+ export declare function saveEntityToCache(path: string, data: object): void;
7
+ /**
8
+ * Retrieves an entity from the in-memory cache or `localStorage`.
9
+ * If the entity is not in the cache but exists in `localStorage`, it loads it into the cache.
10
+ * @param path - The unique path/key for the entity.
11
+ * @returns The cached entity or `undefined` if not found.
12
+ */
13
+ export declare function getEntityFromCache(path: string): object | undefined;
14
+ export declare function hasEntityInCache(path: string): boolean;
15
+ /**
16
+ * Removes an entity from both the in-memory cache and `localStorage`.
17
+ * @param path - The unique path/key for the entity to remove.
18
+ */
19
+ export declare function removeEntityFromCache(path: string): void;
20
+ /**
21
+ * Clears the entire in-memory cache and removes all related entities from `localStorage`.
22
+ */
23
+ export declare function clearEntityCache(): void;
@@ -7,6 +7,7 @@ export * from "./objects";
7
7
  export * from "./paths";
8
8
  export * from "./regexp";
9
9
  export * from "./navigation_utils";
10
+ export * from "./entity_actions";
10
11
  export * from "./useDebouncedCallback";
11
12
  export * from "./property_utils";
12
13
  export * from "./resolutions";
@@ -4,19 +4,24 @@ export interface NavigationViewEntityInternal<M extends Record<string, any>> {
4
4
  type: "entity";
5
5
  entityId: string;
6
6
  path: string;
7
+ fullPath: string;
7
8
  parentCollection: EntityCollection<M>;
8
9
  }
9
10
  export interface NavigationViewCollectionInternal<M extends Record<string, any>> {
10
11
  type: "collection";
12
+ id: string;
11
13
  path: string;
14
+ fullPath: string;
12
15
  collection: EntityCollection<M>;
13
16
  }
14
17
  export interface NavigationViewEntityCustomInternal<M extends Record<string, any>> {
15
18
  type: "custom_view";
16
19
  path: string;
20
+ fullPath: string;
21
+ entityId: string;
17
22
  view: EntityCustomView<M>;
18
23
  }
19
- export declare function getNavigationEntriesFromPathInternal(props: {
24
+ export declare function getNavigationEntriesFromPath(props: {
20
25
  path: string;
21
26
  collections: EntityCollection[] | undefined;
22
27
  currentFullPath?: string;
@@ -1,4 +1,4 @@
1
- import { EntityCollection } from "../types";
1
+ import { EntityCollection, NavigationController, SideEntityController } from "../types";
2
2
  export declare function removeInitialAndTrailingSlashes(s: string): string;
3
3
  export declare function removeInitialSlash(s: string): string;
4
4
  export declare function removeTrailingSlash(s: string): string;
@@ -18,3 +18,14 @@ export declare function getCollectionByPathOrId(pathOrId: string, collections: E
18
18
  * @param subpaths
19
19
  */
20
20
  export declare function getCollectionPathsCombinations(subpaths: string[]): string[];
21
+ export declare function navigateToEntity({ openEntityMode, collection, entityId, copy, path, selectedTab, sideEntityController, onClose, navigation }: {
22
+ openEntityMode: "side_panel" | "full_screen";
23
+ collection?: EntityCollection;
24
+ entityId?: string;
25
+ selectedTab?: string;
26
+ copy?: boolean;
27
+ path: string;
28
+ sideEntityController: SideEntityController;
29
+ onClose?: () => void;
30
+ navigation: NavigationController;
31
+ }): void;
@@ -1,4 +1,4 @@
1
- import { ArrayProperty, CMSType, EntityCollection, EntityCustomView, EntityValues, EnumValueConfig, EnumValues, NumberProperty, PropertiesOrBuilders, PropertyConfig, PropertyOrBuilder, ResolvedArrayProperty, ResolvedEntityCollection, ResolvedNumberProperty, ResolvedProperties, ResolvedProperty, ResolvedStringProperty, StringProperty, UserConfigurationPersistence } from "../types";
1
+ import { ArrayProperty, CMSType, CustomizationController, EntityCollection, EntityCustomView, EntityValues, EnumValueConfig, EnumValues, NumberProperty, PropertiesOrBuilders, PropertyConfig, PropertyOrBuilder, ResolvedArrayProperty, ResolvedEntityCollection, ResolvedNumberProperty, ResolvedProperties, ResolvedProperty, ResolvedStringProperty, StringProperty, UserConfigurationPersistence } from "../types";
2
2
  export declare const resolveCollection: <M extends Record<string, any>>({ collection, path, entityId, values, previousValues, userConfigPersistence, propertyConfigs, ignoreMissingFields }: {
3
3
  collection: EntityCollection<M> | ResolvedEntityCollection<M>;
4
4
  path: string;
@@ -76,3 +76,8 @@ export declare function resolveProperties<M extends Record<string, any>>({ prope
76
76
  export declare function resolvePropertyEnum(property: StringProperty | NumberProperty, fromBuilder?: boolean): ResolvedStringProperty | ResolvedNumberProperty;
77
77
  export declare function resolveEnumValues(input: EnumValues): EnumValueConfig[] | undefined;
78
78
  export declare function resolveEntityView(entityView: string | EntityCustomView<any>, contextEntityViews?: EntityCustomView<any>[]): EntityCustomView<any> | undefined;
79
+ export declare function resolvedSelectedEntityView<M extends Record<string, any>>(customViews: (string | EntityCustomView<M>)[] | undefined, customizationController: CustomizationController, selectedTab?: string): {
80
+ resolvedEntityViews: EntityCustomView[];
81
+ selectedEntityView: EntityCustomView | undefined;
82
+ selectedSecondaryForm: EntityCustomView | undefined;
83
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@firecms/core",
3
3
  "type": "module",
4
- "version": "3.0.0-beta.11",
4
+ "version": "3.0.0-beta.12",
5
5
  "description": "Awesome Firebase/Firestore-based headless open-source CMS",
6
6
  "funding": {
7
7
  "url": "https://github.com/sponsors/firecmsco"
@@ -50,63 +50,61 @@
50
50
  "./package.json": "./package.json"
51
51
  },
52
52
  "dependencies": {
53
- "@firecms/editor": "^3.0.0-beta.11",
54
- "@firecms/formex": "^3.0.0-beta.11",
55
- "@firecms/ui": "^3.0.0-beta.11",
53
+ "@firecms/editor": "^3.0.0-beta.12",
54
+ "@firecms/formex": "^3.0.0-beta.12",
55
+ "@firecms/ui": "^3.0.0-beta.12",
56
56
  "@hello-pangea/dnd": "^17.0.0",
57
- "@radix-ui/react-portal": "^1.1.2",
57
+ "@radix-ui/react-portal": "^1.1.3",
58
58
  "clsx": "^2.1.1",
59
59
  "date-fns": "^3.6.0",
60
60
  "fuse.js": "^7.0.0",
61
61
  "history": "^5.3.0",
62
62
  "markdown-it": "^14.1.0",
63
- "notistack": "^3.0.1",
63
+ "notistack": "^3.0.2",
64
64
  "object-hash": "^3.0.0",
65
65
  "react-dropzone": "^14.3.5",
66
66
  "react-fast-compare": "^3.2.2",
67
67
  "react-image-file-resizer": "^0.4.8",
68
68
  "react-transition-group": "^4.4.5",
69
69
  "react-use-measure": "^2.1.1",
70
- "react-window": "^1.8.10",
70
+ "react-window": "^1.8.11",
71
71
  "yup": "^0.32.11"
72
72
  },
73
73
  "peerDependencies": {
74
- "firebase": "^10.5.2",
75
- "react": "^18.3.1",
76
- "react-dom": "^18.3.1",
74
+ "react": ">=18.0.0",
75
+ "react-dom": ">=18.0.0",
77
76
  "react-router": "^6.28.0",
78
77
  "react-router-dom": "^6.28.0"
79
78
  },
80
79
  "devDependencies": {
81
80
  "@jest/globals": "^29.7.0",
82
- "@testing-library/react": "^16.0.1",
83
- "@testing-library/user-event": "^14.5.2",
81
+ "@testing-library/react": "^16.2.0",
82
+ "@testing-library/user-event": "^14.6.1",
84
83
  "@types/jest": "^29.5.14",
85
- "@types/node": "^20.17.9",
84
+ "@types/node": "^20.17.14",
86
85
  "@types/object-hash": "^3.0.6",
87
- "@types/react": "^18.3.11",
88
- "@types/react-dom": "^18.3.1",
86
+ "@types/react": "^18.3.18",
87
+ "@types/react-dom": "^18.3.0",
89
88
  "@types/react-measure": "^2.0.12",
90
89
  "@vitejs/plugin-react": "^4.3.4",
91
90
  "babel-plugin-react-compiler": "beta",
92
91
  "cross-env": "^7.0.3",
93
92
  "eslint-plugin-react-compiler": "beta",
94
- "firebase": "^10.14.1",
95
93
  "jest": "^29.7.0",
96
94
  "npm-run-all": "^4.1.5",
97
- "react-router": "^6.28.0",
98
- "react-router-dom": "^6.28.0",
95
+ "react-router": "^6.28.2",
96
+ "react-router-dom": "^6.28.2",
99
97
  "ts-jest": "^29.2.5",
100
98
  "ts-node": "^10.9.2",
101
99
  "tsd": "^0.31.2",
102
- "typescript": "^5.7.2",
103
- "vite": "^5.4.11"
100
+ "typescript": "^5.7.3",
101
+ "vite": "^5.4.14"
104
102
  },
105
103
  "files": [
106
104
  "dist",
107
105
  "src"
108
106
  ],
109
- "gitHead": "cb6d419faf2664cfd6cb2603a834e4bf499a92bb",
107
+ "gitHead": "8de3edb4560643922fe44e9c357985f64c3951c1",
110
108
  "publishConfig": {
111
109
  "access": "public"
112
110
  },