@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
@@ -0,0 +1,351 @@
1
+ import { useCallback } from "react";
2
+ import {
3
+ DataSource,
4
+ DataSourceDelegate, DeleteEntityProps,
5
+ Entity,
6
+ EntityCollection,
7
+ EntityReference,
8
+ EntityValues,
9
+ FetchCollectionProps,
10
+ FetchEntityProps,
11
+ FilterValues,
12
+ GeoPoint,
13
+ ListenCollectionProps,
14
+ ListenEntityProps,
15
+ PropertyConfig,
16
+ ResolvedProperties,
17
+ SaveEntityProps
18
+ } from "../types";
19
+ import { resolveCollection, updateDateAutoValues } from "../core";
20
+
21
+ /**
22
+ * Use this hook to build a {@link DataSource} based on Firestore
23
+ * @param firebaseApp
24
+ * @param textSearchController
25
+ * @param collectionRegistry
26
+ * @category Firebase
27
+ */
28
+ export function useBuildDataSource({
29
+ delegate,
30
+ customFields
31
+ }: {
32
+ delegate: DataSourceDelegate,
33
+ customFields: Record<string, PropertyConfig>;
34
+ }): DataSource {
35
+
36
+ return {
37
+
38
+ /**
39
+ * Fetch entities in a Firestore path
40
+ * @param path
41
+ * @param collection
42
+ * @param filter
43
+ * @param limit
44
+ * @param startAfter
45
+ * @param searchString
46
+ * @param orderBy
47
+ * @param order
48
+ * @return Function to cancel subscription
49
+ * @see useCollectionFetch if you need this functionality implemented as a hook
50
+ * @category Firestore
51
+ */
52
+ fetchCollection: useCallback(<M extends Record<string, any>>({
53
+ path,
54
+ collection,
55
+ filter,
56
+ limit,
57
+ startAfter,
58
+ searchString,
59
+ orderBy,
60
+ order
61
+ }: FetchCollectionProps<M>
62
+ ): Promise<Entity<M>[]> => {
63
+
64
+ return delegate.fetchCollection<M>({
65
+ path,
66
+ filter,
67
+ limit,
68
+ startAfter,
69
+ searchString,
70
+ orderBy,
71
+ order
72
+ });
73
+ }, [delegate]),
74
+
75
+ /**
76
+ * Listen to a entities in a given path
77
+ * @param path
78
+ * @param collection
79
+ * @param onError
80
+ * @param filter
81
+ * @param limit
82
+ * @param startAfter
83
+ * @param searchString
84
+ * @param orderBy
85
+ * @param order
86
+ * @param onUpdate
87
+ * @return Function to cancel subscription
88
+ * @see useCollectionFetch if you need this functionality implemented as a hook
89
+ * @category Firestore
90
+ */
91
+ listenCollection: delegate.listenCollection
92
+ // eslint-disable-next-line react-hooks/rules-of-hooks
93
+ ? useCallback(<M extends Record<string, any>>(
94
+ {
95
+ path,
96
+ collection,
97
+ filter,
98
+ limit,
99
+ startAfter,
100
+ searchString,
101
+ orderBy,
102
+ order,
103
+ onUpdate,
104
+ onError
105
+ }: ListenCollectionProps<M>
106
+ ): () => void => {
107
+
108
+ const isCollectionGroup = Boolean(collection.collectionGroup) ?? false;
109
+ if (!delegate.listenCollection)
110
+ throw Error("useBuildDataSource delegate not initialised");
111
+
112
+ return delegate.listenCollection<M>({
113
+ path,
114
+ filter,
115
+ limit,
116
+ startAfter,
117
+ searchString,
118
+ orderBy,
119
+ order,
120
+ onUpdate,
121
+ onError,
122
+ isCollectionGroup
123
+ });
124
+ }, [delegate])
125
+ : undefined,
126
+
127
+ /**
128
+ * Retrieve an entity given a path and a collection
129
+ * @param path
130
+ * @param entityId
131
+ * @param collection
132
+ * @category Firestore
133
+ */
134
+ fetchEntity: useCallback(<M extends Record<string, any>>({
135
+ path,
136
+ entityId
137
+ }: FetchEntityProps<M>
138
+ ): Promise<Entity<M> | undefined> => delegate.fetchEntity({
139
+ path,
140
+ entityId
141
+ }), [delegate]),
142
+
143
+ /**
144
+ *
145
+ * @param path
146
+ * @param entityId
147
+ * @param collection
148
+ * @param onUpdate
149
+ * @param onError
150
+ * @return Function to cancel subscription
151
+ * @category Firestore
152
+ */
153
+ listenEntity: delegate.listenEntity
154
+ // eslint-disable-next-line react-hooks/rules-of-hooks
155
+ ? useCallback(<M extends Record<string, any>>(
156
+ {
157
+ path,
158
+ entityId,
159
+ collection,
160
+ onUpdate,
161
+ onError
162
+ }: ListenEntityProps<M>): () => void => {
163
+ if (!delegate.listenEntity)
164
+ throw Error("useBuildDataSource delegate not initialised");
165
+
166
+ return delegate.listenEntity<M>({
167
+ path,
168
+ entityId,
169
+ onUpdate,
170
+ onError
171
+ })
172
+ }, [delegate.listenEntity]) : undefined,
173
+
174
+ /**
175
+ * Save entity to the specified path. Note that Firestore does not allow
176
+ * undefined values.
177
+ * @param path
178
+ * @param entityId
179
+ * @param values
180
+ * @param schemaId
181
+ * @param collection
182
+ * @param status
183
+ * @category Firestore
184
+ */
185
+ saveEntity: useCallback(<M extends Record<string, any>>(
186
+ {
187
+ path,
188
+ entityId,
189
+ values,
190
+ collection,
191
+ status
192
+ }: SaveEntityProps<M>): Promise<Entity<M>> => {
193
+
194
+ const resolvedCollection = resolveCollection<M>({
195
+ collection,
196
+ path,
197
+ entityId,
198
+ fields: customFields
199
+ });
200
+
201
+ const properties: ResolvedProperties<M> = resolvedCollection.properties;
202
+
203
+ const firestoreValues = cmsToDelegateModel(
204
+ values,
205
+ delegate.buildReference,
206
+ delegate.buildGeoPoint,
207
+ delegate.buildDate,
208
+ delegate.buildDeleteFieldValue
209
+ );
210
+ const updatedFirestoreValues: EntityValues<M> = updateDateAutoValues(
211
+ {
212
+ inputValues: firestoreValues,
213
+ properties,
214
+ status,
215
+ timestampNowValue: delegate.currentTime(),
216
+ setDateToMidnight: delegate.setDateToMidnight
217
+ });
218
+
219
+ console.debug("Saving entity", path, entityId, updatedFirestoreValues);
220
+
221
+ return delegate.saveEntity({
222
+ path,
223
+ entityId,
224
+ values: updatedFirestoreValues,
225
+ status
226
+ }).then((res) => {
227
+ return {
228
+ id: res.id,
229
+ path: res.path,
230
+ values: delegate.delegateToCMSModel(updatedFirestoreValues)
231
+ } as Entity<M>;
232
+ });
233
+ }, [delegate.saveEntity]),
234
+
235
+ /**
236
+ * Delete an entity
237
+ * @param entity
238
+ * @param collection
239
+ * @category Firestore
240
+ */
241
+ deleteEntity: useCallback(<M extends Record<string, any>>(
242
+ {
243
+ entity
244
+ }: DeleteEntityProps<M>
245
+ ): Promise<void> => {
246
+ return delegate.deleteEntity({entity});
247
+ }, [delegate.deleteEntity]),
248
+
249
+ /**
250
+ * Check if the given property is unique in the given collection
251
+ * @param path Collection path
252
+ * @param name of the property
253
+ * @param value
254
+ * @param property
255
+ * @param entityId
256
+ * @return `true` if there are no other fields besides the given entity
257
+ * @category Firestore
258
+ */
259
+ checkUniqueField: useCallback((
260
+ path: string,
261
+ name: string,
262
+ value: any,
263
+ entityId?: string
264
+ ): Promise<boolean> => {
265
+ return delegate.checkUniqueField(path, name, value, entityId);
266
+ }, [delegate.checkUniqueField]),
267
+
268
+ generateEntityId: useCallback((path: string): string => {
269
+ return delegate.generateEntityId(path, );
270
+ }, [delegate.generateEntityId]),
271
+
272
+ countEntities: useCallback(async ({
273
+ path,
274
+ collection,
275
+ filter,
276
+ order,
277
+ orderBy
278
+ }: {
279
+ path: string,
280
+ collection: EntityCollection<any>,
281
+ filter?: FilterValues<Extract<keyof any, string>>,
282
+ orderBy?: string,
283
+ order?: "desc" | "asc",
284
+ }): Promise<number> => {
285
+ return delegate.countEntities({
286
+ path,
287
+ filter,
288
+ orderBy,
289
+ order,
290
+ isCollectionGroup: Boolean(collection.collectionGroup) ?? false
291
+ });
292
+ }, [delegate.countEntities]),
293
+
294
+ isFilterCombinationValid: useCallback(({
295
+ path,
296
+ filterValues,
297
+ sortBy
298
+ }: {
299
+ path: string,
300
+ filterValues: FilterValues<any>,
301
+ sortBy?: [string, "asc" | "desc"]
302
+ }): boolean => {
303
+ if (!delegate.isFilterCombinationValid)
304
+ return true;
305
+ return delegate.isFilterCombinationValid(
306
+ {
307
+ path,
308
+ filterValues,
309
+ sortBy
310
+ }
311
+ )
312
+ }, [delegate.isFilterCombinationValid])
313
+
314
+ };
315
+
316
+ }
317
+
318
+ /**
319
+ * Recursive function that converts Firestore data types into CMS or plain
320
+ * JS types.
321
+ * FireCMS uses Javascript dates internally instead of Firestore timestamps.
322
+ * This makes it easier to interact with the rest of the libraries and
323
+ * bindings.
324
+ * Also, Firestore references are replaced with {@link EntityReference}
325
+ * @param data
326
+ * @category Firestore
327
+ */
328
+ export function cmsToDelegateModel(data: any,
329
+ buildReference: (reference: EntityReference) => any,
330
+ buildGeoPoint: (geoPoint: GeoPoint) => any,
331
+ buildDate: (date: Date) => any,
332
+ buildDelete: () => any
333
+ ): any {
334
+ if (data === undefined) {
335
+ return buildDelete();
336
+ } else if (Array.isArray(data)) {
337
+ return data.map(v => cmsToDelegateModel(v, buildReference, buildGeoPoint, buildDate, buildDelete));
338
+ } else if (data instanceof EntityReference) {
339
+ return buildReference(data);
340
+ } else if (data instanceof GeoPoint) {
341
+ return buildGeoPoint(data);
342
+ } else if (data instanceof Date) {
343
+ return buildDate(data);
344
+ } else if (data && typeof data === "object") {
345
+ return Object.entries(data)
346
+ .map(([key, v]) => ({ [key]: cmsToDelegateModel(v, buildReference, buildGeoPoint, buildDate, buildDelete) }))
347
+ .reduce((a, b) => ({ ...a, ...b }), {});
348
+ }
349
+ return data;
350
+ }
351
+
@@ -0,0 +1,14 @@
1
+ import { useContext } from "react";
2
+ import { DialogsController } from "../types/dialogs_controller";
3
+ import { DialogsControllerContext } from "../core/contexts/DialogsProvider";
4
+
5
+ /**
6
+ * Use this hook to open a dialog imperatively.
7
+ * Alternatively, you can use dialogs declaratively using the `Dialog` component.
8
+ *
9
+ * Consider that in order to use this hook you need to have a parent
10
+ * `FireCMS`
11
+ *
12
+ * @category Hooks and utilities
13
+ */
14
+ export const useDialogsController = (): DialogsController => useContext(DialogsControllerContext);
@@ -8,17 +8,9 @@ import { useDataSource } from "./data/useDataSource";
8
8
  import { useStorageSource } from "./useStorageSource";
