@firecms/collection_editor 3.0.0-alpha.34 → 3.0.0-alpha.36

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 (46) hide show
  1. package/dist/index.es.js +1516 -1465
  2. package/dist/index.es.js.map +1 -1
  3. package/dist/index.umd.js +1 -1
  4. package/dist/index.umd.js.map +1 -1
  5. package/dist/types/collection_editor_controller.d.ts +3 -3
  6. package/dist/types/persisted_collection.d.ts +2 -3
  7. package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +2 -1
  8. package/dist/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +2 -2
  9. package/dist/ui/collection_editor/PropertyEditView.d.ts +1 -1
  10. package/dist/ui/collection_editor/PropertyTree.d.ts +2 -2
  11. package/dist/ui/collection_editor/import/CollectionEditorImportMapping.d.ts +2 -2
  12. package/dist/ui/collection_editor/properties/BlockPropertyField.d.ts +2 -2
  13. package/dist/ui/collection_editor/properties/MapPropertyField.d.ts +2 -2
  14. package/dist/ui/collection_editor/properties/RepeatPropertyField.d.ts +2 -2
  15. package/dist/ui/collection_editor/properties/StringPropertyField.d.ts +1 -1
  16. package/dist/ui/collection_editor/properties/UrlPropertyField.d.ts +4 -0
  17. package/dist/ui/collection_editor/templates/blog_template.d.ts +1 -1
  18. package/dist/ui/collection_editor/utils/update_property_for_widget.d.ts +1 -1
  19. package/package.json +5 -5
  20. package/src/ConfigControllerProvider.tsx +6 -6
  21. package/src/types/collection_editor_controller.tsx +2 -2
  22. package/src/types/persisted_collection.ts +2 -2
  23. package/src/ui/EditorCollectionAction.tsx +1 -1
  24. package/src/ui/RootCollectionSuggestions.tsx +1 -1
  25. package/src/ui/collection_editor/CollectionDetailsForm.tsx +52 -1
  26. package/src/ui/collection_editor/CollectionEditorDialog.tsx +85 -33
  27. package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +15 -15
  28. package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +3 -1
  29. package/src/ui/collection_editor/PropertyEditView.tsx +18 -15
  30. package/src/ui/collection_editor/PropertyFieldPreview.tsx +4 -4
  31. package/src/ui/collection_editor/PropertyTree.tsx +3 -2
  32. package/src/ui/collection_editor/SubcollectionsEditTab.tsx +1 -1
  33. package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +9 -11
  34. package/src/ui/collection_editor/properties/BlockPropertyField.tsx +3 -3
  35. package/src/ui/collection_editor/properties/MapPropertyField.tsx +4 -4
  36. package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +1 -0
  37. package/src/ui/collection_editor/properties/RepeatPropertyField.tsx +4 -6
  38. package/src/ui/collection_editor/properties/StringPropertyField.tsx +1 -7
  39. package/src/ui/collection_editor/properties/UrlPropertyField.tsx +89 -0
  40. package/src/ui/collection_editor/templates/blog_template.ts +3 -4
  41. package/src/ui/collection_editor/templates/products_template.ts +3 -5
  42. package/src/ui/collection_editor/templates/users_template.ts +3 -4
  43. package/src/ui/collection_editor/utils/update_property_for_widget.ts +6 -3
  44. package/src/useCollectionEditorPlugin.tsx +10 -5
  45. package/dist/utils/join_collections.d.ts +0 -13
  46. package/src/utils/join_collections.ts +0 -113
@@ -1,16 +1,16 @@
1
1
  import { CollectionEditorPermissionsBuilder } from "./config_permissions";
2
- import { EntityCollection, Property } from "@firecms/core";
2
+ import { Property } from "@firecms/core";
3
3
  import { PersistedCollection } from "./persisted_collection";
4
4
  /**
5
5
  * Controller to open the collection editor dialog.
6
- * @category Hooks and utilities
6
+ * @group Hooks and utilities
7
7
  */
