@firecms/collection_editor 3.0.0-canary.13 → 3.0.0-canary.131
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/LICENSE +114 -21
- package/dist/ConfigControllerProvider.d.ts +11 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +4715 -3491
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +6685 -3
- package/dist/index.umd.js.map +1 -1
- package/dist/types/collection_editor_controller.d.ts +14 -2
- package/dist/types/collection_inference.d.ts +1 -1
- package/dist/ui/CollectionViewHeaderAction.d.ts +3 -2
- package/dist/ui/EditorCollectionActionStart.d.ts +2 -0
- package/dist/ui/PropertyAddColumnComponent.d.ts +3 -1
- package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +4 -3
- package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +1 -1
- package/dist/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +1 -1
- package/dist/ui/collection_editor/PropertyTree.d.ts +9 -9
- package/dist/ui/collection_editor/SubcollectionsEditTab.d.ts +1 -1
- package/dist/ui/collection_editor/properties/MarkdownPropertyField.d.ts +4 -0
- package/dist/ui/collection_editor/properties/StringPropertyField.d.ts +1 -1
- package/dist/useCollectionEditorPlugin.d.ts +15 -9
- package/dist/utils/collections.d.ts +6 -0
- package/package.json +20 -34
- package/src/ConfigControllerProvider.tsx +75 -63
- package/src/index.ts +1 -0
- package/src/types/collection_editor_controller.tsx +14 -4
- package/src/types/collection_inference.ts +1 -1
- package/src/ui/CollectionViewHeaderAction.tsx +9 -4
- package/src/ui/EditorCollectionAction.tsx +10 -63
- package/src/ui/EditorCollectionActionStart.tsx +88 -0
- package/src/ui/HomePageEditorCollectionAction.tsx +18 -13
- package/src/ui/NewCollectionButton.tsx +12 -10
- package/src/ui/NewCollectionCard.tsx +3 -3
- package/src/ui/PropertyAddColumnComponent.tsx +9 -4
- package/src/ui/collection_editor/CollectionDetailsForm.tsx +69 -8
- package/src/ui/collection_editor/CollectionEditorDialog.tsx +57 -32
- package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +6 -5
- package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +33 -27
- package/src/ui/collection_editor/GetCodeDialog.tsx +15 -3
- package/src/ui/collection_editor/PropertyEditView.tsx +21 -13
- package/src/ui/collection_editor/PropertyFieldPreview.tsx +3 -6
- package/src/ui/collection_editor/PropertySelectItem.tsx +3 -3
- package/src/ui/collection_editor/PropertyTree.tsx +7 -5
- package/src/ui/collection_editor/SubcollectionsEditTab.tsx +26 -19
- package/src/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +25 -9
- package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +9 -7
- package/src/ui/collection_editor/properties/BlockPropertyField.tsx +14 -8
- package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +50 -47
- package/src/ui/collection_editor/properties/EnumPropertyField.tsx +1 -1
- package/src/ui/collection_editor/properties/MapPropertyField.tsx +5 -5
- package/src/ui/collection_editor/properties/MarkdownPropertyField.tsx +139 -0
- package/src/ui/collection_editor/properties/RepeatPropertyField.tsx +0 -1
- package/src/ui/collection_editor/properties/StoragePropertyField.tsx +31 -16
- package/src/ui/collection_editor/properties/StringPropertyField.tsx +1 -10
- package/src/ui/collection_editor/templates/pages_template.ts +1 -6
- package/src/useCollectionEditorPlugin.tsx +37 -27
- package/src/utils/collections.ts +30 -0
- package/dist/ui/RootCollectionSuggestions.d.ts +0 -3
- package/src/ui/RootCollectionSuggestions.tsx +0 -63
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import React from "react";
|
|
1
2
|
import { CollectionEditorPermissionsBuilder } from "./config_permissions";
|
|
2
|
-
import { Property } from "@firecms/core";
|
|
3
|
+
import { Entity, Property } from "@firecms/core";
|
|
3
4
|
import { PersistedCollection } from "./persisted_collection";
|
|
4
5
|
/**
|
|
5
6
|
* Controller to open the collection editor dialog.
|
|
@@ -11,6 +12,7 @@ export interface CollectionEditorController {
|
|
|
11
12
|
fullPath?: string;
|
|
12
13
|
parentCollectionIds: string[];
|
|
13
14
|
parentCollection?: PersistedCollection;
|
|
15
|
+
existingEntities?: Entity<any>[];
|
|
14
16
|
}) => void;
|
|
15
17
|
createCollection: (props: {
|
|
16
18
|
initialValues?: {
|
|
@@ -30,7 +32,17 @@ export interface CollectionEditorController {
|
|
|
30
32
|
editedCollectionId: string;
|
|
31
33
|
parentCollectionIds: string[];
|
|
32
34
|
collection: PersistedCollection;
|
|
35
|
+
existingEntities: Entity<any>[];
|
|
33
36
|
}) => void;
|
|
34
37
|
configPermissions: CollectionEditorPermissionsBuilder;
|
|
35
|
-
|
|
38
|
+
getPathSuggestions?: (path: string) => Promise<string[]>;
|
|
39
|
+
components?: {
|
|
40
|
+
/**
|
|
41
|
+
* Custom component to render the database field
|
|
42
|
+
*/
|
|
43
|
+
DatabaseField?: React.ComponentType<{
|
|
44
|
+
databaseId?: string;
|
|
45
|
+
onDatabaseIdUpdate: (databaseId: string) => void;
|
|
46
|
+
}>;
|
|
47
|
+
};
|
|
36
48
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { EntityCollection } from "@firecms/core";
|
|
2
|
-
export type CollectionInference = (path: string, collectionGroup: boolean,
|
|
2
|
+
export type CollectionInference = (path: string, collectionGroup: boolean, parentCollectionPaths: string[]) => Promise<Partial<EntityCollection> | null>;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { ResolvedProperty } from "@firecms/core";
|
|
1
|
+
import { EntityTableController, ResolvedProperty } from "@firecms/core";
|
|
2
2
|
import { PersistedCollection } from "../types/persisted_collection";
|
|
3
|
-
export declare function CollectionViewHeaderAction({ propertyKey, onHover, property, fullPath, parentCollectionIds, collection }: {
|
|
3
|
+
export declare function CollectionViewHeaderAction({ propertyKey, onHover, property, fullPath, parentCollectionIds, collection, tableController }: {
|
|
4
4
|
property: ResolvedProperty;
|
|
5
5
|
propertyKey: string;
|
|
6
6
|
onHover: boolean;
|
|
7
7
|
fullPath: string;
|
|
8
8
|
parentCollectionIds: string[];
|
|
9
9
|
collection: PersistedCollection;
|
|
10
|
+
tableController: EntityTableController;
|
|
10
11
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { EntityTableController } from "@firecms/core";
|
|
1
2
|
import { PersistedCollection } from "../types/persisted_collection";
|
|
2
|
-
export declare function PropertyAddColumnComponent({ fullPath, parentCollectionIds, collection }: {
|
|
3
|
+
export declare function PropertyAddColumnComponent({ fullPath, parentCollectionIds, collection, tableController }: {
|
|
3
4
|
fullPath: string;
|
|
4
5
|
parentCollectionIds: string[];
|
|
5
6
|
collection: PersistedCollection;
|
|
7
|
+
tableController: EntityTableController;
|
|
6
8
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { EntityCollection, User } from "@firecms/core";
|
|
2
|
+
import { Entity, EntityCollection, User } from "@firecms/core";
|
|
3
3
|
import { CollectionsConfigController } from "../../types/config_controller";
|
|
4
4
|
import { CollectionInference } from "../../types/collection_inference";
|
|
5
5
|
import { PersistedCollection } from "../../types/persisted_collection";
|
|
@@ -25,12 +25,13 @@ export interface CollectionEditorDialogProps {
|
|
|
25
25
|
icon: React.ReactNode;
|
|
26
26
|
};
|
|
27
27
|
pathSuggestions?: (path?: string) => Promise<string[]>;
|
|
28
|
-
getUser
|
|
28
|
+
getUser?: (uid: string) => User | null;
|
|
29
29
|
getData?: (path: string, parentPaths: string[]) => Promise<object[]>;
|
|
30
30
|
parentCollection?: PersistedCollection;
|
|
31
|
+
existingEntities?: Entity<any>[];
|
|
31
32
|
}
|
|
32
33
|
export declare function CollectionEditorDialog(props: CollectionEditorDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
33
|
-
export declare function CollectionEditor
|
|
34
|
+
export declare function CollectionEditor(props: CollectionEditorDialogProps & {
|
|
34
35
|
handleCancel: () => void;
|
|
35
36
|
setFormDirty: (dirty: boolean) => void;
|
|
36
37
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -4,7 +4,7 @@ export declare function CollectionEditorWelcomeView({ path, pathSuggestions, par
|
|
|
4
4
|
path: string;
|
|
5
5
|
pathSuggestions?: (path: string) => Promise<string[]>;
|
|
6
6
|
parentCollection?: EntityCollection;
|
|
7
|
-
onContinue: (importData?: object[]) => void;
|
|
7
|
+
onContinue: (importData?: object[], propertiesOrder?: string[]) => void;
|
|
8
8
|
existingCollectionPaths?: string[];
|
|
9
9
|
}): import("react/jsx-runtime").JSX.Element;
|
|
10
10
|
export declare function TemplateButton({ title, subtitle, icon, onClick }: {
|
|
@@ -9,7 +9,7 @@ type CollectionEditorFormProps = {
|
|
|
9
9
|
setDirty?: (dirty: boolean) => void;
|
|
10
10
|
reservedGroups?: string[];
|
|
11
11
|
extraIcon: React.ReactNode;
|
|
12
|
-
getUser
|
|
12
|
+
getUser?: (uid: string) => User | null;
|
|
13
13
|
getData?: () => Promise<object[]>;
|
|
14
14
|
doCollectionInference: (collection: PersistedCollection) => Promise<Partial<EntityCollection> | null> | undefined;
|
|
15
15
|
propertyConfigs: Record<string, PropertyConfig>;
|
|
@@ -4,17 +4,17 @@ import { DraggableProvided } from "@hello-pangea/dnd";
|
|
|
4
4
|
export declare const PropertyTree: React.MemoExoticComponent<(<M extends {
|
|
5
5
|
[Key: string]: CMSType;
|
|
6
6
|
}>({ namespace, selectedPropertyKey, onPropertyClick, properties, propertiesOrder: propertiesOrderProp, additionalFields, errors, onPropertyMove, onPropertyRemove, className, inferredPropertyKeys, collectionEditable }: {
|
|
7
|
-
namespace?: string
|
|
8
|
-
selectedPropertyKey?: string
|
|
9
|
-
onPropertyClick?: (
|
|
7
|
+
namespace?: string;
|
|
8
|
+
selectedPropertyKey?: string;
|
|
9
|
+
onPropertyClick?: (propertyKey: string, namespace?: string) => void;
|
|
10
10
|
properties: PropertiesOrBuilders<M>;
|
|
11
|
-
propertiesOrder?: string[]
|
|
12
|
-
additionalFields?: AdditionalFieldDelegate<M
|
|
11
|
+
propertiesOrder?: string[];
|
|
12
|
+
additionalFields?: AdditionalFieldDelegate<M>[];
|
|
13
13
|
errors: Record<string, any>;
|
|
14
|
-
onPropertyMove?: (
|
|
15
|
-
onPropertyRemove?: (
|
|
16
|
-
className?: string
|
|
17
|
-
inferredPropertyKeys?: string[]
|
|
14
|
+
onPropertyMove?: (propertiesOrder: string[], namespace?: string) => void;
|
|
15
|
+
onPropertyRemove?: (propertyKey: string, namespace?: string) => void;
|
|
16
|
+
className?: string;
|
|
17
|
+
inferredPropertyKeys?: string[];
|
|
18
18
|
collectionEditable: boolean;
|
|
19
19
|
}) => import("react/jsx-runtime").JSX.Element)>;
|
|
20
20
|
export declare function PropertyTreeEntry({ propertyKey, namespace, propertyOrBuilder, additionalField, provided, selectedPropertyKey, errors, onPropertyClick, onPropertyMove, onPropertyRemove, inferredPropertyKeys, collectionEditable }: {
|
|
@@ -7,6 +7,6 @@ export declare function SubcollectionsEditTab({ collection, parentCollection, co
|
|
|
7
7
|
parentCollection?: EntityCollection;
|
|
8
8
|
configController: CollectionsConfigController;
|
|
9
9
|
collectionInference?: CollectionInference;
|
|
10
|
-
getUser
|
|
10
|
+
getUser?: (uid: string) => User | null;
|
|
11
11
|
parentCollectionIds?: string[];
|
|
12
12
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare function StringPropertyField({ widgetId, disabled, showErrors }: {
|
|
2
|
-
widgetId: "text_field" | "multiline" | "
|
|
2
|
+
widgetId: "text_field" | "multiline" | "email";
|
|
3
3
|
disabled: boolean;
|
|
4
4
|
showErrors: boolean;
|
|
5
5
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -18,19 +18,27 @@ export interface CollectionConfigControllerProps<EC extends PersistedCollection
|
|
|
18
18
|
* names when creating collections.
|
|
19
19
|
* e.g. ["admin"]
|
|
20
20
|
*/
|
|
21
|
-
reservedGroups
|
|
21
|
+
reservedGroups?: string[];
|
|
22
22
|
extraView?: {
|
|
23
23
|
View: React.ComponentType<{
|
|
24
24
|
path: string;
|
|
25
25
|
}>;
|
|
26
26
|
icon: React.ReactNode;
|
|
27
27
|
};
|
|
28
|
-
|
|
28
|
+
getPathSuggestions?: (path?: string) => Promise<string[]>;
|
|
29
29
|
collectionInference?: CollectionInference;
|
|
30
30
|
getData?: (path: string, parentPaths: string[]) => Promise<object[]>;
|
|
31
|
-
getUser
|
|
31
|
+
getUser?: (uid: string) => UserType | null;
|
|
32
32
|
onAnalyticsEvent?: (event: string, params?: object) => void;
|
|
33
|
-
|
|
33
|
+
components?: {
|
|
34
|
+
/**
|
|
35
|
+
* Custom component to render the database field
|
|
36
|
+
*/
|
|
37
|
+
DatabaseField?: React.ComponentType<{
|
|
38
|
+
databaseId?: string;
|
|
39
|
+
onDatabaseIdUpdate: (databaseId: string) => void;
|
|
40
|
+
}>;
|
|
41
|
+
};
|
|
34
42
|
}
|
|
35
43
|
/**
|
|
36
44
|
* Use this hook to initialise the Collection Editor plugin.
|
|
@@ -39,11 +47,9 @@ export interface CollectionConfigControllerProps<EC extends PersistedCollection
|
|
|
39
47
|
* @param configPermissions
|
|
40
48
|
* @param reservedGroups
|
|
41
49
|
* @param extraView
|
|
42
|
-
* @param
|
|
50
|
+
* @param getData
|
|
43
51
|
* @param getUser
|
|
44
52
|
* @param collectionInference
|
|
45
53
|
*/
|
|
46
|
-
export declare function useCollectionEditorPlugin<EC extends PersistedCollection = PersistedCollection, UserType extends User = User>({ collectionConfigController,
|
|
47
|
-
export declare function IntroWidget({
|
|
48
|
-
introMode?: "new_project" | "existing_project";
|
|
49
|
-
}): import("react/jsx-runtime").JSX.Element;
|
|
54
|
+
export declare function useCollectionEditorPlugin<EC extends PersistedCollection = PersistedCollection, UserType extends User = User>({ collectionConfigController, configPermissions, reservedGroups, extraView, getPathSuggestions, getUser, collectionInference, getData, onAnalyticsEvent, components }: CollectionConfigControllerProps<EC, UserType>): FireCMSPlugin<any, any, PersistedCollection>;
|
|
55
|
+
export declare function IntroWidget({}: {}): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { EntityCollection, ModifyCollectionProps } from "@firecms/core";
|
|
2
|
+
import { PersistedCollection } from "../types/persisted_collection";
|
|
3
|
+
/**
|
|
4
|
+
* Function in charge of merging collections defined in code with those stored in the backend.
|
|
5
|
+
*/
|
|
6
|
+
export declare const mergeCollections: (baseCollections: EntityCollection[], backendCollections: PersistedCollection[], modifyCollection?: (props: ModifyCollectionProps) => EntityCollection | void) => EntityCollection<any, any>[];
|
package/package.json
CHANGED
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firecms/collection_editor",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0.0-canary.
|
|
4
|
+
"version": "3.0.0-canary.131",
|
|
5
5
|
"main": "./dist/index.umd.js",
|
|
6
6
|
"module": "./dist/index.es.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"source": "src/index.ts",
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@firecms/
|
|
11
|
-
"@firecms/
|
|
12
|
-
"@firecms/
|
|
13
|
-
"@firecms/
|
|
10
|
+
"@firecms/data_export": "^3.0.0-canary.131",
|
|
11
|
+
"@firecms/data_import": "^3.0.0-canary.131",
|
|
12
|
+
"@firecms/data_import_export": "^3.0.0-canary.131",
|
|
13
|
+
"@firecms/formex": "^3.0.0-canary.131",
|
|
14
|
+
"@firecms/schema_inference": "^3.0.0-canary.131",
|
|
15
|
+
"@firecms/ui": "^3.0.0-canary.131",
|
|
14
16
|
"json5": "^2.2.3",
|
|
15
17
|
"prism-react-renderer": "^2.3.1"
|
|
16
18
|
},
|
|
17
19
|
"peerDependencies": {
|
|
18
|
-
"react": "^18.
|
|
19
|
-
"react-dom": "^18.
|
|
20
|
-
"react-router": "^6.
|
|
21
|
-
"react-router-dom": "^6.
|
|
20
|
+
"react": "^18.3.1",
|
|
21
|
+
"react-dom": "^18.3.1",
|
|
22
|
+
"react-router": "^6.25.1",
|
|
23
|
+
"react-router-dom": "^6.25.1"
|
|
22
24
|
},
|
|
23
25
|
"exports": {
|
|
24
26
|
".": {
|
|
@@ -34,12 +36,6 @@
|
|
|
34
36
|
"build": "vite build && tsc --emitDeclarationOnly -p tsconfig.prod.json",
|
|
35
37
|
"clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f"
|
|
36
38
|
},
|
|
37
|
-
"eslintConfig": {
|
|
38
|
-
"extends": [
|
|
39
|
-
"react-app",
|
|
40
|
-
"react-app/jest"
|
|
41
|
-
]
|
|
42
|
-
},
|
|
43
39
|
"browserslist": {
|
|
44
40
|
"production": [
|
|
45
41
|
">0.2%",
|
|
@@ -54,25 +50,15 @@
|
|
|
54
50
|
},
|
|
55
51
|
"devDependencies": {
|
|
56
52
|
"@jest/globals": "^29.7.0",
|
|
57
|
-
"@types/react": "^18.
|
|
58
|
-
"@types/react-dom": "^18.
|
|
59
|
-
"@
|
|
60
|
-
"@typescript-eslint/parser": "^7.3.1",
|
|
61
|
-
"@vitejs/plugin-react": "^4.2.1",
|
|
62
|
-
"eslint": "^8.57.0",
|
|
63
|
-
"eslint-config-standard": "^17.1.0",
|
|
64
|
-
"eslint-plugin-import": "^2.29.1",
|
|
65
|
-
"eslint-plugin-n": "^16.6.2",
|
|
66
|
-
"eslint-plugin-promise": "^6.1.1",
|
|
67
|
-
"eslint-plugin-react": "^7.34.1",
|
|
68
|
-
"eslint-plugin-react-hooks": "^4.6.0",
|
|
53
|
+
"@types/react": "^18.3.3",
|
|
54
|
+
"@types/react-dom": "^18.3.0",
|
|
55
|
+
"@vitejs/plugin-react": "^4.3.1",
|
|
69
56
|
"jest": "^29.7.0",
|
|
70
|
-
"react-router": "^6.
|
|
71
|
-
"react-router-dom": "^6.
|
|
72
|
-
"ts-jest": "^29.
|
|
73
|
-
"typescript": "^5.4
|
|
74
|
-
"vite": "^5.
|
|
75
|
-
"vite-plugin-fonts": "^0.7.0"
|
|
57
|
+
"react-router": "^6.25.1",
|
|
58
|
+
"react-router-dom": "^6.25.1",
|
|
59
|
+
"ts-jest": "^29.2.3",
|
|
60
|
+
"typescript": "^5.5.4",
|
|
61
|
+
"vite": "^5.3.4"
|
|
76
62
|
},
|
|
77
63
|
"files": [
|
|
78
64
|
"dist",
|
|
@@ -81,5 +67,5 @@
|
|
|
81
67
|
"publishConfig": {
|
|
82
68
|
"access": "public"
|
|
83
69
|
},
|
|
84
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "4ed84e51a0d5d3409f8ea7371c41af4377128110"
|
|
85
71
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import React, { PropsWithChildren, useCallback
|
|
1
|
+
import React, { PropsWithChildren, useCallback } from "react";
|
|
2
2
|
import equal from "react-fast-compare"
|
|
3
3
|
|
|
4
4
|
import { CollectionsConfigController } from "./types/config_controller";
|
|
5
5
|
import {
|
|
6
|
+
Entity,
|
|
6
7
|
Property,
|
|
7
8
|
useCustomizationController,
|
|
8
9
|
useNavigationController,
|
|
@@ -48,14 +49,21 @@ export interface ConfigControllerProviderProps {
|
|
|
48
49
|
icon: React.ReactNode
|
|
49
50
|
};
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
getPathSuggestions?: (path?: string) => Promise<string[]>;
|
|
52
53
|
|
|
53
|
-
getUser
|
|
54
|
+
getUser?: (uid: string) => User | null
|
|
54
55
|
|
|
55
56
|
getData?: (path: string, parentPaths: string[]) => Promise<object[]>;
|
|
56
57
|
|
|
57
58
|
onAnalyticsEvent?: (event: string, params?: object) => void;
|
|
58
59
|
|
|
60
|
+
components?: {
|
|
61
|
+
/**
|
|
62
|
+
* Custom component to render the database field
|
|
63
|
+
*/
|
|
64
|
+
DatabaseField?: React.ComponentType<{ databaseId?: string, onDatabaseIdUpdate: (databaseId:string) => void }>;
|
|
65
|
+
};
|
|
66
|
+
|
|
59
67
|
}
|
|
60
68
|
|
|
61
69
|
export const ConfigControllerProvider = React.memo(
|
|
@@ -66,10 +74,11 @@ export const ConfigControllerProvider = React.memo(
|
|
|
66
74
|
reservedGroups,
|
|
67
75
|
collectionInference,
|
|
68
76
|
extraView,
|
|
69
|
-
|
|
77
|
+
getPathSuggestions,
|
|
70
78
|
getUser,
|
|
71
79
|
getData,
|
|
72
|
-
onAnalyticsEvent
|
|
80
|
+
onAnalyticsEvent,
|
|
81
|
+
components
|
|
73
82
|
}: PropsWithChildren<ConfigControllerProviderProps>) {
|
|
74
83
|
|
|
75
84
|
const navigation = useNavigationController();
|
|
@@ -77,20 +86,6 @@ export const ConfigControllerProvider = React.memo(
|
|
|
77
86
|
const snackbarController = useSnackbarController();
|
|
78
87
|
const { propertyConfigs } = useCustomizationController();
|
|
79
88
|
|
|
80
|
-
const {
|
|
81
|
-
collections
|
|
82
|
-
} = navigation;
|
|
83
|
-
const existingPaths = (collections ?? []).map(col => col.path.trim().toLowerCase());
|
|
84
|
-
|
|
85
|
-
const [rootPathSuggestions, setRootPathSuggestions] = React.useState<string[] | undefined>();
|
|
86
|
-
useEffect(() => {
|
|
87
|
-
if (pathSuggestions) {
|
|
88
|
-
pathSuggestions().then((paths) => {
|
|
89
|
-
setRootPathSuggestions(paths.filter(p => !existingPaths.includes(p.trim().toLowerCase())));
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
}, [pathSuggestions]);
|
|
93
|
-
|
|
94
89
|
const [currentDialog, setCurrentDialog] = React.useState<{
|
|
95
90
|
isNewCollection: boolean,
|
|
96
91
|
parentCollection?: PersistedCollection,
|
|
@@ -102,7 +97,8 @@ export const ConfigControllerProvider = React.memo(
|
|
|
102
97
|
group?: string,
|
|
103
98
|
name?: string
|
|
104
99
|
},
|
|
105
|
-
redirect: boolean
|
|
100
|
+
redirect: boolean,
|
|
101
|
+
existingEntities?: Entity<any>[]
|
|
106
102
|
}>();
|
|
107
103
|
|
|
108
104
|
const [currentPropertyDialog, setCurrentPropertyDialog] = React.useState<{
|
|
@@ -115,6 +111,7 @@ export const ConfigControllerProvider = React.memo(
|
|
|
115
111
|
fullPath?: string,
|
|
116
112
|
parentCollectionIds: string[],
|
|
117
113
|
collectionEditable: boolean;
|
|
114
|
+
existingEntities?: Entity<any>[]
|
|
118
115
|
}>();
|
|
119
116
|
|
|
120
117
|
const defaultConfigPermissions: CollectionEditorPermissionsBuilder = useCallback(() => ({
|
|
@@ -123,46 +120,57 @@ export const ConfigControllerProvider = React.memo(
|
|
|
123
120
|
deleteCollections: true
|
|
124
121
|
}), []);
|
|
125
122
|
|
|
126
|
-
const editCollection =
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
123
|
+
const editCollection = ({
|
|
124
|
+
id,
|
|
125
|
+
fullPath,
|
|
126
|
+
parentCollectionIds,
|
|
127
|
+
parentCollection,
|
|
128
|
+
existingEntities
|
|
129
|
+
}: {
|
|
132
130
|
id?: string,
|
|
133
131
|
fullPath?: string,
|
|
134
132
|
parentCollectionIds: string[],
|
|
135
|
-
parentCollection?: PersistedCollection
|
|
133
|
+
parentCollection?: PersistedCollection,
|
|
134
|
+
existingEntities?: Entity<any>[]
|
|
136
135
|
}) => {
|
|
137
136
|
console.debug("Edit collection", id, fullPath, parentCollectionIds, parentCollection);
|
|
138
|
-
onAnalyticsEvent?.("edit_collection", {
|
|
137
|
+
onAnalyticsEvent?.("edit_collection", {
|
|
138
|
+
id,
|
|
139
|
+
fullPath
|
|
140
|
+
});
|
|
139
141
|
setCurrentDialog({
|
|
140
142
|
editedCollectionId: id,
|
|
141
143
|
fullPath,
|
|
142
144
|
parentCollectionIds,
|
|
143
145
|
isNewCollection: false,
|
|
144
146
|
parentCollection,
|
|
145
|
-
redirect: false
|
|
147
|
+
redirect: false,
|
|
148
|
+
existingEntities
|
|
146
149
|
});
|
|
147
|
-
}
|
|
150
|
+
};
|
|
148
151
|
|
|
149
|
-
const editProperty =
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
152
|
+
const editProperty = ({
|
|
153
|
+
propertyKey,
|
|
154
|
+
property,
|
|
155
|
+
editedCollectionId,
|
|
156
|
+
currentPropertiesOrder,
|
|
157
|
+
parentCollectionIds,
|
|
158
|
+
collection,
|
|
159
|
+
existingEntities
|
|
160
|
+
}: {
|
|
157
161
|
propertyKey?: string,
|
|
158
162
|
property?: Property,
|
|
159
163
|
currentPropertiesOrder?: string[],
|
|
160
164
|
editedCollectionId: string,
|
|
161
165
|
parentCollectionIds: string[],
|
|
162
166
|
collection: PersistedCollection,
|
|
167
|
+
existingEntities?: Entity<any>[]
|
|
163
168
|
}) => {
|
|
164
169
|
console.debug("Edit property", propertyKey, property, editedCollectionId, currentPropertiesOrder, parentCollectionIds, collection);
|
|
165
|
-
onAnalyticsEvent?.("edit_property", {
|
|
170
|
+
onAnalyticsEvent?.("edit_property", {
|
|
171
|
+
propertyKey,
|
|
172
|
+
editedCollectionId
|
|
173
|
+
});
|
|
166
174
|
// namespace is all the path until the last dot
|
|
167
175
|
const namespace = propertyKey && propertyKey.includes(".")
|
|
168
176
|
? propertyKey.substring(0, propertyKey.lastIndexOf("."))
|
|
@@ -175,19 +183,20 @@ export const ConfigControllerProvider = React.memo(
|
|
|
175
183
|
property,
|
|
176
184
|
namespace,
|
|
177
185
|
currentPropertiesOrder,
|
|
178
|
-
editedCollectionId
|
|
186
|
+
editedCollectionId,
|
|
179
187
|
parentCollectionIds,
|
|
180
|
-
collectionEditable: collection?.editable ?? false
|
|
188
|
+
collectionEditable: collection?.editable ?? false,
|
|
189
|
+
existingEntities
|
|
181
190
|
});
|
|
182
|
-
}
|
|
191
|
+
};
|
|
183
192
|
|
|
184
|
-
const createCollection =
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
193
|
+
const createCollection = ({
|
|
194
|
+
parentCollectionIds,
|
|
195
|
+
parentCollection,
|
|
196
|
+
initialValues,
|
|
197
|
+
redirect,
|
|
198
|
+
sourceClick
|
|
199
|
+
}: {
|
|
191
200
|
parentCollectionIds: string[],
|
|
192
201
|
parentCollection?: PersistedCollection
|
|
193
202
|
initialValues?: {
|
|
@@ -198,8 +207,20 @@ export const ConfigControllerProvider = React.memo(
|
|
|
198
207
|
redirect: boolean,
|
|
199
208
|
sourceClick?: string
|
|
200
209
|
}) => {
|
|
201
|
-
console.debug("Create collection", {
|
|
202
|
-
|
|
210
|
+
console.debug("Create collection", {
|
|
211
|
+
parentCollectionIds,
|
|
212
|
+
parentCollection,
|
|
213
|
+
initialValues,
|
|
214
|
+
redirect,
|
|
215
|
+
sourceClick
|
|
216
|
+
});
|
|
217
|
+
onAnalyticsEvent?.("create_collection", {
|
|
218
|
+
parentCollectionIds,
|
|
219
|
+
parentCollection,
|
|
220
|
+
initialValues,
|
|
221
|
+
redirect,
|
|
222
|
+
sourceClick
|
|
223
|
+
});
|
|
203
224
|
setCurrentDialog({
|
|
204
225
|
isNewCollection: true,
|
|
205
226
|
parentCollectionIds,
|
|
@@ -207,17 +228,7 @@ export const ConfigControllerProvider = React.memo(
|
|
|
207
228
|
initialValues,
|
|
208
229
|
redirect
|
|
209
230
|
});
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
const getPathSuggestions = !pathSuggestions
|
|
213
|
-
? undefined
|
|
214
|
-
: (path?: string) => {
|
|
215
|
-
if (!path && rootPathSuggestions)
|
|
216
|
-
return Promise.resolve(rootPathSuggestions);
|
|
217
|
-
else {
|
|
218
|
-
return pathSuggestions?.(path);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
231
|
+
};
|
|
221
232
|
|
|
222
233
|
return (
|
|
223
234
|
<ConfigControllerContext.Provider value={collectionConfigController}>
|
|
@@ -227,7 +238,8 @@ export const ConfigControllerProvider = React.memo(
|
|
|
227
238
|
createCollection,
|
|
228
239
|
editProperty,
|
|
229
240
|
configPermissions: configPermissions ?? defaultConfigPermissions,
|
|
230
|
-
|
|
241
|
+
getPathSuggestions,
|
|
242
|
+
components
|
|
231
243
|
}}>
|
|
232
244
|
|
|
233
245
|
{children}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import React from "react";
|
|
1
2
|
import { CollectionEditorPermissionsBuilder } from "./config_permissions";
|
|
2
|
-
import { Property } from "@firecms/core";
|
|
3
|
+
import { Entity, Property } from "@firecms/core";
|
|
3
4
|
import { PersistedCollection } from "./persisted_collection";
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -12,7 +13,8 @@ export interface CollectionEditorController {
|
|
|
12
13
|
id?: string,
|
|
13
14
|
fullPath?: string,
|
|
14
15
|
parentCollectionIds: string[],
|
|
15
|
-
parentCollection?: PersistedCollection
|
|
16
|
+
parentCollection?: PersistedCollection,
|
|
17
|
+
existingEntities?: Entity<any>[]
|
|
16
18
|
}) => void;
|
|
17
19
|
|
|
18
20
|
createCollection: (props: {
|
|
@@ -33,11 +35,19 @@ export interface CollectionEditorController {
|
|
|
33
35
|
currentPropertiesOrder?: string[],
|
|
34
36
|
editedCollectionId: string,
|
|
35
37
|
parentCollectionIds: string[],
|
|
36
|
-
collection: PersistedCollection
|
|
38
|
+
collection: PersistedCollection,
|
|
39
|
+
existingEntities: Entity<any>[]
|
|
37
40
|
}) => void;
|
|
38
41
|
|
|
39
42
|
configPermissions: CollectionEditorPermissionsBuilder;
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
getPathSuggestions?: (path: string) => Promise<string[]>;
|
|
45
|
+
|
|
46
|
+
components?: {
|
|
47
|
+
/**
|
|
48
|
+
* Custom component to render the database field
|
|
49
|
+
*/
|
|
50
|
+
DatabaseField?: React.ComponentType<{ databaseId?: string, onDatabaseIdUpdate: (databaseId: string) => void }>;
|
|
51
|
+
};
|
|
42
52
|
|
|
43
53
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { EntityCollection } from "@firecms/core";
|
|
2
2
|
|
|
3
|
-
export type CollectionInference = (path: string, collectionGroup: boolean,
|
|
3
|
+
export type CollectionInference = (path: string, collectionGroup: boolean, parentCollectionPaths: string[]) => Promise<Partial<EntityCollection> | null>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ResolvedProperty } from "@firecms/core";
|
|
1
|
+
import { EntityTableController, ResolvedProperty } from "@firecms/core";
|
|
2
2
|
import { IconButton, SettingsIcon, Tooltip } from "@firecms/ui";
|
|
3
3
|
import React from "react";
|
|
4
4
|
import { useCollectionEditorController } from "../useCollectionEditorController";
|
|
@@ -10,7 +10,8 @@ export function CollectionViewHeaderAction({
|
|
|
10
10
|
property,
|
|
11
11
|
fullPath,
|
|
12
12
|
parentCollectionIds,
|
|
13
|
-
collection
|
|
13
|
+
collection,
|
|
14
|
+
tableController
|
|
14
15
|
}: {
|
|
15
16
|
property: ResolvedProperty,
|
|
16
17
|
propertyKey: string,
|
|
@@ -18,12 +19,15 @@ export function CollectionViewHeaderAction({
|
|
|
18
19
|
fullPath: string,
|
|
19
20
|
parentCollectionIds: string[],
|
|
20
21
|
collection: PersistedCollection;
|
|
22
|
+
tableController: EntityTableController;
|
|
21
23
|
}) {
|
|
22
24
|
|
|
23
25
|
const collectionEditorController = useCollectionEditorController();
|
|
24
26
|
|
|
25
27
|
return (
|
|
26
|
-
<Tooltip
|
|
28
|
+
<Tooltip
|
|
29
|
+
asChild={true}
|
|
30
|
+
title={"Edit"}>
|
|
27
31
|
<IconButton
|
|
28
32
|
className={onHover ? "bg-white dark:bg-gray-950" : "hidden"}
|
|
29
33
|
onClick={() => {
|
|
@@ -32,7 +36,8 @@ export function CollectionViewHeaderAction({
|
|
|
32
36
|
property,
|
|
33
37
|
editedCollectionId: collection.id,
|
|
34
38
|
parentCollectionIds,
|
|
35
|
-
collection
|
|
39
|
+
collection,
|
|
40
|
+
existingEntities: tableController.data ?? []
|
|
36
41
|
});
|
|
37
42
|
}}
|
|
38
43
|
size={"small"}>
|