9
9
  import { useSnackbarController } from "./useSnackbarController";
10
10
  import { useUserConfigurationPersistence } from "./useUserConfigurationPersistence";
11
+ import { useDialogsController } from "./useDialogsController";
11
12
 
12
- export const FireCMSContextInstance = createContext<Partial<FireCMSContext>>({
13
- sideDialogsController: {} as any,
14
- sideEntityController: {} as any,
15
- navigation: {} as any,
16
- dataSource: {} as any,
17
- storageSource: {} as any,
18
- authController: {} as any,
19
- snackbarController: {} as any,
20
- fields: {}
21
- });
13
+ export const FireCMSContextInstance = createContext<Partial<FireCMSContext>>({});
22
14
 
23
15
  /**
24
16
  * Hook to retrieve the {@link FireCMSContext}.
@@ -40,6 +32,7 @@ export const useFireCMSContext = <UserType extends User = User, AuthControllerTy
40
32
  const storageSource = useStorageSource();
41
33
  const snackbarController = useSnackbarController();
42
34
  const userConfigPersistence = useUserConfigurationPersistence();
35
+ const dialogsController = useDialogsController();
43
36
 
44
37
  return {
45
38
  ...partialContext,
@@ -50,7 +43,8 @@ export const useFireCMSContext = <UserType extends User = User, AuthControllerTy
50
43
  dataSource,
51
44
  storageSource,
52
45
  snackbarController,
53
- userConfigPersistence
46
+ userConfigPersistence,
47
+ dialogsController
54
48
  }
55
49
 
56
50
  };
@@ -45,13 +45,15 @@ export function StringPropertyPreview({
45
45
  if (!value) return <></>;
46
46
  const lines = value.split("\n");
47
47
  return value && value.includes("\n")
48
- ? <div>
48
+ ? <div className={"overflow-x-scroll"}>
49
49
  {lines.map((str, index) =>
50
50
  <React.Fragment key={`string_preview_${index}`}>
51
51
  <span>{str}</span>
52
52
  {index !== lines.length - 1 && <br/>}
53
53
  </React.Fragment>)}
54
54
  </div>
55
- : <>{value}</>;
55
+ : <>
56
+ {value}
57
+ </>;
56
58
  }
57
59
  }
package/src/styles.ts CHANGED
@@ -1,4 +1,4 @@
1
- export 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 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 const focusedInvisibleMixin = "focus:bg-opacity-70 focus:bg-gray-100 focus:dark:bg-gray-800 focus:dark:bg-opacity-60";
3
3
  export const focusedClasses = "z-30 outline-none ring-2 ring-primary ring-opacity-75 ring-offset-2 ring-offset-transparent ";
4
4
  export 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
  /**
11
12
  * This interface represents a view that includes a collection of entities.
@@ -14,9 +15,7 @@ import { FormContext } from "./fields";
14
15
  *
15
16
  * @category Models
16
17
  */