8
8
  export interface CollectionEditorController {
9
9
  editCollection: (props: {
10
10
  path?: string;
11
11
  fullPath?: string;
12
12
  parentPathSegments: string[];
13
- parentCollection?: EntityCollection;
13
+ parentCollection?: PersistedCollection;
14
14
  }) => void;
15
15
  createCollection: (props: {
16
16
  initialValues?: {
@@ -1,6 +1,5 @@
1
- import { EntityCollection, Properties, User } from "@firecms/core";
2
- export type PersistedCollection<M extends Record<string, any> = any, UserType extends User = User> = Omit<EntityCollection<M, UserType>, "properties" | "subcollections"> & {
3
- properties: Properties<M>;
1
+ import { EntityCollection, User } from "@firecms/core";
2
+ export type PersistedCollection<M extends Record<string, any> = any, UserType extends User = User> = Omit<EntityCollection<M, UserType>, "subcollections"> & {
4
3
  ownerId: string;
5
4
  subcollections?: PersistedCollection<any, any>[];
6
5
  editable?: boolean;
@@ -2,6 +2,7 @@ import * as React from "react";
2
2
  import { CMSType, EntityCollection, User } from "@firecms/core";
3
3
  import { CollectionsConfigController } from "../../types/config_controller";
4
4
  import { CollectionInference } from "../../types/collection_inference";
5
+ import { PersistedCollection } from "../../types/persisted_collection";
5
6
  export interface CollectionEditorDialogProps {
6
7
  open: boolean;
7
8
  isNewCollection: boolean;
@@ -26,7 +27,7 @@ export interface CollectionEditorDialogProps {
26
27
  pathSuggestions?: (path?: string) => Promise<string[]>;
27
28
  getUser: (uid: string) => User | null;
28
29
  getData?: (path: string) => Promise<object[]>;
29
- parentCollection?: EntityCollection;
30
+ parentCollection?: PersistedCollection;
30
31
  }
31
32
  export declare function CollectionEditorDialog(props: CollectionEditorDialogProps): import("react/jsx-runtime").JSX.Element;
32
33
  export declare function CollectionEditorDialogInternal<M extends {
@@ -13,8 +13,8 @@ type CollectionEditorFormProps = {
13
13
  getUser: (uid: string) => User | null;
14
14
  getData?: () => Promise<object[]>;
15
15
  doCollectionInference: (collection: PersistedCollection) => Promise<EntityCollection | null> | undefined;
16
- customFields: Record<string, PropertyConfig>;
16
+ propertyConfigs: Record<string, PropertyConfig>;
17
17
  collectionEditable: boolean;
18
18
  };
19
- export declare function CollectionPropertiesEditorForm({ showErrors, isNewCollection, propertyErrorsRef, onPropertyError, setDirty, reservedGroups, extraIcon, getUser, getData, doCollectionInference, customFields, collectionEditable }: CollectionEditorFormProps): import("react/jsx-runtime").JSX.Element;
19
+ export declare function CollectionPropertiesEditorForm({ showErrors, isNewCollection, propertyErrorsRef, onPropertyError, setDirty, reservedGroups, extraIcon, getUser, getData, doCollectionInference, propertyConfigs, collectionEditable }: CollectionEditorFormProps): import("react/jsx-runtime").JSX.Element;
20
20
  export {};
@@ -29,7 +29,7 @@ export type PropertyFormProps = {
29
29
  allowDataInference: boolean;
30
30
  getData?: () => Promise<object[]>;
31
31
  getHelpers?: (formikProps: FormikProps<PropertyWithId>) => void;
32
- customFields: Record<string, PropertyConfig>;
32
+ propertyConfigs: Record<string, PropertyConfig>;
33
33
  collectionEditable: boolean;
34
34
  };
35
35
  export declare const PropertyForm: React.NamedExoticComponent<PropertyFormProps>;
@@ -2,7 +2,7 @@ import { AdditionalFieldDelegate, CMSType, PropertiesOrBuilders, PropertyOrBuild
2
2
  import { DraggableProvided } from "@hello-pangea/dnd";
3
3
  export declare function PropertyTree<M extends {
4
4
  [Key: string]: CMSType;
5
- }>({ namespace, selectedPropertyKey, onPropertyClick, properties, propertiesOrder: propertiesOrderProp, additionalFields, errors, onPropertyMove, onPropertyRemove, className, inferredPropertyKeys, collectionEditable }: {
5
+ }>({ namespace, selectedPropertyKey, onPropertyClick, properties, propertiesOrder: propertiesOrderProp, additionalFields, errors, onPropertyMove, onPropertyRemove, className, inferredPropertyKeys, collectionEditable, }: {
6
6
  namespace?: string;
7
7
  selectedPropertyKey?: string;
8
8
  onPropertyClick?: (propertyKey: string, namespace?: string) => void;
@@ -16,7 +16,7 @@ export declare function PropertyTree<M extends {
16
16
  inferredPropertyKeys?: string[];
17
17
  collectionEditable: boolean;
18
18
  }): import("react/jsx-runtime").JSX.Element;
19
- export declare function PropertyTreeEntry({ propertyKey, namespace, propertyOrBuilder, additionalField, provided, selectedPropertyKey, errors, onPropertyClick, onPropertyMove, onPropertyRemove, inferredPropertyKeys, collectionEditable }: {
19
+ export declare function PropertyTreeEntry({ propertyKey, namespace, propertyOrBuilder, additionalField, provided, selectedPropertyKey, errors, onPropertyClick, onPropertyMove, onPropertyRemove, inferredPropertyKeys, collectionEditable, }: {
20
20
  propertyKey: string;
21
21
  namespace?: string;
22
22
  propertyOrBuilder: PropertyOrBuilder;
@@ -1,7 +1,7 @@
1
1
  import { ImportConfig } from "@firecms/data_import";
2
2
  import { PropertyConfig } from "@firecms/core";
3
- export declare function CollectionEditorImportMapping({ importConfig, customFields, collectionEditable }: {
3
+ export declare function CollectionEditorImportMapping({ importConfig, propertyConfigs, collectionEditable }: {
4
4
  importConfig: ImportConfig;
5
- customFields: Record<string, PropertyConfig>;
5
+ propertyConfigs: Record<string, PropertyConfig>;
6
6
  collectionEditable: boolean;
7
7
  }): import("react/jsx-runtime").JSX.Element;
@@ -1,8 +1,8 @@
1
1
  import { PropertyConfig } from "@firecms/core";
2
- export declare function BlockPropertyField({ disabled, getData, allowDataInference, customFields, collectionEditable }: {
2
+ export declare function BlockPropertyField({ disabled, getData, allowDataInference, propertyConfigs, collectionEditable }: {
3
3
  disabled: boolean;
4
4
  getData?: () => Promise<object[]>;
5
5
  allowDataInference: boolean;
6
- customFields: Record<string, PropertyConfig>;
6
+ propertyConfigs: Record<string, PropertyConfig>;
7
7
  collectionEditable: boolean;
8
8
  }): import("react/jsx-runtime").JSX.Element;
@@ -1,8 +1,8 @@
1
1
  import { PropertyConfig } from "@firecms/core";
2
- export declare function MapPropertyField({ disabled, getData, allowDataInference, customFields, collectionEditable }: {
2
+ export declare function MapPropertyField({ disabled, getData, allowDataInference, propertyConfigs, collectionEditable }: {
3
3
  disabled: boolean;
4
4
  getData?: () => Promise<object[]>;
5
5
  allowDataInference: boolean;
6
- customFields: Record<string, PropertyConfig>;
6
+ propertyConfigs: Record<string, PropertyConfig>;
7
7
  collectionEditable: boolean;
8
8
  }): import("react/jsx-runtime").JSX.Element;
@@ -1,10 +1,10 @@
1
1
  import { PropertyConfig } from "@firecms/core";
2
- export declare function RepeatPropertyField({ showErrors, existing, disabled, getData, allowDataInference, customFields, collectionEditable }: {
2
+ export declare function RepeatPropertyField({ showErrors, existing, disabled, getData, allowDataInference, propertyConfigs, collectionEditable }: {
3
3
  showErrors: boolean;
4
4
  existing: boolean;
5
5
  disabled: boolean;
6
6
  getData?: () => Promise<object[]>;
7
7
  allowDataInference: boolean;
8
- customFields: Record<string, PropertyConfig>;
8
+ propertyConfigs: Record<string, PropertyConfig>;
9
9
  collectionEditable: boolean;
10
10
  }): import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  export declare function StringPropertyField({ widgetId, disabled, showErrors }: {
2
- widgetId: "text_field" | "multiline" | "markdown" | "url" | "email";
2
+ widgetId: "text_field" | "multiline" | "markdown" | "email";
3
3
  disabled: boolean;
4
4
  showErrors: boolean;
5
5
  }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,4 @@
1
+ export declare function UrlPropertyField({ disabled, showErrors }: {
2
+ disabled: boolean;
3
+ showErrors: boolean;
4
+ }): import("react/jsx-runtime").JSX.Element;
@@ -1,2 +1,2 @@
1
- import { EntityCollection } from "@firecms/firebase";
1
+ import { EntityCollection } from "@firecms/core";
2
2
  export declare const blogCollectionTemplate: EntityCollection;
@@ -1,2 +1,2 @@
1
1
  import { Property, PropertyConfig } from "@firecms/core";
2
- export declare function updatePropertyFromWidget(propertyData: any, selectedWidgetId: string | undefined, customFields: Record<string, PropertyConfig>): Property;
2
+ export declare function updatePropertyFromWidget(propertyData: any, selectedWidgetId: string | undefined, propertyConfigs: Record<string, PropertyConfig>): Property;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firecms/collection_editor",
3
- "version": "3.0.0-alpha.34",
3
+ "version": "3.0.0-alpha.36",
4
4
  "main": "./dist/index.umd.js",
5
5
  "module": "./dist/index.es.js",
6
6
  "types": "dist/index.d.ts",
@@ -14,8 +14,8 @@
14
14
  "./package.json": "./package.json"
15
15
  },
16
16
  "dependencies": {
17
- "@firecms/data_import": "^3.0.0-alpha.34",
18
- "@firecms/schema_inference": "^3.0.0-alpha.34",
17
+ "@firecms/data_import": "^3.0.0-alpha.36",
18
+ "@firecms/schema_inference": "^3.0.0-alpha.36",
19
19
  "json5": "^2.2.3",
20
20
  "prism-react-renderer": "^2.3.0"
21
21
  },
@@ -67,7 +67,7 @@
67
67
  "react-router": "^6.17.0",
68
68
  "react-router-dom": "^6.17.0",
69
69
  "ts-jest": "^29.1.1",
70
- "typescript": "^5.2.2",
70
+ "typescript": "^5.3.0",
71
71
  "vite": "^4.5.0",
72
72
  "vite-plugin-fonts": "^0.7.0"
73
73
  },
@@ -78,5 +78,5 @@
78
78
  "publishConfig": {
79
79
  "access": "public"
80
80
  },
81
- "gitHead": "97fea385cfd4a0ab9301d45d50e1d145021c1df5"
81
+ "gitHead": "80d437634caccc4400fa111504186eb13197bac1"
82
82
  }
@@ -73,7 +73,7 @@ export const ConfigControllerProvider = React.memo(
73
73
  const navigation = useNavigationContext();
74
74
  const navigate = useNavigate();
75
75
  const snackbarController = useSnackbarController();
76
- const { fields: customFields } = useFireCMSContext();
76
+ const { propertyConfigs } = useFireCMSContext();
77
77
 
78
78
  const {
79
79
  collections
@@ -91,7 +91,7 @@ export const ConfigControllerProvider = React.memo(
91
91
 
92
92
  const [currentDialog, setCurrentDialog] = React.useState<{
93
93
  isNewCollection: boolean,
94
- parentCollection?: EntityCollection,
94
+ parentCollection?: PersistedCollection,
95
95
  editedCollectionPath?: string,
96
96
  fullPath?: string,
97
97
  parentPathSegments: string[],
@@ -107,7 +107,7 @@ export const ConfigControllerProvider = React.memo(
107
107
  propertyKey?: string,
108
108
  property?: Property,
109
109
  namespace?: string,
110
- parentCollection?: EntityCollection,
110
+ parentCollection?: PersistedCollection,
111
111
  currentPropertiesOrder?: string[],
112
112
  editedCollectionPath: string,
113
113
  fullPath?: string,
@@ -130,7 +130,7 @@ export const ConfigControllerProvider = React.memo(
130
130
  path?: string,
131
131
  fullPath?: string,
132
132
  parentPathSegments: string[],
133
- parentCollection?: EntityCollection
133
+ parentCollection?: PersistedCollection
134
134
  }) => {
135
135
  setCurrentDialog({
136
136
  editedCollectionPath: path,
@@ -183,7 +183,7 @@ export const ConfigControllerProvider = React.memo(
183
183
  redirect
184
184
  }: {
185
185
  parentPathSegments: string[],
186
- parentCollection?: EntityCollection
186
+ parentCollection?: PersistedCollection
187
187
  initialValues?: {
188
188
  group?: string,
189
189
  path?: string,
@@ -317,7 +317,7 @@ export const ConfigControllerProvider = React.memo(
317
317
  forceShowErrors={false}
318
318
  existingPropertyKeys={[]}
319
319
  allowDataInference={true}
320
- customFields={customFields}
320
+ propertyConfigs={propertyConfigs}
321
321
  property={currentPropertyDialog?.property}
322
322
  propertyKey={currentPropertyDialog?.propertyKey}/>
323
323
 
@@ -4,7 +4,7 @@ import { PersistedCollection } from "./persisted_collection";
4
4
 
5
5
  /**
6
6
  * Controller to open the collection editor dialog.
7
- * @category Hooks and utilities
7
+ * @group Hooks and utilities
8
8
  */
9
9
  export interface CollectionEditorController {
10
10
 
@@ -12,7 +12,7 @@ export interface CollectionEditorController {
12
12
  path?: string,
13
13
  fullPath?: string,
14
14
  parentPathSegments: string[],
15
- parentCollection?: EntityCollection
15
+ parentCollection?: PersistedCollection
16
16
  }) => void;
17
17
 
18
18
  createCollection: (props: {
@@ -1,8 +1,8 @@
1
1
  import { EntityCollection, Properties, User } from "@firecms/core";
2
2
 
3
3
  export type PersistedCollection<M extends Record<string, any> = any, UserType extends User = User>
4
- = Omit<EntityCollection<M, UserType>, "properties" | "subcollections"> & {
5
- properties: Properties<M>;
4
+ = Omit<EntityCollection<M, UserType>, "subcollections"> & {
5
+ // properties: Properties<M>;
6
6
  ownerId: string;
7
7
  subcollections?: PersistedCollection<any, any>[];
8
8
  editable?: boolean;
@@ -75,7 +75,7 @@ export function EditorCollectionAction({
75
75
  color={"primary"}
76
76
  disabled={!canEditCollection}
77
77
  onClick={canEditCollection
78
- ? () => collectionEditorController?.editCollection({ path: collection.path, fullPath, parentPathSegments, parentCollection })
78
+ ? () => collectionEditorController?.editCollection({ path: collection.path, fullPath, parentPathSegments, parentCollection: parentCollection as PersistedCollection })
79
79
  : undefined}>
80
80
  <SettingsIcon/>
81
81
  </IconButton>
@@ -21,7 +21,7 @@ export function RootCollectionSuggestions() {
21
21
  in={showSuggestions}>
22
22
 
23
23
  <div
24
- className={"flex flex-col gap-1 p-2"}>
24
+ className={"flex flex-col gap-1 p-2 my-4"}>
25
25
 
26
26
  <Typography variant={"body2"} color={"secondary"}>
27
27
  Create a collection from your data:
@@ -109,6 +109,18 @@ export function CollectionDetailsForm({
109
109
 
110
110
  const isSubcollection = !!parentCollection;
111
111
 
112
+ let customIdValue: "true" | "false" | "optional" | "code_defined" | undefined;
113
+ if (customIdValue) {
114
+ if (typeof values.customId === "object") {
115
+ customIdValue = "code_defined";
116
+ } else if (values.customId === true) {
117
+ customIdValue = "true";
118
+ } else if (values.customId === false) {
119
+ customIdValue = "false";
120
+ } else if (values.customId === "optional") {
121
+ customIdValue = "optional";
122
+ }
123
+ }
112
124
  return (
113
125
  <div className={"overflow-auto my-auto"}>
114
126
  <Container maxWidth={"4xl"} className={"flex flex-col gap-4 p-8 m-auto"}>
@@ -117,7 +129,7 @@ export function CollectionDetailsForm({
117
129
  <div
118
130
  className="flex flex-row py-2 pt-3 items-center">
119
131
  <Typography variant={!isNewCollection ? "h5" : "h4"} className={"flex-grow"}>
120
- {isNewCollection ? "New collection" : `${values.name} collection`}
132
+ {isNewCollection ? "New collection" : `${values?.name} collection`}
121
133
  </Typography>
122
134
  <Tooltip title={"Change icon"}>
123
135
  <IconButton
@@ -269,6 +281,45 @@ export function CollectionDetailsForm({
269
281
  ))}
270
282
  </Select>
271
283
  </div>
284
+ <div className={"col-span-12"}>
285
+ <Select
286
+ name="customId"
287
+ label="ID generation"
288
+ position={"item-aligned"}
289
+ disabled={customIdValue === "code_defined"}
290
+ onValueChange={(v) => {
291
+ if (v === "code_defined")
292
+ throw new Error("This should not happen");
293
+ else if (v === "true")
294
+ setFieldValue("customId", true);
295
+ else if (v === "false")
296
+ setFieldValue("customId", false);
297
+ else if (v === "optional")
298
+ setFieldValue("customId", "optional");
299
+ }}
300
+ value={customIdValue ?? ""}
301
+ renderValue={(value: any) => {
302
+ if (value === "code_defined")
303
+ return "Code defined";
304
+ else if (value === "true")
305
+ return "Users must define an ID";
306
+ else if (value === "optional")
307
+ return "Users can define an ID, but it is not required";
308
+ else
309
+ return "ID is generated automatically";
310
+ }}
311
+ >
312
+ <SelectItem value={"false"}>
313
+ ID is generated automatically
314
+ </SelectItem>
315
+ <SelectItem value={"true"}>
316
+ Users must define an ID
317
+ </SelectItem>
318
+ <SelectItem value={"optional"}>
319
+ Users can define an ID, but it is not required
320
+ </SelectItem>
321
+ </Select>
322
+ </div>
272
323
  <div className={"col-span-12"}>
273
324
  <BooleanSwitchWithLabel
274
325
  position={"start"}
@@ -15,8 +15,15 @@ import {
15
15
  EntityCollection,
16
16
  ErrorView,
17
17
  IconButton,
18
+ isPropertyBuilder,
18
19
  LoadingButton,
20
+ MapProperty,
21
+ mergeDeep,
19
22
  Properties,
23
+ PropertiesOrBuilders,
24
+ Property,
25
+ PropertyConfig,
26
+ PropertyOrBuilder,
20
27
  removeUndefined,
21
28
  Tab,
22
29
  Tabs,
@@ -32,7 +39,6 @@ import { YupSchema } from "./CollectionYupValidation";
32
39
  import { CollectionDetailsForm } from "./CollectionDetailsForm";
33
40
  import { CollectionPropertiesEditorForm } from "./CollectionPropertiesEditorForm";
34
41
  import { UnsavedChangesDialog } from "./UnsavedChangesDialog";
35
- import { PersistedCollection } from "../../types/persisted_collection";
36
42
  import { SubcollectionsEditTab } from "./SubcollectionsEditTab";
37
43
  import { CollectionsConfigController } from "../../types/config_controller";
38
44
  import { CollectionEditorWelcomeView } from "./CollectionEditorWelcomeView";
@@ -42,6 +48,7 @@ import { buildEntityPropertiesFromData } from "@firecms/schema_inference";
42
48
  import { CollectionEditorImportMapping } from "./import/CollectionEditorImportMapping";
43
49
  import { CollectionEditorImportDataPreview } from "./import/CollectionEditorImportDataPreview";
44
50
  import { cleanPropertiesFromImport } from "./import/clean_import_data";
51
+ import { PersistedCollection } from "../../types/persisted_collection";
45
52
 
46
53
  export interface CollectionEditorDialogProps {
47
54
  open: boolean;
@@ -67,7 +74,7 @@ export interface CollectionEditorDialogProps {
67
74
  pathSuggestions?: (path?: string) => Promise<string[]>;
68
75
  getUser: (uid: string) => User | null;
69
76
  getData?: (path: string) => Promise<object[]>;
70
- parentCollection?: EntityCollection;
77
+ parentCollection?: PersistedCollection;
71
78
  }
72
79
 
73
80
  export function CollectionEditorDialog(props: CollectionEditorDialogProps) {
@@ -150,7 +157,7 @@ export function CollectionEditorDialogInternal<M extends {
150
157
  }
151
158
  ) {
152
159
 
153
- const { fields: customFields } = useFireCMSContext();
160
+ const { propertyConfigs } = useFireCMSContext();
154
161
  const navigation = useNavigationContext();
155
162
  const {
156
163
  topLevelNavigation,
@@ -226,11 +233,11 @@ export function CollectionEditorDialogInternal<M extends {
226
233
  });
227
234
  };
228
235
 
229
- const initialValues: PersistedCollection<M> = collection ?? {
236
+ const initialValues: PersistedCollection<M> = collection ? applyPropertyConfigs(collection, propertyConfigs) : {
230
237
  path: initialValuesProp?.path ?? "",
231
238
  name: initialValuesProp?.name ?? "",
232
239
  group: initialValuesProp?.group ?? "",
233
- properties: {} as Properties<M>,
240
+ properties: {} as PropertiesOrBuilders<M>,
234
241
  propertiesOrder: [],
235
242
  icon: coolIconKeys[Math.floor(Math.random() * coolIconKeys.length)],
236
243
  ownerId: authController.user?.uid ?? ""
@@ -266,39 +273,48 @@ export function CollectionEditorDialogInternal<M extends {
266
273
 
267
274
  const inferCollectionFromData = useCallback(async (newCollection: PersistedCollection<M>) => {
268
275
 
269
- if (!doCollectionInference) {
270
- setCollection(newCollection);
271
- return Promise.resolve(newCollection);
272
- }
276
+ try {
277
+ if (!doCollectionInference) {
278
+ setCollection(newCollection);
279
+ return Promise.resolve(newCollection);
280
+ }
273
281
 
274
- setCurrentView("loading");
282
+ setCurrentView("loading");
275
283
 
276
- const inferredCollection = await doCollectionInference?.(newCollection);
284
+ const inferredCollection = await doCollectionInference?.(newCollection);
277
285
 
278
- if (!inferredCollection) {
279
- setCollection(newCollection);
280
- return Promise.resolve(newCollection);
281
- }
282
- const values = {
283
- ...(newCollection ?? {}),
284
- };
286
+ if (!inferredCollection) {
287
+ setCollection(newCollection);
288
+ return Promise.resolve(newCollection);
289
+ }
290
+ const values = {
291
+ ...(newCollection ?? {}),
292
+ };
285
293
 
286
- if (Object.keys(inferredCollection.properties ?? {}).length > 0) {
287
- values.properties = inferredCollection.properties as Properties<M>;
288
- values.propertiesOrder = inferredCollection.propertiesOrder as Extract<keyof M, string>[];
289
- }
294
+ if (Object.keys(inferredCollection.properties ?? {}).length > 0) {
295
+ values.properties = inferredCollection.properties as PropertiesOrBuilders<M>;
296
+ values.propertiesOrder = inferredCollection.propertiesOrder as Extract<keyof M, string>[];
297
+ }
290
298
 
291
- if (!values.propertiesOrder) {
292
- values.propertiesOrder = Object.keys(values.properties) as Extract<keyof M, string>[];
299
+ if (!values.propertiesOrder) {
300
+ values.propertiesOrder = Object.keys(values.properties) as Extract<keyof M, string>[];
301
+ return values;
302
+ }
303
+
304
+ setCollection(values);
305
+ console.log("Inferred collection", {
306
+ newCollection: newCollection ?? {},
307
+ values
308
+ });
293
309
  return values;
310
+ } catch (e: any) {
311
+ console.error(e);
312
+ snackbarController.open({
313
+ type: "error",
314
+ message: "Error inferring collection: " + (e.message ?? "Details in the console")
315
+ });
316
+ return newCollection;
294
317
  }
295
-
296
- setCollection(values);
297
- console.log("Inferred collection", {
298
- newCollection: newCollection ?? {},
299
- values
300
- });
301
- return values;
302
318
  }, [parentPathSegments, doCollectionInference]);
303
319
 
304
320
  const onSubmit = (newCollectionState: PersistedCollection<M>, formikHelpers: FormikHelpers<PersistedCollection<M>>) => {
@@ -479,7 +495,7 @@ export function CollectionEditorDialogInternal<M extends {
479
495
  {currentView === "import_data_mapping" && importConfig &&
480
496
  <CollectionEditorImportMapping importConfig={importConfig}
481
497
  collectionEditable={collectionEditable}
482
- customFields={customFields}/>}
498
+ propertyConfigs={propertyConfigs}/>}
483
499
 
484
500
  {currentView === "import_data_preview" && importConfig &&
485
501
  <CollectionEditorImportDataPreview importConfig={importConfig}
@@ -529,7 +545,7 @@ export function CollectionEditorDialogInternal<M extends {
529
545
  getUser={getUser}
530
546
  getData={getDataWithPath}
531
547
  doCollectionInference={doCollectionInference}
532
- customFields={customFields}
548
+ propertyConfigs={propertyConfigs}
533
549
  collectionEditable={collectionEditable}
534
550
  extraIcon={extraView?.icon &&
535
551
  <IconButton
@@ -642,3 +658,39 @@ export function CollectionEditorDialogInternal<M extends {
642
658
  </DialogContent>
643
659
 
644
660
  }
661
+
662
+ function applyPropertyConfigs<M extends Record<string, any> = any>(collection: PersistedCollection<M>, propertyConfigs: Record<string, PropertyConfig<any>>): PersistedCollection<M> {
663
+ const { properties, ...rest } = collection;
664
+ const propertiesResult: PropertiesOrBuilders<any> = {};
665
+ Object.keys(properties).forEach((key) => {
666
+ propertiesResult[key] = applyPropertiesConfig(properties[key] as PropertyOrBuilder, propertyConfigs);
667
+ });
668
+
669
+ return { ...rest, properties: propertiesResult };
670
+ }
671
+
672
+ function applyPropertiesConfig(property: PropertyOrBuilder, propertyConfigs: Record<string, PropertyConfig<any>>) {
673
+ let internalProperty = property;
674
+ if (propertyConfigs && typeof internalProperty === "object" && internalProperty.propertyConfig) {
675
+ const propertyConfig = propertyConfigs[internalProperty.propertyConfig];
676
+ if (propertyConfig && isPropertyBuilder(propertyConfig.property)) {
677
+ internalProperty = propertyConfig.property;
678
+ } else {
679
+
680
+ if (propertyConfig) {
681
+ internalProperty = mergeDeep(propertyConfig.property, internalProperty);
682
+ }
683
+
684
+ if (!isPropertyBuilder(internalProperty) && internalProperty.dataType === "map" && internalProperty.properties) {
685
+ const properties: Record<string, PropertyOrBuilder> = {};
686
+ Object.keys(internalProperty.properties).forEach((key) => {
687
+ properties[key] = applyPropertiesConfig(((internalProperty as MapProperty).properties as Properties)[key] as Property, propertyConfigs);
688
+ });
689
+ internalProperty = { ...internalProperty, properties };
690
+ }
691
+
692
+ }
693
+ }
694
+ return internalProperty;
695
+
696
+ }