@firecms/core 3.0.0-canary.112 → 3.0.0-canary.113

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.
@@ -54,6 +54,7 @@ export interface SaveEntityProps<M extends Record<string, any> = any> {
54
54
  */
55
55
  export interface DeleteEntityProps<M extends Record<string, any> = any> {
56
56
  entity: Entity<M>;
57
+ collection?: EntityCollection<M> | ResolvedEntityCollection<M>;
57
58
  }
58
59
  /**
59
60
  * Component in charge of communicating with the data source.
@@ -122,21 +123,21 @@ export interface DataSource {
122
123
  * @param entity
123
124
  * @return was the whole deletion flow successful
124
125
  */
125
- deleteEntity<M extends Record<string, any> = any>({ entity }: DeleteEntityProps<M>): Promise<void>;
126
+ deleteEntity<M extends Record<string, any> = any>({ entity, collection }: DeleteEntityProps<M>): Promise<void>;
126
127
  /**
127
128
  * Check if the given property is unique in the given collection
128
129
  * @param path Collection path
129
130
  * @param name of the property
130
131
  * @param value
131
- * @param property
132
+ * @param collection
132
133
  * @param entityId
133
134
  * @return `true` if there are no other fields besides the given entity
134
135
  */
135
- checkUniqueField(path: string, name: string, value: any, entityId?: string, databaseId?: string): Promise<boolean>;
136
+ checkUniqueField(path: string, name: string, value: any, entityId?: string, collection?: EntityCollection): Promise<boolean>;
136
137
  /**
137
138
  * Generate an id for a new entity
138
139
  */
139
- generateEntityId(path: string): string;
140
+ generateEntityId(path: string, collection: EntityCollection): string;
140
141
  /**
141
142
  * Count the number of entities in a collection
142
143
  */
@@ -241,13 +242,14 @@ export interface DataSourceDelegate {
241
242
  * @param name of the property
242
243
  * @param value
243
244
  * @param entityId
245
+ * @param collection
244
246
  * @return `true` if there are no other fields besides the given entity
245
247
  */
246
- checkUniqueField(path: string, name: string, value: any, entityId?: string, databaseId?: string): Promise<boolean>;
248
+ checkUniqueField(path: string, name: string, value: any, entityId?: string, collection?: EntityCollection): Promise<boolean>;
247
249
  /**
248
250
  * Generate an id for a new entity
249
251
  */
250
- generateEntityId(path: string): string;
252
+ generateEntityId(path: string, collection?: EntityCollection): string;
251
253
  /**
252
254
  * Count the number of entities in a collection
253
255
  */
@@ -1,6 +1,6 @@
1
- import { DataSource } from "./datasource";
1
+ import { DataSourceDelegate } from "./datasource";
2
2
  import { StorageSource } from "./storage";
3
3
  export type EntityOverrides = {
4
- dataSource?: DataSource;
4
+ dataSourceDelegate?: DataSourceDelegate;
5
5
  storageSource?: StorageSource;
6
6
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@firecms/core",
3
3
  "type": "module",
4
- "version": "3.0.0-canary.112",
4
+ "version": "3.0.0-canary.113",
5
5
  "description": "Awesome Firebase/Firestore-based headless open-source CMS",
6
6
  "funding": {
7
7
  "url": "https://github.com/sponsors/firecmsco"
@@ -46,9 +46,9 @@
46
46
  "./package.json": "./package.json"
47
47
  },
48
48
  "dependencies": {
49
- "@firecms/editor": "^3.0.0-canary.112",
50
- "@firecms/formex": "^3.0.0-canary.112",
51
- "@firecms/ui": "^3.0.0-canary.112",
49
+ "@firecms/editor": "^3.0.0-canary.113",
50
+ "@firecms/formex": "^3.0.0-canary.113",
51
+ "@firecms/ui": "^3.0.0-canary.113",
52
52
  "@hello-pangea/dnd": "^16.6.0",
53
53
  "@radix-ui/react-portal": "^1.1.1",
54
54
  "clsx": "^2.1.1",
@@ -100,7 +100,7 @@
100
100
  "dist",
101
101
  "src"
102
102
  ],
103
- "gitHead": "da32db5185c6e867794209172c89cf9f92abc404",
103
+ "gitHead": "9593fe324c33f2ef657a8835fc925fd58157c135",
104
104
  "publishConfig": {
105
105
  "access": "public"
106
106
  },
@@ -306,7 +306,7 @@ export const EntityCollectionView = React.memo(
306
306
  value,
307
307
  property,
308
308
  entityId
309
- }) => dataSource.checkUniqueField(fullPath, name, value, entityId, collection.databaseId),
309
+ }) => dataSource.checkUniqueField(fullPath, name, value, entityId, collection),
310
310
  [fullPath]);
