@firecms/core 3.0.0-alpha.54 → 3.0.0-alpha.56

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firecms/core",
3
- "version": "3.0.0-alpha.54",
3
+ "version": "3.0.0-alpha.56",
4
4
  "description": "Awesome Firebase/Firestore-based headless open-source CMS",
5
5
  "funding": {
6
6
  "url": "https://github.com/sponsors/firecmsco"
@@ -45,7 +45,7 @@
45
45
  "generateIcons": "ts-node --esm src/icons/generateIcons.ts"
46
46
  },
47
47
  "dependencies": {
48
- "@firecms/ui": "^3.0.0-alpha.54",
48
+ "@firecms/ui": "^3.0.0-alpha.56",
49
49
  "@fontsource/ibm-plex-mono": "^5.0.8",
50
50
  "@fontsource/roboto": "^5.0.8",
51
51
  "@hello-pangea/dnd": "^16.5.0",
@@ -116,7 +116,7 @@
116
116
  "dist",
117
117
  "src"
118
118
  ],
119
- "gitHead": "9955c4f6403138fb68a54d6cbaf2c22d92fe85ce",
119
+ "gitHead": "a03621e95fe5b24491289fb9c3b5d71ec8e0c90d",
120
120
  "publishConfig": {
121
121
  "access": "public"
122
122
  }
