@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.
- package/dist/index.es.js +1516 -1465
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/types/collection_editor_controller.d.ts +3 -3
- package/dist/types/persisted_collection.d.ts +2 -3
- package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +2 -1
- package/dist/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +2 -2
- package/dist/ui/collection_editor/PropertyEditView.d.ts +1 -1
- package/dist/ui/collection_editor/PropertyTree.d.ts +2 -2
- package/dist/ui/collection_editor/import/CollectionEditorImportMapping.d.ts +2 -2
- package/dist/ui/collection_editor/properties/BlockPropertyField.d.ts +2 -2
- package/dist/ui/collection_editor/properties/MapPropertyField.d.ts +2 -2
- package/dist/ui/collection_editor/properties/RepeatPropertyField.d.ts +2 -2
- package/dist/ui/collection_editor/properties/StringPropertyField.d.ts +1 -1
- package/dist/ui/collection_editor/properties/UrlPropertyField.d.ts +4 -0
- package/dist/ui/collection_editor/templates/blog_template.d.ts +1 -1
- package/dist/ui/collection_editor/utils/update_property_for_widget.d.ts +1 -1
- package/package.json +5 -5
- package/src/ConfigControllerProvider.tsx +6 -6
- package/src/types/collection_editor_controller.tsx +2 -2
- package/src/types/persisted_collection.ts +2 -2
- package/src/ui/EditorCollectionAction.tsx +1 -1
- package/src/ui/RootCollectionSuggestions.tsx +1 -1
- package/src/ui/collection_editor/CollectionDetailsForm.tsx +52 -1
- package/src/ui/collection_editor/CollectionEditorDialog.tsx +85 -33
- package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +15 -15
- package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +3 -1
- package/src/ui/collection_editor/PropertyEditView.tsx +18 -15
- package/src/ui/collection_editor/PropertyFieldPreview.tsx +4 -4
- package/src/ui/collection_editor/PropertyTree.tsx +3 -2
- package/src/ui/collection_editor/SubcollectionsEditTab.tsx +1 -1
- package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +9 -11
- package/src/ui/collection_editor/properties/BlockPropertyField.tsx +3 -3
- package/src/ui/collection_editor/properties/MapPropertyField.tsx +4 -4
- package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +1 -0
- package/src/ui/collection_editor/properties/RepeatPropertyField.tsx +4 -6
- package/src/ui/collection_editor/properties/StringPropertyField.tsx +1 -7
- package/src/ui/collection_editor/properties/UrlPropertyField.tsx +89 -0
- package/src/ui/collection_editor/templates/blog_template.ts +3 -4
- package/src/ui/collection_editor/templates/products_template.ts +3 -5
- package/src/ui/collection_editor/templates/users_template.ts +3 -4
- package/src/ui/collection_editor/utils/update_property_for_widget.ts +6 -3
- package/src/useCollectionEditorPlugin.tsx +10 -5
- package/dist/utils/join_collections.d.ts +0 -13
- package/src/utils/join_collections.ts +0 -113
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { CollectionEditorPermissionsBuilder } from "./config_permissions";
|
|
2
|
-
import {
|
|
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
|
-
* @
|
|
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?:
|
|
13
|
+
parentCollection?: PersistedCollection;
|
|
14
14
|
}) => void;
|
|
15
15
|
createCollection: (props: {
|
|
16
16
|
initialValues?: {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { EntityCollection,
|
|
2
|
-
export type PersistedCollection<M extends Record<string, any> = any, UserType extends User = User> = Omit<EntityCollection<M, UserType>, "
|
|
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?:
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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,
|
|
3
|
+
export declare function CollectionEditorImportMapping({ importConfig, propertyConfigs, collectionEditable }: {
|
|
4
4
|
importConfig: ImportConfig;
|
|
5
|
-
|
|
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,
|
|
2
|
+
export declare function BlockPropertyField({ disabled, getData, allowDataInference, propertyConfigs, collectionEditable }: {
|
|
3
3
|
disabled: boolean;
|
|
4
4
|
getData?: () => Promise<object[]>;
|
|
5
5
|
allowDataInference: boolean;
|
|
6
|
-
|
|
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,
|
|
2
|
+
export declare function MapPropertyField({ disabled, getData, allowDataInference, propertyConfigs, collectionEditable }: {
|
|
3
3
|
disabled: boolean;
|
|
4
4
|
getData?: () => Promise<object[]>;
|
|
5
5
|
allowDataInference: boolean;
|
|
6
|
-
|
|
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,
|
|
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
|
-
|
|
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" | "
|
|
2
|
+
widgetId: "text_field" | "multiline" | "markdown" | "email";
|
|
3
3
|
disabled: boolean;
|
|
4
4
|
showErrors: boolean;
|
|
5
5
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { EntityCollection } from "@firecms/
|
|
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,
|
|
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.
|
|
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.
|
|
18
|
-
"@firecms/schema_inference": "^3.0.0-alpha.
|
|
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.
|
|
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": "
|
|
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 {
|
|
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?:
|
|
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?:
|
|
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?:
|
|
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?:
|
|
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
|
-
|
|
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
|
-
* @
|
|
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?:
|
|
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>, "
|
|
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
|
|
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?:
|
|
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 {
|
|
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
|
|
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
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
276
|
+
try {
|
|
277
|
+
if (!doCollectionInference) {
|
|
278
|
+
setCollection(newCollection);
|
|
279
|
+
return Promise.resolve(newCollection);
|
|
280
|
+
}
|
|
273
281
|
|
|
274
|
-
|
|
282
|
+
setCurrentView("loading");
|
|
275
283
|
|
|
276
|
-
|
|
284
|
+
const inferredCollection = await doCollectionInference?.(newCollection);
|
|
277
285
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
286
|
+
if (!inferredCollection) {
|
|
287
|
+
setCollection(newCollection);
|
|
288
|
+
return Promise.resolve(newCollection);
|
|
289
|
+
}
|
|
290
|
+
const values = {
|
|
291
|
+
...(newCollection ?? {}),
|
|
292
|
+
};
|
|
285
293
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
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
|
-
|
|
292
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
+
}
|