17
- export interface EntityCollection<M extends Record<string, any> = any,
18
- AdditionalKey extends string = string,
19
- UserType extends User = User> {
18
+ export interface EntityCollection<M extends Record<string, any> = any, UserType extends User = User> {
20
19
 
21
20
  /**
22
21
  * Name of the collection, typically plural.
@@ -58,9 +57,9 @@ export interface EntityCollection<M extends Record<string, any> = any,
58
57
 
59
58
  /**
60
59
  * Icon key to use in this collection.
61
- * You can use any of the icons in the MUI specs:
62
- * https://mui.com/material-ui/material-icons/
63
- * e.g. 'AccountTree' or 'Person'
60
+ * You can use any of the icons in the Material specs:
61
+ * https://fonts.google.com/icons
62
+ * e.g. 'account_tree' or 'person'
64
63
  */
65
64
  icon?: string;
66
65
 
@@ -93,7 +92,7 @@ export interface EntityCollection<M extends Record<string, any> = any,
93
92
  * - If you are using a collection group, you will also have an
94
93
  * additional `collectionGroupParent` column.
95
94
  */
96
- propertiesOrder?: Extract<keyof M | AdditionalKey, string>[];
95
+ propertiesOrder?: Extract<keyof M, string>[];
97
96
 
98
97
  /**
99
98
  * If enabled, content is loaded in batches. If `false` all entities in the
@@ -113,7 +112,7 @@ export interface EntityCollection<M extends Record<string, any> = any,
113
112
  * Permissions the logged-in user can perform on this collection.
114
113
  * If not specified everything defaults to `true`.
115
114
  */
116
- permissions?: Permissions | PermissionsBuilder<EntityCollection<M>, UserType, M>;
115
+ permissions?: Permissions | PermissionsBuilder<any, UserType, M>;
117
116
 
118
117
  /**
119
118
  * Are the entities in this collection selectable. Defaults to `true`
@@ -140,6 +139,31 @@ export interface EntityCollection<M extends Record<string, any> = any,
140
139
  */
141
140
  Actions?: React.ComponentType<CollectionActionsProps> | React.ComponentType<CollectionActionsProps>[];
142
141
 
142
+ /**
143
+ * You can define additional actions that can be performed on the entities
144
+ * in this collection. These actions can be displayed in the collection
145
+ * view or in the entity view.
146
+ *
147
+ * You can use the `onClick` method to implement your own logic.
148
+ * In the `context` prop you can access all the controllers of FireCMS.
149
+ *
150
+ * ```
151
+ * const archiveEntityAction: EntityAction = {
152
+ * icon: <ArchiveIcon/>,
153
+ * name: "Archive",
154
+ * onClick({
155
+ * entity,
156
+ * collection,
157
+ * context,
158
+ * }): Promise<void> {
159
+ * // Add your code here
160
+ * return Promise.resolve(undefined);
161
+ * }
162
+ * }
163
+ * ```
164
+ */
165
+ entityActions?: EntityAction<M, UserType>[];
166
+
143
167
  /**
144
168
  * Pass your own selection controller if you want to control selected
145
169
  * entities externally.
@@ -190,8 +214,7 @@ export interface EntityCollection<M extends Record<string, any> = any,
190
214
  * You can add additional fields to the collection view by implementing
191
215
  * an additional field delegate.
192
216
  */
193
- additionalFields?: AdditionalFieldDelegate<M, AdditionalKey, UserType>[];
194
-
217
+ additionalFields?: AdditionalFieldDelegate<M, UserType>[];
195
218
 
196
219
  /**
197
220
  * Default size of the rendered collection
@@ -245,10 +268,8 @@ export interface EntityCollection<M extends Record<string, any> = any,
245
268
 
246
269
  /**
247
270
  * Parameter passed to the `Actions` prop in the collection configuration.
248
- * Note that actions are rendered in the collection toolbar, as well
249
- * as in the home page card.
250
- * If you don't want to render the actions in the home page card, you can
251
- * return `null` if mode is `home`.
271
+ * The component will receive this prop when it is rendered in the collection
272
+ * toolbar.
252
273
  *
253
274
  * @category Models
254
275
  */
@@ -349,7 +370,6 @@ export type FilterCombination<Key extends string> = Partial<Record<Key, "asc" |
349
370
  */
350
371
  export type CollectionSize = "xs" | "s" | "m" | "l" | "xl";
351
372
 
352
-
353
373
  export type AdditionalFieldDelegateProps<M extends Record<string, any> = any, UserType extends User = User> = {
354
374
  entity: Entity<M>,
355
375
  context: FireCMSContext<UserType>
@@ -361,14 +381,13 @@ export type AdditionalFieldDelegateProps<M extends Record<string, any> = any, Us
361
381
  * @category Models
362
382
  */
363
383
  export interface AdditionalFieldDelegate<M extends Record<string, any> = any,
364
- AdditionalKey extends string = string,
365
384
  UserType extends User = User> {
366
385
 
367
386
  /**
368
387
  * ID of this column. You can use this id in the `properties` field of the
369
388
  * collection in any order you want
370
389
  */
371
- id: AdditionalKey;
390
+ id: string;
372
391
 
373
392
  /**
374
393
  * Header of this column