@@ -184,7 +184,7 @@ export function ArrayContainer<T>({
184
184
 
185
185
  {includeAddButton && <div className="py-4 justify-center text-left">
186
186
  <Button
187
- variant={size === "small" ? "text" : "outlined"}
187
+ variant={"text"}
188
188
  size={size === "small" ? "small" : "medium"}
189
189
  color="primary"
190
190
  disabled={disabled}
@@ -147,10 +147,6 @@ export function ReferenceFilterField({
147
147
  );
148
148
  };
149
149
 
150
- console.log("ReferenceFilterField", {
151
- internalValue
152
-
153
- })
154
150
  return (
155
151
 
156
152
  <div className="flex w-[440px] flex-row">
@@ -30,6 +30,7 @@ export function DeleteEntityDialog<M extends Record<string, any>>({
30
30
  }: DeleteEntityDialogProps<M>) {
31
31
 
32
32
  const dataSource = useDataSource();
33
+ console.log("dataSource", dataSource)
33
34
  const snackbarController = useSnackbarController();
34
35
  const [loading, setLoading] = useState(false);
35
36
 
@@ -98,8 +98,6 @@ export function ReferenceSelectionInner<M extends Record<string, any>>(
98
98
  maxSelection
99
99
  }: ReferenceSelectionInnerProps<M>) {
100
100
 
101
- console.log("ReferenceSelectionInner");
102
-
103
101
  const sideDialogContext = useSideDialogContext();
104
102
  const sideEntityController = useSideEntityController();
105
103
  const navigation = useNavigationController();
@@ -113,65 +113,40 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
113
113
  );
114
114
  }
115
115
 
116
- const providers: {
117
- context: React.Context<any>;
118
- value?: any;
119
- }[] = [
120
- { context: ModeControllerContext, value: modeController },
121
- { context: FireCMSContextInstance, value: context },
122
- { context: UserConfigurationPersistenceContext, value: userConfigPersistence },
123
- { context: StorageSourceContext, value: storageSource },
124
- { context: DataSourceContext, value: dataSource },
125
- { context: AuthControllerContext, value: authController },
126
- { context: SideDialogsControllerContext, value: sideDialogsController },
127
- { context: SideEntityControllerContext, value: sideEntityController },
128
- { context: NavigationContext, value: navigationController }
129
- // { context: DialogsProvider }
130
- ];
131
-
132
- return providers.reduce((children, provider) => {
133
- const { context: Context, value } = provider;
134
- return (
135
- <Context.Provider value={value}>{children}</Context.Provider>
136
- )
137
- }, <FireCMSInternal
138
- loading={loading}>
139
- {children}
140
- </FireCMSInternal>);
141
-
142
- // return (
143
- // <ModeControllerContext.Provider value={modeController}>
144
- // <FireCMSContextInstance.Provider value={context}>
145
- // <UserConfigurationPersistenceContext.Provider
146
- // value={userConfigPersistence}>
147
- // <StorageSourceContext.Provider
148
- // value={storageSource}>
149
- // <DataSourceContext.Provider
150
- // value={dataSource}>
151
- // <AuthControllerContext.Provider
152
- // value={authController}>
153
- // <SideDialogsControllerContext.Provider
154
- // value={sideDialogsController}>
155
- // <SideEntityControllerContext.Provider
156
- // value={sideEntityController}>
157
- // <NavigationContext.Provider
158
- // value={navigationController}>
159
- // <DialogsProvider>
160
- // <FireCMSInternal
161
- // loading={loading}>
162
- // {children}
163
- // </FireCMSInternal>
164
- // </DialogsProvider>
165
- // </NavigationContext.Provider>
166
- // </SideEntityControllerContext.Provider>
167
- // </SideDialogsControllerContext.Provider>
168
- // </AuthControllerContext.Provider>
169
- // </DataSourceContext.Provider>
170
- // </StorageSourceContext.Provider>
171
- // </UserConfigurationPersistenceContext.Provider>
172
- // </FireCMSContextInstance.Provider>
173
- // </ModeControllerContext.Provider>
174
- // );
116
+ return (
117
+ <ModeControllerContext.Provider value={modeController}>
118
+ <FireCMSContextInstance.Provider value={context}>
119
+ <UserConfigurationPersistenceContext.Provider
120
+ value={userConfigPersistence}>
121
+ <StorageSourceContext.Provider
122
+ value={storageSource}>
123
+ <DataSourceContext.Provider
124
+ value={dataSource}>
125
+ <AuthControllerContext.Provider
126
+ value={authController}>
127
+ <SideDialogsControllerContext.Provider
128
+ value={sideDialogsController}>
129
+ <SideEntityControllerContext.Provider
130
+ value={sideEntityController}>
131
+ <NavigationContext.Provider
132
+ value={navigationController}>
133
+ <DialogsProvider>
134
+ <FireCMSInternal
135
+ loading={loading}>
136
+ {children}
137
+ </FireCMSInternal>
138
+ </DialogsProvider>
139
+ </NavigationContext.Provider>
140
+ </SideEntityControllerContext.Provider>
141
+ </SideDialogsControllerContext.Provider>
142
+ </AuthControllerContext.Provider>
143
+ </DataSourceContext.Provider>
144
+ </StorageSourceContext.Provider>
145
+ </UserConfigurationPersistenceContext.Provider>
146
+ </FireCMSContextInstance.Provider>
147
+ </ModeControllerContext.Provider>
148
+ );
149
+
175
150
  }
176
151
 
177
152
  function FireCMSInternal({
@@ -147,6 +147,7 @@ function EntityFormInternal<M extends Record<string, any>>({
147
147
  autoSave,
148
148
  onIdUpdateError
149
149
  }: EntityFormProps<M>) {
150
+
150
151
  const context = useFireCMSContext();
151
152
  const dataSource = useDataSource();
152
153
  const plugins = context.plugins;
@@ -212,7 +213,7 @@ function EntityFormInternal<M extends Record<string, any>>({
212
213
  onIdChange(entityId);
213
214
  }, [entityId, onIdChange]);
214
215
 
215
- const collection = resolveCollection<M>({
216
+ const resolvedCollection = resolveCollection<M>({
216
217
  collection: inputCollection,
217
218
  path,
218
219
  entityId,
@@ -221,12 +222,12 @@ function EntityFormInternal<M extends Record<string, any>>({
221
222
  fields: context.propertyConfigs
222
223
  });
223
224
 
224
- const onIdUpdate = collection.callbacks?.onIdUpdate;
225
+ const onIdUpdate = inputCollection.callbacks?.onIdUpdate;
225
226
  useEffect(() => {
226
227
  if (onIdUpdate && internalValues && (status === "new" || status === "copy")) {
227
228
  try {
228
229
  const updatedId = onIdUpdate({
229
- collection,
230
+ collection: resolvedCollection,
230
231
  path,
231
232
  entityId,
232
233
  values: internalValues,
@@ -242,7 +243,7 @@ function EntityFormInternal<M extends Record<string, any>>({
242
243
 
243
244
  const underlyingChanges: Partial<EntityValues<M>> = useMemo(() => {
244
245
  if (initialValues && status === "existing") {
245
- return Object.entries(collection.properties)
246
+ return Object.entries(resolvedCollection.properties)
246
247
  .map(([key, property]) => {
247
248
  if (isHidden(property)) {
248
249
  return {};
@@ -258,11 +259,11 @@ function EntityFormInternal<M extends Record<string, any>>({
258
259
  } else {
259
260
  return {};
260
261
  }
261
- }, [baseDataSourceValues, collection.properties, initialValues, status]);
262
+ }, [baseDataSourceValues, resolvedCollection.properties, initialValues, status]);
262
263
 
263
264
  const save = (values: EntityValues<M>) => {
264
265
  return onEntitySaveRequested({
265
- collection,
266
+ collection: resolvedCollection,
266
267
  path,
267
268
  entityId,
268
269
  values,
@@ -300,8 +301,8 @@ function EntityFormInternal<M extends Record<string, any>>({
300
301
  if (status === "existing") {
301
302
  if (!entity?.id) throw Error("Form misconfiguration when saving, no id for existing entity");
302
303
  } else if (status === "new" || status === "copy") {
303
- if (collection.customId) {
304
- if (collection.customId !== "optional" && !entityId) {
304
+ if (inputCollection.customId) {
305
+ if (inputCollection.customId !== "optional" && !entityId) {
305
306
  throw Error("Form misconfiguration when saving, entityId should be set");
306
307
  }
307
308
  }
@@ -333,16 +334,16 @@ function EntityFormInternal<M extends Record<string, any>>({
333
334
  const validationSchema = useMemo(() => entityId
334
335
  ? getYupEntitySchema(
335
336
  entityId,
336
- collection.properties,
337
+ resolvedCollection.properties,
337
338
  uniqueFieldValidator)
338
339
  : undefined,
339
- [entityId, collection.properties, uniqueFieldValidator]);
340
+ [entityId, resolvedCollection.properties, uniqueFieldValidator]);
340
341
 
341
342
  const authController = useAuthController();
342
343
 
343
344
  const getActionsForEntity = useCallback(({ entity, customEntityActions }: { entity?: Entity<M>, customEntityActions?: EntityAction[] }): EntityAction[] => {
344
- const createEnabled = canCreateEntity(collection, authController, fullPathToCollectionSegments(path), null);
345
- const deleteEnabled = entity ? canDeleteEntity(collection, authController, fullPathToCollectionSegments(path), entity) : true;
345
+ const createEnabled = canCreateEntity(inputCollection, authController, fullPathToCollectionSegments(path), null);
346
+ const deleteEnabled = entity ? canDeleteEntity(inputCollection, authController, fullPathToCollectionSegments(path), entity) : true;
346
347
  const actions: EntityAction[] = [];
347
348
  if (createEnabled)
348
349
  actions.push(copyEntityAction);
@@ -351,7 +352,7 @@ function EntityFormInternal<M extends Record<string, any>>({
351
352
  if (customEntityActions)
352
353
  actions.push(...customEntityActions);
353
354
  return actions;
354
- }, [authController, collection, path]);
355
+ }, [authController, inputCollection, path]);
355
356
 
356
357
  return (
357
358
  <Formik
@@ -368,11 +369,7 @@ function EntityFormInternal<M extends Record<string, any>>({
368
369
  const formContext: FormContext<M> = {
369
370
  setFieldValue: props.setFieldValue,
370
371
  values: props.values,
371
- collection: resolveCollection({
372
- collection,
373
- path,
374
- fields: context.propertyConfigs
375
- }),
372
+ collection: resolvedCollection,
376
373
  entityId,
377
374
  path,
378
375
  save
@@ -385,7 +382,7 @@ function EntityFormInternal<M extends Record<string, any>>({
385
382
  }
386
383
  }, [onFormContextChange, formContext]);
387
384
 
388
- if (plugins && collection) {
385
+ if (plugins && inputCollection) {
389
386
  const actionProps: PluginFormActionProps = {
390
387
  entityId,
391
388
  path,
@@ -419,13 +416,13 @@ function EntityFormInternal<M extends Record<string, any>>({
419
416
  className={`w-full py-2 flex items-center mt-${4 + (pluginActions ? 8 : 0)} lg:mt-${8 + (pluginActions ? 8 : 0)} mb-8`}>
420
417
 
421
418
  <Typography
422
- className={"mt-4 flex-grow " + collection.hideIdFromForm ? "mb-2" : "mb-0"}
423
- variant={"h4"}>{collection.singularName ?? collection.name}
419
+ className={"mt-4 flex-grow " + inputCollection.hideIdFromForm ? "mb-2" : "mb-0"}
420
+ variant={"h4"}>{inputCollection.singularName ?? inputCollection.name}
424
421
  </Typography>
425
422
  </div>
426
423
 
427
424
  {!hideId &&
428
- <CustomIdField customId={collection.customId}
425
+ <CustomIdField customId={inputCollection.customId}
429
426
  entityId={entityId}
430
427
  status={status}
431
428
  onChange={setEntityId}
@@ -439,13 +436,13 @@ function EntityFormInternal<M extends Record<string, any>>({
439
436
  onValuesChanged={doOnValuesChanges}
440
437
  underlyingChanges={underlyingChanges}
441
438
  entity={entity}
442
- resolvedCollection={collection}
439
+ resolvedCollection={resolvedCollection}
443
440
  formContext={formContext}
444
441
  status={status}
445
442
  savingError={savingError}
446
443
  closeAfterSaveRef={closeAfterSaveRef}
447
444
  autoSave={autoSave}
448
- entityActions={getActionsForEntity({ entity, customEntityActions: collection.entityActions })}/>}
445
+ entityActions={getActionsForEntity({ entity, customEntityActions: inputCollection.entityActions })}/>}
449
446
 
450
447
  </div>
451
448
  </div>
@@ -202,7 +202,7 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
202
202
  (!Array.isArray(error) || !!error.filter((e: any) => !!e).length);
203
203
 
204
204
  const WrappedComponent: ComponentType<FieldProps<T, any, M>> | null = useWrappedComponent(context.path, context.collection, propertyKey, property, Component, plugins);
205
- const UsedComponent: ComponentType<FieldProps<T>> = WrappedComponent ?? Component;
205
+ const UsedComponent: ComponentType<FieldProps<T>> = Component;
206
206
 
207
207
  const isSubmitting = fieldProps.form.isSubmitting;
208
208
 
@@ -51,7 +51,7 @@ export function resolveCollectionPathAliases(path: string, allCollections: Entit
51
51
  const cleanPath = removeInitialAndTrailingSlashes(path);
52
52
  const subpaths = cleanPath.split("/");
53
53
  if (subpaths.length % 2 === 0) {
54
- throw Error(`Collection paths must have an odd number of segments: ${path}`);
54
+ throw Error(`resolveCollectionPathAliases: Collection paths must have an odd number of segments: ${path}`);
55
55
  }
56
56
 
57
57
  const aliasedCollection = allCollections.find((col) => col.id === subpaths[0]);
@@ -82,7 +82,7 @@ export function getCollectionByPathOrAlias(pathOrAlias: string, collections: Ent
82
82
 
83
83
  const subpaths = removeInitialAndTrailingSlashes(pathOrAlias).split("/");
84
84
  if (subpaths.length % 2 === 0) {
85
- throw Error(`Collection paths must have an odd number of segments: ${pathOrAlias}`);
85
+ throw Error(`getCollectionByPathOrAlias: Collection paths must have an odd number of segments: ${pathOrAlias}`);
86
86
  }
87
87
 
88
88
  const subpathCombinations = getCollectionPathsCombinations(subpaths);
@@ -28,6 +28,8 @@ import { getIn } from "formik";
28
28
  import { enumToObjectEntries } from "./enums";
29
29
  import { isDefaultFieldConfigId } from "../core";
30
30
 
31
+ // import util from "util";
32
+
31
33
  export const resolveCollection = <M extends Record<string, any>, >
32
34
  ({
33
35
  collection,
@@ -57,17 +59,19 @@ export const resolveCollection = <M extends Record<string, any>, >
57
59
  const resolvedProperties = Object.entries(collection.properties)
58
60
  .map(([key, propertyOrBuilder]) => {
59
61
  const propertyValue = usedValues ? getIn(usedValues, key) : undefined;
62
+ const childResolvedProperty = resolveProperty({
63
+ propertyKey: key,
64
+ propertyOrBuilder: propertyOrBuilder as PropertyOrBuilder | ResolvedProperty,
65
+ values: usedValues,
66
+ previousValues: usedPreviousValues,
67
+ path,
68
+ propertyValue,
69
+ entityId,
70
+ fields
71
+ });
72
+ if (!childResolvedProperty) return {};
60
73
  return ({
61
- [key]: resolveProperty({
62
- propertyKey: key,
63
- propertyOrBuilder: propertyOrBuilder as PropertyOrBuilder | ResolvedProperty,
64
- values: usedValues,
65
- previousValues: usedPreviousValues,
66
- path,
67
- propertyValue,
68
- entityId,
69
- fields
70
- })
74
+ [key]: childResolvedProperty
71
75
  });
72
76
  })
73
77
  .filter((a) => a !== null)
@@ -133,7 +137,6 @@ export function resolveProperty<T extends CMSType = CMSType, M extends Record<st
133
137
  });
134
138
 
135
139
  if (!result) {
136
- console.debug("Property builder not returning `Property` so it is not rendered", path, props.entityId, propertyOrBuilder);
137
140
  return null;
138
141
  }
139
142
 
@@ -338,13 +341,16 @@ export function resolveProperties<M extends Record<string, any>>({
338
341
  }): ResolvedProperties<M> {
339
342
  return Object.entries<PropertyOrBuilder>(properties as Record<string, PropertyOrBuilder>)
340
343
  .map(([key, property]) => {
344
+ const thisPropertyValue = propertyValue && typeof propertyValue === "object" ? getValueInPath(propertyValue, key) : undefined;
345
+ const childResolvedProperty = resolveProperty({
346
+ propertyKey: key,
347
+ propertyOrBuilder: property,
348
+ propertyValue: thisPropertyValue,
349
+ ...props
350
+ });
351
+ if (!childResolvedProperty) return {};
341
352
  return {
342
- [key]: resolveProperty({
343
- propertyKey: key,
344
- propertyOrBuilder: property,
345
- propertyValue: propertyValue && typeof propertyValue === "object" ? getValueInPath(propertyValue, key) : undefined,
346
- ...props
347
- })
353
+ [key]: childResolvedProperty
348
354
  };
349
355
  })
350
356
  .filter((a) => a !== null)