@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.
- package/dist/components/Popover.d.ts +3 -1
- package/dist/core/FireCMS.d.ts +2 -2
- package/dist/core/builders.d.ts +5 -5
- package/dist/core/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +4 -2
- package/dist/core/components/EntityCollectionTable/filters/ReferenceFilterField.d.ts +3 -3
- package/dist/core/components/EntityCollectionTable/internal/EntityCollectionRowActions.d.ts +15 -11
- package/dist/core/components/EntityCollectionTable/internal/default_entity_actions.d.ts +5 -0
- package/dist/core/components/EntityCollectionTable/types.d.ts +1 -37
- package/dist/core/components/FieldConfigBadge.d.ts +3 -3
- package/dist/core/components/VirtualTable/VirtualTableHeader.d.ts +2 -2
- package/dist/core/components/VirtualTable/VirtualTableProps.d.ts +1 -1
- package/dist/core/contexts/DialogsProvider.d.ts +4 -0
- package/dist/core/form_field_configs.d.ts +3 -3
- package/dist/core/index.d.ts +1 -1
- package/dist/core/internal/useBuildNavigationContext.d.ts +3 -3
- package/dist/core/util/property_utils.d.ts +5 -5
- package/dist/core/util/references.d.ts +2 -2
- package/dist/core/util/resolutions.d.ts +6 -6
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/useBuildDataSource.d.ts +23 -0
- package/dist/hooks/useDialogsController.d.ts +11 -0
- package/dist/index.es.js +8996 -8583
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +67 -67
- package/dist/index.umd.js.map +1 -1
- package/dist/styles.d.ts +1 -1
- package/dist/types/collections.d.ts +36 -13
- package/dist/types/datasource.d.ts +120 -11
- package/dist/types/dialogs_controller.d.ts +30 -0
- package/dist/types/entity_actions.d.ts +33 -0
- package/dist/types/fields.d.ts +1 -1
- package/dist/types/firecms.d.ts +8 -8
- package/dist/types/firecms_context.d.ts +10 -3
- package/dist/types/index.d.ts +2 -1
- package/dist/types/navigation.d.ts +3 -3
- package/dist/types/plugins.d.ts +11 -10
- package/dist/types/properties.d.ts +1 -1
- package/dist/types/{field_config.d.ts → property_config.d.ts} +3 -4
- package/package.json +3 -3
- package/src/components/Popover.tsx +10 -3
- package/src/components/Sheet.tsx +1 -0
- package/src/components/TextareaAutosize.tsx +2 -1
- package/src/core/FireCMS.tsx +9 -6
- package/src/core/builders.ts +11 -11
- package/src/core/components/ArrayContainer.tsx +1 -1
- package/src/core/components/EntityCollectionTable/EntityCollectionTable.tsx +20 -13
- package/src/core/components/EntityCollectionTable/EntityCollectionTableProps.tsx +5 -2
- package/src/core/components/EntityCollectionTable/filters/ReferenceFilterField.tsx +11 -6
- package/src/core/components/EntityCollectionTable/internal/EntityCollectionRowActions.tsx +96 -79
- package/src/core/components/EntityCollectionTable/internal/PropertyTableCell.tsx +2 -2
- package/src/core/components/EntityCollectionTable/internal/default_entity_actions.tsx +107 -0
- package/src/core/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +6 -2
- package/src/core/components/EntityCollectionTable/types.tsx +1 -56
- package/src/core/components/EntityCollectionView/EntityCollectionView.tsx +67 -43
- package/src/core/components/FieldConfigBadge.tsx +4 -4
- package/src/core/components/ReferenceSelectionInner.tsx +2 -2
- package/src/core/components/VirtualTable/VirtualTable.tsx +4 -6
- package/src/core/components/VirtualTable/VirtualTableHeader.tsx +21 -18
- package/src/core/components/VirtualTable/VirtualTableProps.tsx +1 -1
- package/src/core/contexts/DialogsProvider.tsx +50 -0
- package/src/core/form_field_configs.tsx +5 -5
- package/src/core/index.tsx +1 -1
- package/src/core/internal/useBuildNavigationContext.tsx +13 -13
- package/src/core/internal/useBuildSideEntityController.tsx +9 -1
- package/src/core/util/property_utils.tsx +5 -5
- package/src/core/util/references.ts +2 -2
- package/src/core/util/resolutions.ts +16 -11
- package/src/form/EntityForm.tsx +64 -7
- package/src/form/PropertyFieldBinding.tsx +4 -4
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +1 -1
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +4 -6
- package/src/hooks/index.tsx +1 -0
- package/src/hooks/useBuildDataSource.ts +351 -0
- package/src/hooks/useDialogsController.tsx +14 -0
- package/src/hooks/useFireCMSContext.tsx +5 -11
- package/src/preview/property_previews/StringPropertyPreview.tsx +4 -2
- package/src/styles.ts +1 -1
- package/src/types/collections.ts +36 -17
- package/src/types/datasource.ts +174 -10
- package/src/types/dialogs_controller.tsx +31 -0
- package/src/types/entity_actions.tsx +36 -0
- package/src/types/fields.tsx +1 -1
- package/src/types/firecms.tsx +8 -8
- package/src/types/firecms_context.tsx +11 -3
- package/src/types/index.ts +2 -1
- package/src/types/navigation.ts +3 -3
- package/src/types/plugins.tsx +11 -10
- package/src/types/properties.ts +1 -1
- package/src/types/{field_config.tsx → property_config.tsx} +3 -4
- /package/dist/core/contexts/{SnackbarContext.d.ts → SnackbarProvider.d.ts} +0 -0
- /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,
|
|
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
|
|
52
|
-
* https://
|
|
53
|
-
* e.g. '
|
|
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
|
|
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<
|
|
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,
|
|
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
|
-
*
|
|
212
|
-
*
|
|
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,
|
|
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:
|
|
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
|
|
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,
|
|
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
|
|
146
|
-
*/
|
|
147
|
-
isFilterCombinationValid?(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
+
};
|
package/dist/types/fields.d.ts
CHANGED
|
@@ -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 =
|
|
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"
|
package/dist/types/firecms.d.ts
CHANGED
|
@@ -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 {
|
|
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
|
-
}) =>
|
|
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?:
|
|
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 `
|
|
80
|
+
* the `propertyConfig` prop of a property in a collection.
|
|
81
81
|
*/
|
|
82
|
-
fields?: Record<string,
|
|
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 {
|
|
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 `
|
|
91
|
+
* the `propertyConfig` prop of a property in a collection.
|
|
85
92
|
*/
|
|
86
|
-
fields: Record<string,
|
|
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
|
package/dist/types/index.d.ts
CHANGED
|
@@ -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 "./
|
|
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
|
|
131
|
-
* https://
|
|
132
|
-
* e.g. '
|
|
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
|
/**
|
package/dist/types/plugins.d.ts
CHANGED
|
@@ -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
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
|
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
|
|
8
|
+
export type PropertyConfig<T extends CMSType = any> = {
|
|
10
9
|
/**
|
|
11
|
-
* Key used to identify this
|
|
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.
|
|
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": "^
|
|
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": "
|
|
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}
|
|
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-
|
|
60
|
+
<PopoverPrimitive.Content className={cn(paperMixin, "PopoverContent shadow z-40", className)}
|
|
54
61
|
side={side}
|
|
55
62
|
sideOffset={sideOffset}
|
|
56
63
|
align={align}
|
package/src/components/Sheet.tsx
CHANGED
|
@@ -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",
|