@firecms/core 3.0.0-alpha.27 → 3.0.0-alpha.29

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 (91) hide show
  1. package/dist/components/Popover.d.ts +3 -1
  2. package/dist/core/FireCMS.d.ts +2 -2
  3. package/dist/core/builders.d.ts +5 -5
  4. package/dist/core/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +4 -2
  5. package/dist/core/components/EntityCollectionTable/filters/ReferenceFilterField.d.ts +3 -3
  6. package/dist/core/components/EntityCollectionTable/internal/EntityCollectionRowActions.d.ts +15 -11
  7. package/dist/core/components/EntityCollectionTable/internal/default_entity_actions.d.ts +5 -0
  8. package/dist/core/components/EntityCollectionTable/types.d.ts +1 -37
  9. package/dist/core/components/FieldConfigBadge.d.ts +3 -3
  10. package/dist/core/components/VirtualTable/VirtualTableHeader.d.ts +2 -2
  11. package/dist/core/components/VirtualTable/VirtualTableProps.d.ts +1 -1
  12. package/dist/core/contexts/DialogsProvider.d.ts +4 -0
  13. package/dist/core/form_field_configs.d.ts +3 -3
  14. package/dist/core/index.d.ts +1 -1
  15. package/dist/core/internal/useBuildNavigationContext.d.ts +3 -3
  16. package/dist/core/util/property_utils.d.ts +5 -5
  17. package/dist/core/util/references.d.ts +2 -2
  18. package/dist/core/util/resolutions.d.ts +6 -6
  19. package/dist/hooks/index.d.ts +1 -0
  20. package/dist/hooks/useBuildDataSource.d.ts +23 -0
  21. package/dist/hooks/useDialogsController.d.ts +11 -0
  22. package/dist/index.es.js +8996 -8583
  23. package/dist/index.es.js.map +1 -1
  24. package/dist/index.umd.js +67 -67
  25. package/dist/index.umd.js.map +1 -1
  26. package/dist/styles.d.ts +1 -1
  27. package/dist/types/collections.d.ts +36 -13
  28. package/dist/types/datasource.d.ts +120 -11
  29. package/dist/types/dialogs_controller.d.ts +30 -0
  30. package/dist/types/entity_actions.d.ts +33 -0
  31. package/dist/types/fields.d.ts +1 -1
  32. package/dist/types/firecms.d.ts +8 -8
  33. package/dist/types/firecms_context.d.ts +10 -3
  34. package/dist/types/index.d.ts +2 -1
  35. package/dist/types/navigation.d.ts +3 -3
  36. package/dist/types/plugins.d.ts +11 -10
  37. package/dist/types/properties.d.ts +1 -1
  38. package/dist/types/{field_config.d.ts → property_config.d.ts} +3 -4
  39. package/package.json +3 -3
  40. package/src/components/Popover.tsx +10 -3
  41. package/src/components/Sheet.tsx +1 -0
  42. package/src/components/TextareaAutosize.tsx +2 -1
  43. package/src/core/FireCMS.tsx +9 -6
  44. package/src/core/builders.ts +11 -11
  45. package/src/core/components/ArrayContainer.tsx +1 -1
  46. package/src/core/components/EntityCollectionTable/EntityCollectionTable.tsx +20 -13
  47. package/src/core/components/EntityCollectionTable/EntityCollectionTableProps.tsx +5 -2
  48. package/src/core/components/EntityCollectionTable/filters/ReferenceFilterField.tsx +11 -6
  49. package/src/core/components/EntityCollectionTable/internal/EntityCollectionRowActions.tsx +96 -79
  50. package/src/core/components/EntityCollectionTable/internal/PropertyTableCell.tsx +2 -2
  51. package/src/core/components/EntityCollectionTable/internal/default_entity_actions.tsx +107 -0
  52. package/src/core/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +6 -2
  53. package/src/core/components/EntityCollectionTable/types.tsx +1 -56
  54. package/src/core/components/EntityCollectionView/EntityCollectionView.tsx +67 -43
  55. package/src/core/components/FieldConfigBadge.tsx +4 -4
  56. package/src/core/components/ReferenceSelectionInner.tsx +2 -2
  57. package/src/core/components/VirtualTable/VirtualTable.tsx +4 -6
  58. package/src/core/components/VirtualTable/VirtualTableHeader.tsx +21 -18
  59. package/src/core/components/VirtualTable/VirtualTableProps.tsx +1 -1
  60. package/src/core/contexts/DialogsProvider.tsx +50 -0
  61. package/src/core/form_field_configs.tsx +5 -5
  62. package/src/core/index.tsx +1 -1
  63. package/src/core/internal/useBuildNavigationContext.tsx +13 -13
  64. package/src/core/internal/useBuildSideEntityController.tsx +9 -1
  65. package/src/core/util/property_utils.tsx +5 -5
  66. package/src/core/util/references.ts +2 -2
  67. package/src/core/util/resolutions.ts +16 -11
  68. package/src/form/EntityForm.tsx +64 -7
  69. package/src/form/PropertyFieldBinding.tsx +4 -4
  70. package/src/form/field_bindings/KeyValueFieldBinding.tsx +1 -1
  71. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +4 -6
  72. package/src/hooks/index.tsx +1 -0
  73. package/src/hooks/useBuildDataSource.ts +351 -0
  74. package/src/hooks/useDialogsController.tsx +14 -0
  75. package/src/hooks/useFireCMSContext.tsx +5 -11
  76. package/src/preview/property_previews/StringPropertyPreview.tsx +4 -2
  77. package/src/styles.ts +1 -1
  78. package/src/types/collections.ts +36 -17
  79. package/src/types/datasource.ts +174 -10
  80. package/src/types/dialogs_controller.tsx +31 -0
  81. package/src/types/entity_actions.tsx +36 -0
  82. package/src/types/fields.tsx +1 -1
  83. package/src/types/firecms.tsx +8 -8
  84. package/src/types/firecms_context.tsx +11 -3
  85. package/src/types/index.ts +2 -1
  86. package/src/types/navigation.ts +3 -3
  87. package/src/types/plugins.tsx +11 -10
  88. package/src/types/properties.ts +1 -1
  89. package/src/types/{field_config.tsx → property_config.tsx} +3 -4
  90. /package/dist/core/contexts/{SnackbarContext.d.ts → SnackbarProvider.d.ts} +0 -0
  91. /package/src/core/contexts/{SnackbarContext.tsx → SnackbarProvider.tsx} +0 -0