311
311
 
312
312
  const onValueChange: OnCellValueChange<any, any> = ({
@@ -109,6 +109,7 @@ export function ReferenceSelectionTable<M extends Record<string, any>>(
109
109
 
110
110
  const fullPath = navigation.resolveAliasesFrom(pathInput);
111
111
 
112
+ console.trace("Opening reference dialog for path " + fullPath);
112
113
  const dataSource = useDataSource(collection);
113
114
 
114
115
  const [entitiesDisplayedFirst, setEntitiesDisplayedFirst] = useState<Entity<any>[]>([]);
@@ -199,7 +199,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
199
199
  if (mustSetCustomId) {
200
200
  return undefined;
201
201
  } else {
202
- return dataSource.generateEntityId(path);
202
+ return dataSource.generateEntityId(path, collection);
203
203
  }
204
204
  } else {
205
205
  return entityIdProp;
@@ -675,7 +675,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
675
675
  name,
676
676
  value,
677
677
  property
678
- }) => dataSource.checkUniqueField(path, name, value, entityId, collection.databaseId),
678
+ }) => dataSource.checkUniqueField(path, name, value, entityId, collection),
679
679
  [dataSource, path, entityId]);
680
680
 
681
681
  const validationSchema = useMemo(() => entityId
@@ -104,11 +104,9 @@ function SideDialogView({
104
104
  };
105
105
 
106
106
  const onCloseRequest = (force?: boolean) => {
107
- console.log("onCloseRequest", blocked, force);
108
107
  if (blocked && !force) {
109
108
  setDrawerCloseRequested(true);
110
109
  } else {
111
- console.log("onCloseRequest closing");
112
110
  sideDialogsController.close();
113
111
  panel?.onClose?.();
114
112
  }
@@ -81,7 +81,8 @@ export async function deleteEntityWithCallbacks<M extends Record<string, any>, U
81
81
  }
82
82
  }
83
83
  return dataSource.deleteEntity({
84
- entity
84
+ entity,
85
+ collection
85
86
  }).then(() => {
86
87
  onDeleteSuccess && onDeleteSuccess(entity);
87
88
  try {
@@ -7,8 +7,16 @@ import { DataSourceContext } from "../../contexts/DataSourceContext";
7
7
  * @group Hooks and utilities
8
8
  */
9
9
  export const useDataSource = (collection?: EntityCollection<any, any>): DataSource => {
10
+ // const customizationController = useCustomizationController();
11
+ // const navigationController = useNavigationController();
10
12
  const defaultDataSource = useContext(DataSourceContext);
11
- if (collection?.overrides?.dataSource)
12
- return collection?.overrides.dataSource;
13
+ // if (collection?.overrides?.dataSourceDelegate) {
14
+ // console.trace("Using custom data source for collection " + collection.id);
15
+ // return useBuildDataSource({
16
+ // delegate: collection.overrides.dataSourceDelegate,
17
+ // propertyConfigs: customizationController?.propertyConfigs,
18
+ // navigationController: navigationController
19
+ // });
20
+ // }
13
21
  return defaultDataSource;
14
22
  };
@@ -19,7 +19,8 @@ import {
19
19
  import {
20
20
  applyPermissionsFunctionIfEmpty,
21
21
  getCollectionByPathOrId,
22
- mergeDeep, removeFunctions,
22
+ mergeDeep,
23
+ removeFunctions,
23
24
  removeInitialAndTrailingSlashes,
24
25
  resolveCollectionPathIds,
25
26
  resolvePermissions
@@ -61,7 +61,8 @@ export function useBuildDataSource({
61
61
  order,
62
62
  }: FetchCollectionProps<M>
63
63
  ): Promise<Entity<M>[]> => {
64
- return delegate.fetchCollection<M>({
64
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
65
+ return usedDelegate.fetchCollection<M>({
65
66
  path,
66
67
  filter,
67
68
  limit,
@@ -106,11 +107,12 @@ export function useBuildDataSource({
106
107
  ): () => void => {
107
108
 
108
109
  const collection = collectionProp ?? navigationController.getCollection(path);
109
- const isCollectionGroup = Boolean(collection?.collectionGroup);
110
- if (!delegate.listenCollection)
110
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
111
+
112
+ if (!usedDelegate.listenCollection)
111
113
  throw Error("useBuildDataSource delegate not initialised");
112
114
 
113
- return delegate.listenCollection<M>({
115
+ return usedDelegate.listenCollection<M>({
114
116
  path,
115
117
  filter,
116
118
  limit,
@@ -137,11 +139,14 @@ export function useBuildDataSource({
137
139
  entityId,
138
140
  collection
139
141
  }: FetchEntityProps<M>
140
- ): Promise<Entity<M> | undefined> => delegate.fetchEntity({
141
- path,
142
- entityId,
143
- collection
144
- }), [delegate]),
142
+ ): Promise<Entity<M> | undefined> => {
143
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
144
+ return usedDelegate.fetchEntity({
145
+ path,
146
+ entityId,
147
+ collection
148
+ });
149
+ }, [delegate.fetchEntity]),
145
150
 
146
151
  /**
147
152
  *
@@ -162,10 +167,12 @@ export function useBuildDataSource({
162
167
  onUpdate,
163
168
  onError
164
169
  }: ListenEntityProps<M>): () => void => {
165
- if (!delegate.listenEntity)
170
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
171
+
172
+ if (!usedDelegate.listenEntity)
166
173
  throw Error("useBuildDataSource delegate not initialised");
167
174
 
168
- return delegate.listenEntity<M>({
175
+ return usedDelegate.listenEntity<M>({
169
176
  path,
170
177
  entityId,
171
178
  onUpdate,
@@ -195,6 +202,7 @@ export function useBuildDataSource({
195
202
  }: SaveEntityProps<M>): Promise<Entity<M>> => {
196
203
 
197
204
  const collection = collectionProp ?? navigationController.getCollection(path);
205
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
198
206
 
199
207
  console.log("useBuildDatasource save", {
200
208
  path,
@@ -216,32 +224,32 @@ export function useBuildDataSource({
216
224
 
217
225
  const properties: ResolvedProperties<M> | undefined = resolvedCollection?.properties;
218
226
 
219
- const firestoreValues = delegate.cmsToDelegateModel(
227
+ const firestoreValues = usedDelegate.cmsToDelegateModel(
220
228
  values,
221
229
  );
222
230
 
223
- const updatedFirestoreValues: EntityValues<M> = properties
231
+ const updatedValues: EntityValues<M> = properties
224
232
  ? updateDateAutoValues(
225
233
  {
226
234
  inputValues: firestoreValues,
227
235
  properties,
228
236
  status,
229
- timestampNowValue: delegate.currentTime?.() ?? new Date(),
230
- setDateToMidnight: delegate.setDateToMidnight
237
+ timestampNowValue: usedDelegate.currentTime?.() ?? new Date(),
238
+ setDateToMidnight: usedDelegate.setDateToMidnight
231
239
  })
232
240
  : firestoreValues;
233
241
 
234
- return delegate.saveEntity({
242
+ return usedDelegate.saveEntity({
235
243
  path,
236
244
  collection,
237
245
  entityId,
238
- values: updatedFirestoreValues,
246
+ values: updatedValues,
239
247
  status
240
248
  }).then((res) => {
241
249
  return {
242
250
  id: res.id,
243
251
  path: res.path,
244
- values: delegate.delegateToCMSModel(updatedFirestoreValues)
252
+ values: usedDelegate.delegateToCMSModel(updatedValues)
245
253
  } as Entity<M>;
246
254
  });
247
255
  }, [delegate.saveEntity, navigationController.getCollection]),
@@ -254,10 +262,12 @@ export function useBuildDataSource({
254
262
  */
255
263
  deleteEntity: useCallback(<M extends Record<string, any>>(
256
264
  {
257
- entity
265
+ entity,
266
+ collection
258
267
  }: DeleteEntityProps<M>
259
268
  ): Promise<void> => {
260
- return delegate.deleteEntity({ entity });
269
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
270
+ return usedDelegate.deleteEntity({ entity, collection });
261
271
  }, [delegate.deleteEntity]),
262
272
 
263
273
  /**
@@ -275,13 +285,15 @@ export function useBuildDataSource({
275
285
  name: string,
276
286
  value: any,
277
287
  entityId?: string,
278
- databaseId?: string
288
+ collection?: EntityCollection
279
289
  ): Promise<boolean> => {
280
- return delegate.checkUniqueField(path, name, value, entityId, databaseId);
290
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
291
+ return usedDelegate.checkUniqueField(path, name, value, entityId, collection);
281
292
  }, [delegate.checkUniqueField]),
282
293
 
283
- generateEntityId: useCallback((path: string): string => {
284
- return delegate.generateEntityId(path,);
294
+ generateEntityId: useCallback((path: string, collection: EntityCollection): string => {
295
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
296
+ return usedDelegate.generateEntityId(path, collection);
285
297
  }, [delegate.generateEntityId]),
286
298
 
287
299
  countEntities: delegate.countEntities ? async ({
@@ -297,7 +309,8 @@ export function useBuildDataSource({
297
309
  orderBy?: string,
298
310
  order?: "desc" | "asc",
299
311
  }): Promise<number> => {
300
- return delegate.countEntities!({
312
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
313
+ return usedDelegate.countEntities!({
301
314
  path,
302
315
  filter,
303
316
  orderBy,
@@ -335,51 +348,12 @@ export function useBuildDataSource({
335
348
  collection: EntityCollection,
336
349
  parentCollectionIds?: string[]
337
350
  }): Promise<boolean> => {
338
- if (!delegate.initTextSearch)
351
+ const usedDelegate = props.collection?.overrides?.dataSourceDelegate ?? delegate;
352
+ if (!usedDelegate.initTextSearch)
339
353
  return false;
340
- return delegate.initTextSearch(props)
354
+ return usedDelegate.initTextSearch(props)
341
355
  }, [delegate.initTextSearch]),
342
356
 
343
357
  };
344
358
 
345
359
  }
346
-
347
- // /**
348
- // * Recursive function that converts Firestore data types into CMS or plain
349
- // * JS types.
350
- // * FireCMS uses Javascript dates internally instead of Firestore timestamps.
351
- // * This makes it easier to interact with the rest of the libraries and
352
- // * bindings.
353
- // * Also, Firestore references are replaced with {@link EntityReference}
354
- // * @param data
355
- // * @param buildReference
356
- // * @param buildGeoPoint
357
- // * @param buildDate
358
- // * @param buildDelete
359
- // * @group Firestore
360
- // */
361
- // export function cmsToDelegateModel(data: any,
362
- // buildReference: (reference: EntityReference) => any,
363
- // buildGeoPoint: (geoPoint: GeoPoint) => any,
364
- // buildDate: (date: Date) => any,
365
- // buildDelete: () => any
366
- // ): any {
367
- // if (data === undefined) {
368
- // return buildDelete();
369
- // } else if (data === null) {
370
- // return null;
371
- // } else if (Array.isArray(data)) {
372
- // return data.map(v => cmsToDelegateModel(v, buildReference, buildGeoPoint, buildDate, buildDelete));
373
- // } else if (data.isEntityReference && data.isEntityReference()) {
374
- // return buildReference(data);
375
- // } else if (data instanceof GeoPoint) {
376
- // return buildGeoPoint(data);
377
- // } else if (data instanceof Date) {
378
- // return buildDate(data);
379
- // } else if (data && typeof data === "object") {
380
- // return Object.entries(data)
381
- // .map(([key, v]) => ({ [key]: cmsToDelegateModel(v, buildReference, buildGeoPoint, buildDate, buildDelete) }))
382
- // .reduce((a, b) => ({ ...a, ...b }), {});
383
- // }
384
- // return data;
385
- // }
@@ -64,6 +64,7 @@ export interface SaveEntityProps<M extends Record<string, any> = any> {
64
64
  */
65
65
  export interface DeleteEntityProps<M extends Record<string, any> = any> {
66
66
  entity: Entity<M>;
67
+ collection?: EntityCollection<M> | ResolvedEntityCollection<M>;
67
68
  }
68
69
 
69
70
  /**
@@ -182,7 +183,8 @@ export interface DataSource {
182
183
  */
183
184
  deleteEntity<M extends Record<string, any> = any>(
184
185
  {
185
- entity
186
+ entity,
187
+ collection
186
188
  }: DeleteEntityProps<M>
187
189
  ): Promise<void>;
188
190
 
@@ -191,7 +193,7 @@ export interface DataSource {
191
193
  * @param path Collection path
192
194
  * @param name of the property
193
195
  * @param value
194
- * @param property
196
+ * @param collection
195
197
  * @param entityId
196
198
  * @return `true` if there are no other fields besides the given entity
197
199
  */
@@ -200,13 +202,13 @@ export interface DataSource {
200
202
  name: string,
201
203
  value: any,
202
204
  entityId?: string,
203
- databaseId?: string
205
+ collection?: EntityCollection
204
206
  ): Promise<boolean>;
205
207
 
206
208
  /**
207
209
  * Generate an id for a new entity
208
210
  */
209
- generateEntityId(path: string): string;
211
+ generateEntityId(path: string, collection: EntityCollection): string;
210
212
 
211
213
  /**
212
214
  * Count the number of entities in a collection
@@ -360,14 +362,15 @@ export interface DataSourceDelegate {
360
362
  * @param name of the property
361
363
  * @param value
362
364
  * @param entityId
365
+ * @param collection
363
366
  * @return `true` if there are no other fields besides the given entity
364
367
  */
365
- checkUniqueField(path: string, name: string, value: any, entityId?: string, databaseId?: string): Promise<boolean>;
368
+ checkUniqueField(path: string, name: string, value: any, entityId?: string, collection?: EntityCollection): Promise<boolean>;
366
369
 
367
370
  /**
368
371
  * Generate an id for a new entity
369
372
  */
370
- generateEntityId(path: string): string;
373
+ generateEntityId(path: string, collection?: EntityCollection): string;
371
374
 
372
375
  /**
373
376
  * Count the number of entities in a collection
@@ -1,7 +1,7 @@
1
- import { DataSource } from "./datasource";
1
+ import { DataSource, DataSourceDelegate } from "./datasource";
2
2
  import { StorageSource } from "./storage";
3
3
 
4
4
  export type EntityOverrides = {
5
- dataSource?: DataSource;
5
+ dataSourceDelegate?: DataSourceDelegate;
6
6
  storageSource?: StorageSource;
7
7
  };