package/dist/styles.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare const focusedMixin = "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-opacity-75 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent";
1
+ export declare const focusedMixin = "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-opacity-75 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent";
2
2
  export declare const focusedInvisibleMixin = "focus:bg-opacity-70 focus:bg-gray-100 focus:dark:bg-gray-800 focus:dark:bg-opacity-60";
3
3
  export declare const focusedClasses = "z-30 outline-none ring-2 ring-primary ring-opacity-75 ring-offset-2 ring-offset-transparent ";
4
4
  export declare const fieldBackgroundMixin = "bg-opacity-70 bg-gray-100 dark:bg-gray-800 dark:bg-opacity-60 transition duration-150 ease-in-out";
@@ -6,6 +6,7 @@ import { EntityCallbacks } from "./entity_callbacks";
6
6
  import { Permissions, PermissionsBuilder } from "./permissions";
7
7
  import { EnumValues, PropertiesOrBuilders } from "./properties";
8
8
  import { FormContext } from "./fields";
9
+ import { EntityAction } from "./entity_actions";
9
10
  /**
10
11
  * This interface represents a view that includes a collection of entities.
11
12
  * It can be in the root level of the configuration, defining the main
@@ -13,7 +14,7 @@ import { FormContext } from "./fields";
13
14
  *
14
15
  * @category Models
15
16
  */
16
- export interface EntityCollection<M extends Record<string, any> = any, AdditionalKey extends string = string, UserType extends User = User> {
17
+ export interface EntityCollection<M extends Record<string, any> = any, UserType extends User = User> {
17
18
  /**
18
19
  * Name of the collection, typically plural.
19
20
  * E.g. `Products`, `Blog`
@@ -48,9 +49,9 @@ export interface EntityCollection<M extends Record<string, any> = any, Additiona
48
49
  alias?: string;
49
50
  /**
50
51
  * Icon key to use in this collection.
51
- * You can use any of the icons in the MUI specs:
52
- * https://mui.com/material-ui/material-icons/
53
- * e.g. 'AccountTree' or 'Person'
52
+ * You can use any of the icons in the Material specs:
53
+ * https://fonts.google.com/icons
54
+ * e.g. 'account_tree' or 'person'
54
55
  */
55
56
  icon?: string;
56
57
  /**
@@ -80,7 +81,7 @@ export interface EntityCollection<M extends Record<string, any> = any, Additiona
80
81
  * - If you are using a collection group, you will also have an
81
82
  * additional `collectionGroupParent` column.
82
83
  */
83
- propertiesOrder?: Extract<keyof M | AdditionalKey, string>[];
84
+ propertiesOrder?: Extract<keyof M, string>[];
84
85
  /**
85
86
  * If enabled, content is loaded in batches. If `false` all entities in the
86
87
  * collection are loaded.
@@ -97,7 +98,7 @@ export interface EntityCollection<M extends Record<string, any> = any, Additiona
97
98
  * Permissions the logged-in user can perform on this collection.
98
99
  * If not specified everything defaults to `true`.
99
100
  */
100
- permissions?: Permissions | PermissionsBuilder<EntityCollection<M>, UserType, M>;
101
+ permissions?: Permissions | PermissionsBuilder<any, UserType, M>;
101
102
  /**
102
103
  * Are the entities in this collection selectable. Defaults to `true`
103
104
  */
@@ -119,6 +120,30 @@ export interface EntityCollection<M extends Record<string, any> = any, Additiona
119
120
  * collection toolbar
120
121
  */
121
122
  Actions?: React.ComponentType<CollectionActionsProps> | React.ComponentType<CollectionActionsProps>[];
123
+ /**
124
+ * You can define additional actions that can be performed on the entities
125
+ * in this collection. These actions can be displayed in the collection
126
+ * view or in the entity view.
127
+ *
128
+ * You can use the `onClick` method to implement your own logic.
129
+ * In the `context` prop you can access all the controllers of FireCMS.
130
+ *
131
+ * ```
132
+ * const archiveEntityAction: EntityAction = {
133
+ * icon: <ArchiveIcon/>,
134
+ * name: "Archive",
135
+ * onClick({
136
+ * entity,
137
+ * collection,
138
+ * context,
139
+ * }): Promise<void> {
140
+ * // Add your code here
141
+ * return Promise.resolve(undefined);
142
+ * }
143
+ * }
144
+ * ```
145
+ */
146
+ entityActions?: EntityAction<M, UserType>[];
122
147
  /**
123
148
  * Pass your own selection controller if you want to control selected
124
149
  * entities externally.
@@ -163,7 +188,7 @@ export interface EntityCollection<M extends Record<string, any> = any, Additiona
163
188
  * You can add additional fields to the collection view by implementing
164
189
  * an additional field delegate.
165
190
  */
166
- additionalFields?: AdditionalFieldDelegate<M, AdditionalKey, UserType>[];
191
+ additionalFields?: AdditionalFieldDelegate<M, UserType>[];
167
192
  /**
168
193
  * Default size of the rendered collection
169
194
  */
@@ -208,10 +233,8 @@ export interface EntityCollection<M extends Record<string, any> = any, Additiona
208
233
  }
209
234
  /**
210
235
  * Parameter passed to the `Actions` prop in the collection configuration.
211
- * Note that actions are rendered in the collection toolbar, as well
212
- * as in the home page card.
213
- * If you don't want to render the actions in the home page card, you can
214
- * return `null` if mode is `home`.
236
+ * The component will receive this prop when it is rendered in the collection
237
+ * toolbar.
215
238
  *
216
239
  * @category Models
217
240
  */
@@ -296,12 +319,12 @@ export type AdditionalFieldDelegateProps<M extends Record<string, any> = any, Us
296
319
  * If you need to do some async loading you can use {@link AsyncPreviewComponent}
297
320
  * @category Models
298
321
  */
299
- export interface AdditionalFieldDelegate<M extends Record<string, any> = any, AdditionalKey extends string = string, UserType extends User = User> {
322
+ export interface AdditionalFieldDelegate<M extends Record<string, any> = any, UserType extends User = User> {
300
323
  /**
301
324
  * ID of this column. You can use this id in the `properties` field of the
302
325
  * collection in any order you want
303
326
  */
304
- id: AdditionalKey;
327
+ id: string;
305
328
  /**
306
329
  * Header of this column
307
330
  */
@@ -1,6 +1,6 @@
1
- import { Entity, EntityStatus, EntityValues } from "./entities";
1
+ import { Entity, EntityReference, EntityStatus, EntityValues, GeoPoint } from "./entities";
2
2
  import { EntityCollection, FilterValues } from "./collections";
3
- import { ResolvedEntityCollection, ResolvedProperty } from "./resolved_entities";
3
+ import { ResolvedEntityCollection } from "./resolved_entities";
4
4
  /**
5
5
  * @category Datasource
6
6
  */
@@ -131,7 +131,7 @@ export interface DataSource {
131
131
  * @param entityId
132
132
  * @return `true` if there are no other fields besides the given entity
133
133
  */
134
- checkUniqueField(path: string, name: string, value: any, property: ResolvedProperty, entityId?: string): Promise<boolean>;
134
+ checkUniqueField(path: string, name: string, value: any, entityId?: string): Promise<boolean>;
135
135
  /**
136
136
  * Generate an id for a new entity
137
137
  */
@@ -142,12 +142,121 @@ export interface DataSource {
142
142
  countEntities<M extends Record<string, any> = any>(props: FetchCollectionProps<M>): Promise<number>;
143
143
  /**
144
144
  * Check if the given filter combination is valid
145
- * @param params
146
- */
147
- isFilterCombinationValid?(params: {
148
- path: string;
149
- collection: EntityCollection<any>;
150
- filterValues: FilterValues<any>;
151
- sortBy?: [string, "asc" | "desc"];
152
- }): boolean;
145
+ * @param props
146
+ */
147
+ isFilterCombinationValid?(props: FilterCombinationValidProps): boolean;
148
+ }
149
+ export type FilterCombinationValidProps = {
150
+ path: string;
151
+ collection: EntityCollection<any>;
152
+ filterValues: FilterValues<any>;
153
+ sortBy?: [string, "asc" | "desc"];
154
+ };
155
+ export type SaveEntityDelegateProps<M extends Record<string, any> = any> = Omit<SaveEntityProps<M>, "collection">;
156
+ export type FetchCollectionDelegateProps<M extends Record<string, any> = any> = Omit<FetchCollectionProps<M>, "collection"> & {
157
+ isCollectionGroup?: boolean;
158
+ };
159
+ export type ListenCollectionDelegateProps<M extends Record<string, any> = any> = Omit<ListenCollectionProps<M>, "collection"> & {
160
+ isCollectionGroup?: boolean;
161
+ };
162
+ export interface DataSourceDelegate {
163
+ /**
164
+ * Fetch data from a collection
165
+ * @param path
166
+ * @param filter
167
+ * @param limit
168
+ * @param startAfter
169
+ * @param orderBy
170
+ * @param order
171
+ * @param searchString
172
+ * @return Function to cancel subscription
173
+ * @see useCollectionFetch if you need this functionality implemented as a hook
174
+ */
175
+ fetchCollection<M extends Record<string, any> = any>({ path, filter, limit, startAfter, orderBy, order, searchString }: FetchCollectionDelegateProps<M>): Promise<Entity<M>[]>;
176
+ /**
177
+ * Listen to a collection in a given path. If you don't implement this method
178
+ * `fetchCollection` will be used instead, with no real time updates.
179
+ * @param path
180
+ * @param onUpdate
181
+ * @param onError
182
+ * @param filter
183
+ * @param limit
184
+ * @param startAfter
185
+ * @param orderBy
186
+ * @param order
187
+ * @param searchString
188
+ * @return Function to cancel subscription
189
+ * @see useCollectionFetch if you need this functionality implemented as a hook
190
+ */
191
+ listenCollection?<M extends Record<string, any> = any>({ path, filter, limit, startAfter, searchString, orderBy, order, onUpdate, onError }: ListenCollectionDelegateProps<M>): () => void;
192
+ /**
193
+ * Retrieve an entity given a path and a collection
194
+ * @param path
195
+ * @param entityId
196
+ */
197
+ fetchEntity<M extends Record<string, any> = any>({ path, entityId, }: Omit<FetchEntityProps<M>, "collection">): Promise<Entity<M> | undefined>;
198
+ /**
199
+ * Get realtime updates on one entity.
200
+ * @param path
201
+ * @param entityId
202
+ * @param collection
203
+ * @param onUpdate
204
+ * @param onError
205
+ * @return Function to cancel subscription
206
+ */
207
+ listenEntity?<M extends Record<string, any> = any>({ path, entityId, onUpdate, onError }: Omit<ListenEntityProps<M>, "collection">): () => void;
208
+ /**
209
+ * Save entity to the specified path
210
+ * @param path
211
+ * @param id
212
+ * @param collection
213
+ * @param status
214
+ */
215
+ saveEntity<M extends Record<string, any> = any>({ path, entityId, values, status }: SaveEntityDelegateProps<M>): Promise<Entity<M>>;
216
+ /**
217
+ * Delete an entity
218
+ * @param entity
219
+ * @return was the whole deletion flow successful
220
+ */
221
+ deleteEntity<M extends Record<string, any> = any>({ entity }: DeleteEntityProps<M>): Promise<void>;
222
+ /**
223
+ * Check if the given property is unique in the given collection
224
+ * @param path Collection path
225
+ * @param name of the property
226
+ * @param value
227
+ * @param entityId
228
+ * @return `true` if there are no other fields besides the given entity
229
+ */
230
+ checkUniqueField(path: string, name: string, value: any, entityId?: string): Promise<boolean>;
231
+ /**
232
+ * Generate an id for a new entity
233
+ */
234
+ generateEntityId(path: string): string;
235
+ /**
236
+ * Count the number of entities in a collection
237
+ */
238
+ countEntities<M extends Record<string, any> = any>(props: FetchCollectionDelegateProps<M>): Promise<number>;
239
+ /**
240
+ * Check if the given filter combination is valid
241
+ * @param props
242
+ */
243
+ isFilterCombinationValid?(props: Omit<FilterCombinationValidProps, "collection">): boolean;
244
+ /**
245
+ * Convert a FireCMS reference to a reference that can be used by the datasource
246
+ * @param reference
247
+ */
248
+ buildReference: (reference: EntityReference) => any;
249
+ /**
250
+ * Convert a FireCMS GeoPoint to a GeoPoint that can be used by the datasource
251
+ * @param geoPoint
252
+ */
253
+ buildGeoPoint: (geoPoint: GeoPoint) => any;
254
+ /**
255
+ * Get the object to generate the current time in the datasource
256
+ */
257
+ currentTime(): any;
258
+ buildDate: (date: Date) => any;
259
+ buildDeleteFieldValue: () => any;
260
+ delegateToCMSModel: (data: any) => any;
261
+ setDateToMidnight: (input?: any) => any;
153
262
  }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Controller to open the side dialog
3
+ * @category Hooks and utilities
4
+ */
5
+ export interface DialogsController {
6
+ /**
7
+ * Close the last dialog
8
+ */
9
+ close: () => void;
10
+ /**
11
+ * Open a dialog
12
+ * @param props
13
+ */
14
+ open: (props: DialogControllerEntryProps) => {
15
+ closeDialog: () => void;
16
+ };
17
+ }
18
+ /**
19
+ * Props used to open a side dialog
20
+ * @category Hooks and utilities
21
+ */
22
+ export interface DialogControllerEntryProps {
23
+ key: string;
24
+ /**
25
+ * The component type that will be rendered
26
+ */
27
+ Component: React.ComponentType<{
28
+ open: boolean;
29
+ }>;
30
+ }
@@ -0,0 +1,33 @@
1
+ import React from "react";
2
+ import { FireCMSContext } from "./firecms_context";
3
+ import { Entity } from "./entities";
4
+ import { EntityCollection, SelectionController } from "./collections";
5
+ import { User } from "./user";
6
+ import { SideEntityController } from "./side_entity_controller";
7
+ export type EntityAction<M extends object = any, UserType extends User = User> = {
8
+ name: string;
9
+ icon?: React.ReactElement;
10
+ onClick: (props: EntityActionClickProps<M, UserType>) => Promise<void>;
11
+ /**
12
+ * Show this action in the menu, defaults to true
13
+ */
14
+ collapsed?: boolean;
15
+ /**
16
+ * Show this action in the form, defaults to true
17
+ */
18
+ includeInForm?: boolean;
19
+ };
20
+ export type EntityActionClickProps<M extends object, UserType extends User = User> = {
21
+ entity: Entity<M>;
22
+ context: FireCMSContext<UserType>;
23
+ fullPath?: string;
24
+ collection?: EntityCollection<M>;
25
+ selectionController?: SelectionController;
26
+ highlightEntity?: (entity: Entity<any>) => void;
27
+ unhighlightEntity?: (entity: Entity<any>) => void;
28
+ onCollectionChange?: () => void;
29
+ /**
30
+ * If this actions is being called from a side dialog
31
+ */
32
+ sideEntityController?: SideEntityController;
33
+ };
@@ -7,7 +7,7 @@ import { ResolvedEntityCollection, ResolvedProperty } from "./resolved_entities"
7
7
  *
8
8
  * @category Form custom fields
9
9
  */
10
- export interface FieldProps<T extends CMSType = CMSType, CustomProps = any, M extends Record<string, any> = any> {
10
+ export interface FieldProps<T extends CMSType = any, CustomProps = any, M extends Record<string, any> = any> {
11
11
  /**
12
12
  * Key of the property
13
13
  * E.g. "user.name" for a property with path "user.name"
@@ -5,7 +5,7 @@ import { DataSource } from "./datasource";
5
5
  import { EntityCollection, EntityCustomView } from "./collections";
6
6
  import { CMSView } from "./navigation";
7
7
  import { FireCMSContext } from "./firecms_context";
8
- import { FieldConfig } from "./field_config";
8
+ import { PropertyConfig } from "./property_config";
9
9
  import { Locale } from "./locales";
10
10
  import { StorageSource } from "./storage";
11
11
  import { EntityLinkBuilder } from "./entity_link_builder";
@@ -22,11 +22,11 @@ import { CMSAnalyticsEvent } from "./analytics";
22
22
  * APIs directly, or a REST API.
23
23
  * @category Models
24
24
  */
25
- export type EntityCollectionsBuilder = (params: {
25
+ export type EntityCollectionsBuilder<EC extends EntityCollection> = (params: {
26
26
  user: User | null;
27
27
  authController: AuthController;
28
28
  dataSource: DataSource;
29
- }) => EntityCollection[] | Promise<EntityCollection[]>;
29
+ }) => EC[] | Promise<EC[]>;
30
30
  /**
31
31
  * Use this callback to build custom views dynamically.
32
32
  * You can use the user to decide which views to show.
@@ -44,7 +44,7 @@ export type CMSViewsBuilder = (params: {
44
44
  /**
45
45
  * @category Models
46
46
  */
47
- export type FireCMSProps<UserType extends User> = {
47
+ export type FireCMSProps<UserType extends User, EC extends EntityCollection> = {
48
48
  /**
49
49
  * Use this function to return the components you want to render under
50
50
  * FireCMS
@@ -68,7 +68,7 @@ export type FireCMSProps<UserType extends User> = {
68
68
  * Each of the navigation entries in this field
69
69
  * generates an entry in the main menu.
70
70
  */
71
- collections?: EntityCollection[] | EntityCollectionsBuilder;
71
+ collections?: EC[] | EntityCollectionsBuilder<EC>;
72
72
  /**
73
73
  * Custom additional views created by the developer, added to the main
74
74
  * navigation
@@ -77,9 +77,9 @@ export type FireCMSProps<UserType extends User> = {
77
77
  /**
78
78
  * Record of custom form fields to be used in the CMS.
79
79
  * You can use the key to reference the custom field in
80
- * the `fieldConfig` prop of a property in a collection.
80
+ * the `propertyConfig` prop of a property in a collection.
81
81
  */
82
- fields?: Record<string, FieldConfig>;
82
+ fields?: Record<string, PropertyConfig>;
83
83
  /**
84
84
  * List of additional custom views for entities.
85
85
  * You can use the key to reference the custom view in
@@ -130,7 +130,7 @@ export type FireCMSProps<UserType extends User> = {
130
130
  * Use plugins to modify the behaviour of the CMS.
131
131
  * Currently, in ALPHA, and likely subject to change.
132
132
  */
133
- plugins?: FireCMSPlugin[];
133
+ plugins?: FireCMSPlugin<any, any, any>[];
134
134
  /**
135
135
  * Callback used to get analytics events from the CMS
136
136
  */
@@ -11,8 +11,9 @@ import { UserConfigurationPersistence } from "./local_config_persistence";
11
11
  import { SideDialogsController } from "./side_dialogs_controller";
12
12
  import { FireCMSPlugin } from "./plugins";
13
13
  import { CMSAnalyticsEvent } from "./analytics";
14
- import { FieldConfig } from "./field_config";
14
+ import { PropertyConfig } from "./property_config";
15
15
  import { EntityCustomView } from "./collections";
16
+ import { DialogsController } from "./dialogs_controller";
16
17
  /**
17
18
  * Context that includes the internal controllers and contexts used by the app.
18
19
  * Some controllers and context included in this context can be accessed
@@ -51,8 +52,14 @@ export type FireCMSContext<UserType extends User = User, AuthControllerType exte
51
52
  sideEntityController: SideEntityController;
52
53
  /**
53
54
  * Controller used to open side dialogs
55
+ * This is the controller used internally by side entity dialogs
56
+ * or reference dialogs.
54
57
  */
55
58
  sideDialogsController: SideDialogsController;
59
+ /**
60
+ * Controller used to open regular dialogs
61
+ */
62
+ dialogsController: DialogsController;
56
63
  /**
57
64
  * Used auth controller
58
65
  */
@@ -81,9 +88,9 @@ export type FireCMSContext<UserType extends User = User, AuthControllerType exte
81
88
  /**
82
89
  * Record of custom form fields to be used in the CMS.
83
90
  * You can use the key to reference the custom field in
84
- * the `fieldConfig` prop of a property in a collection.
91
+ * the `propertyConfig` prop of a property in a collection.
85
92
  */
86
- fields: Record<string, FieldConfig>;
93
+ fields: Record<string, PropertyConfig>;
87
94
  /**
88
95
  * List of additional custom views for entities.
89
96
  * You can use the key to reference the custom view in
@@ -1,5 +1,6 @@
1
1
  export * from "./auth";
2
2
  export * from "./entities";
3
+ export * from "./entity_actions";
3
4
  export * from "./resolved_entities";
4
5
  export * from "./properties";
5
6
  export * from "./collections";
@@ -10,7 +11,7 @@ export * from "./user";
10
11
  export * from "./colors";
11
12
  export * from "./storage";
12
13
  export * from "./fields";
13
- export * from "./field_config";
14
+ export * from "./property_config";
14
15
  export * from "./datasource";
15
16
  export * from "./entity_link_builder";
16
17
  export * from "./side_entity_controller";
@@ -127,9 +127,9 @@ export interface CMSView {
127
127
  description?: string;
128
128
  /**
129
129
  * Icon key to use in this view.
130
- * You can use any of the icons in the MUI specs:
131
- * https://mui.com/material-ui/material-icons/
132
- * e.g. 'AccountTree' or 'Person'
130
+ * You can use any of the icons in the Material specs:
131
+ * https://fonts.google.com/icons
132
+ * e.g. 'account_tree' or 'person'
133
133
  */
134
134
  icon?: string;
135
135
  /**
@@ -11,7 +11,7 @@ import { ResolvedProperty } from "./resolved_entities";
11
11
  * NOTE: This is a work in progress and the API is not stable yet.
12
12
  * @category Core
13
13
  */
14
- export type FireCMSPlugin<PROPS = any, FORM_PROPS = any> = {
14
+ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollection = EntityCollection> = {
15
15
  /**
16
16
  * Name of the plugin
17
17
  */
@@ -34,15 +34,15 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any> = {
34
34
  * Use this component to add custom actions to the entity collections
35
35
  * toolbar.
36
36
  */
37
- CollectionActions?: React.ComponentType<CollectionActionsProps> | React.ComponentType<CollectionActionsProps>[];
37
+ CollectionActions?: React.ComponentType<CollectionActionsProps<any, any, EC>> | React.ComponentType<CollectionActionsProps<any, any, EC>>[];
38
38
  };
39
39
  form?: {
40
40
  provider?: {
41
- Component: React.ComponentType<PropsWithChildren<FORM_PROPS & PluginFormActionProps<any>>>;
41
+ Component: React.ComponentType<PropsWithChildren<FORM_PROPS & PluginFormActionProps<any, EC>>>;
42
42
  props?: FORM_PROPS;
43
43
  };
44
- Actions?: React.ComponentType<PluginFormActionProps>;
45
- fieldBuilder?: <T extends CMSType = CMSType>(props: PluginFieldBuilderParams<T>) => React.ComponentType<FieldProps<T>> | null;
44
+ Actions?: React.ComponentType<PluginFormActionProps<any, EC>>;
45
+ fieldBuilder?: <T extends CMSType = CMSType>(props: PluginFieldBuilderParams<T, any, EC>) => React.ComponentType<FieldProps<T>> | null;
46
46
  fieldBuilderEnabled?: <T extends CMSType = CMSType>(props: PluginFieldBuilderParams<T>) => boolean;
47
47
  };
48
48
  /**
@@ -95,6 +95,7 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any> = {
95
95
  fullPath: string;
96
96
  parentPathSegments: string[];
97
97
  onHover: boolean;
98
+ collection: EC;
98
99
  }>;
99
100
  /**
100
101
  * If you add this callback to your plugin, an add button will be added to the collection table.
@@ -103,7 +104,7 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any> = {
103
104
  AddColumnComponent?: React.ComponentType<{
104
105
  fullPath: string;
105
106
  parentPathSegments: string[];
106
- collection: EntityCollection;
107
+ collection: EC;
107
108
  }>;
108
109
  };
109
110
  };
@@ -129,23 +130,23 @@ export interface PluginHomePageActionsProps<EP extends object = object, M extend
129
130
  context: FireCMSContext<UserType>;
130
131
  extraProps?: EP;
131
132
  }
132
- export interface PluginFormActionProps<UserType extends User = User> {
133
+ export interface PluginFormActionProps<UserType extends User = User, EC extends EntityCollection = EntityCollection> {
133
134
  entityId?: string;
134
135
  path: string;
135
136
  status: EntityStatus;
136
- collection: EntityCollection;
137
+ collection: EC;
137
138
  formContext?: FormContext<any>;
138
139
  context: FireCMSContext<UserType>;
139
140
  currentEntityId?: string;
140
141
  }
141
- export type PluginFieldBuilderParams<T extends CMSType = CMSType, M extends Record<string, any> = any> = {
142
+ export type PluginFieldBuilderParams<T extends CMSType = CMSType, M extends Record<string, any> = any, EC extends EntityCollection<M> = EntityCollection<M>> = {
142
143
  fieldConfigId: string;
143
144
  propertyKey: string;
144
145
  property: Property<T> | ResolvedProperty<T>;
145
146
  Field: React.ComponentType<FieldProps<T, any, M>>;
146
147
  plugin: FireCMSPlugin;
147
148
  path: string;
148
- collection: EntityCollection<M>;
149
+ collection: EC;
149
150
  };
150
151
  export interface PluginGenericProps<UserType extends User = User> {
151
152
  context: FireCMSContext<UserType>;
@@ -44,7 +44,7 @@ export interface BaseProperty<T extends CMSType, CustomProps = any> {
44
44
  * All the configuration will be taken from the inherited config, and
45
45
  * overwritten by the current property config.
46
46
  */
47
- fieldConfig?: string;
47
+ propertyConfig?: string;
48
48
  /**
49
49
  * Longer description of a field, displayed under a popover
50
50
  */
@@ -1,14 +1,13 @@
1
1
  import React from "react";
2
2
  import { CMSType, PropertyOrBuilder } from "./properties";
3
3
  /**
4
- * This is the configuration object for the field component generated for a
5
- * property.
4
+ * This is the configuration object for a property.
6
5
  * These configs are generated by default for the properties defined in your
7
6
  * collections' configuration, but you can define your own to be used.
8
7
  */
9
- export type FieldConfig<T extends CMSType = any> = {
8
+ export type PropertyConfig<T extends CMSType = any> = {
10
9
  /**
11
- * Key used to identify this field type.
10
+ * Key used to identify this property config.
12
11
  */
13
12
  key: string;
14
13
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firecms/core",
3
- "version": "3.0.0-alpha.27",
3
+ "version": "3.0.0-alpha.29",
4
4
  "description": "Awesome Firebase/Firestore-based headless open-source CMS",
5
5
  "funding": {
6
6
  "url": "https://github.com/sponsors/firecmsco"
@@ -101,7 +101,7 @@
101
101
  "@testing-library/react": "^14.0.0",
102
102
  "@testing-library/user-event": "^14.5.1",
103
103
  "@types/jest": "^29.5.6",
104
- "@types/node": "^18.18.7",
104
+ "@types/node": "^20.8.9",
105
105
  "@types/object-hash": "^3.0.5",
106
106
  "@types/react": "^18.2.33",
107
107
  "@types/react-dom": "^18.2.14",
@@ -133,7 +133,7 @@
133
133
  "dist",
134
134
  "src"
135
135
  ],
136
- "gitHead": "deb0ef4491986b9a599919a2cd581f40ac6920c1",
136
+ "gitHead": "65c1ea189696ea89b29b2416680a1dc541da0b36",
137
137
  "publishConfig": {
138
138
  "access": "public"
139
139
  }
@@ -22,6 +22,8 @@ export interface PopoverProps {
22
22
  hideWhenDetached?: boolean;
23
23
  avoidCollisions?: boolean;
24
24
  enabled?: boolean;
25
+ modal?: boolean;
26
+ className?: string;
25
27
  }
26
28
 
27
29
  export function Popover({
@@ -37,7 +39,9 @@ export function Popover({
37
39
  sticky,
38
40
  hideWhenDetached,
39
41
  avoidCollisions,
40
- enabled = true
42
+ enabled = true,
43
+ modal = false,
44
+ className
41
45
  }: PopoverProps) {
42
46
 
43
47
  useInjectStyles("Popover", popoverStyles);
@@ -45,12 +49,15 @@ export function Popover({
45
49
  if (!enabled)
46
50
  return <>{trigger}</>;
47
51
 
48
- return <PopoverPrimitive.Root open={open} onOpenChange={onOpenChange}>
52
+ return <PopoverPrimitive.Root open={open}
53
+ onOpenChange={onOpenChange}
54
+ modal={modal}
55
+ >
49
56
  <PopoverPrimitive.Trigger asChild>
50
57
  {trigger}
51
58
  </PopoverPrimitive.Trigger>
52
59
  <PopoverPrimitive.Portal>
53
- <PopoverPrimitive.Content className={cn(paperMixin, "PopoverContent shadow z-50")}
60
+ <PopoverPrimitive.Content className={cn(paperMixin, "PopoverContent shadow z-40", className)}
54
61
  side={side}
55
62
  sideOffset={sideOffset}
56
63
  align={align}
@@ -61,6 +61,7 @@ export const Sheet: React.FC<SheetProps> = ({
61
61
  {...props}
62
62
  className={cn(
63
63
  // "transform-gpu",
64
+ "will-change-transform",
64
65
  "text-gray-900 dark:text-white",
65
66
  "fixed transform z-20 transition-all duration-[240ms] ease-in-out",
66
67
  "outline-none focus:outline-none",