@firecms/collection_editor 3.0.0-beta.13 → 3.0.0-beta.15
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/README.md +165 -1
- package/dist/ConfigControllerProvider.d.ts +0 -1
- package/dist/index.es.js +1620 -948
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +1616 -947
- package/dist/index.umd.js.map +1 -1
- package/dist/types/collection_editor_controller.d.ts +0 -1
- package/dist/types/collection_inference.d.ts +3 -0
- package/dist/types/config_controller.d.ts +3 -1
- package/dist/ui/EditorEntityAction.d.ts +2 -0
- 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/EntityActionsEditTab.d.ts +4 -0
- package/dist/ui/collection_editor/EntityActionsSelectDialog.d.ts +4 -0
- package/dist/ui/collection_editor/PropertyTree.d.ts +2 -3
- package/dist/ui/collection_editor/properties/ReferencePropertyField.d.ts +2 -1
- package/dist/useCollectionEditorPlugin.d.ts +3 -3
- package/package.json +8 -9
- package/src/ConfigControllerProvider.tsx +0 -5
- package/src/types/collection_editor_controller.tsx +0 -2
- package/src/types/collection_inference.ts +3 -0
- package/src/types/config_controller.tsx +4 -1
- package/src/ui/EditorCollectionAction.tsx +2 -7
- package/src/ui/EditorEntityAction.tsx +51 -0
- package/src/ui/HomePageEditorCollectionAction.tsx +2 -1
- package/src/ui/collection_editor/CollectionDetailsForm.tsx +69 -37
- package/src/ui/collection_editor/CollectionEditorDialog.tsx +18 -5
- package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +15 -25
- package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +8 -6
- package/src/ui/collection_editor/EntityActionsEditTab.tsx +163 -0
- package/src/ui/collection_editor/EntityActionsSelectDialog.tsx +41 -0
- package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +5 -2
- package/src/ui/collection_editor/GetCodeDialog.tsx +5 -3
- package/src/ui/collection_editor/PropertyEditView.tsx +11 -3
- package/src/ui/collection_editor/PropertyFieldPreview.tsx +1 -0
- package/src/ui/collection_editor/PropertyTree.tsx +183 -139
- package/src/ui/collection_editor/UnsavedChangesDialog.tsx +6 -2
- package/src/ui/collection_editor/properties/MapPropertyField.tsx +1 -1
- package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +5 -3
- package/src/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +2 -0
- package/src/ui/collection_editor/utils/supported_fields.tsx +1 -0
- package/src/ui/collection_editor/utils/update_property_for_widget.ts +9 -0
- package/src/useCollectionEditorPlugin.tsx +12 -7
- package/src/utils/collections.ts +15 -5
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
import { EntityCollection } from "@firecms/core";
|
|
2
|
+
/**
|
|
3
|
+
* This function is used to infer the configuration of a collection given its path.
|
|
4
|
+
*/
|
|
2
5
|
export type CollectionInference = (path: string, collectionGroup: boolean, parentCollectionPaths: string[]) => Promise<Partial<EntityCollection> | null>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CMSType, Property } from "@firecms/core";
|
|
1
|
+
import { CMSType, NavigationGroupMapping, Property } from "@firecms/core";
|
|
2
2
|
import { PersistedCollection } from "./persisted_collection";
|
|
3
3
|
/**
|
|
4
4
|
* Use this controller to access the configuration that is stored externally,
|
|
@@ -17,6 +17,8 @@ export interface CollectionsConfigController {
|
|
|
17
17
|
saveProperty: (params: SavePropertyParams) => Promise<void>;
|
|
18
18
|
deleteProperty: (params: DeletePropertyParams) => Promise<void>;
|
|
19
19
|
deleteCollection: (props: DeleteCollectionParams) => Promise<void>;
|
|
20
|
+
navigationEntries: NavigationGroupMapping[];
|
|
21
|
+
saveNavigationEntries: (entries: NavigationGroupMapping[]) => Promise<void>;
|
|
20
22
|
}
|
|
21
23
|
export type UpdateCollectionParams<M extends Record<string, any>> = {
|
|
22
24
|
id: string;
|
|
@@ -6,7 +6,7 @@ export declare function CollectionEditorWelcomeView({ path, pathSuggestions, par
|
|
|
6
6
|
parentCollection?: EntityCollection;
|
|
7
7
|
onContinue: (importData?: object[], propertiesOrder?: string[]) => void;
|
|
8
8
|
existingCollectionPaths?: string[];
|
|
9
|
-
}): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
10
10
|
export declare function TemplateButton({ title, subtitle, icon, onClick }: {
|
|
11
11
|
title: string;
|
|
12
12
|
icon: React.ReactNode;
|
|
@@ -11,7 +11,7 @@ type CollectionEditorFormProps = {
|
|
|
11
11
|
extraIcon: React.ReactNode;
|
|
12
12
|
getUser?: (uid: string) => User | null;
|
|
13
13
|
getData?: () => Promise<object[]>;
|
|
14
|
-
doCollectionInference
|
|
14
|
+
doCollectionInference?: (collection: PersistedCollection) => Promise<Partial<EntityCollection> | null> | undefined;
|
|
15
15
|
propertyConfigs: Record<string, PropertyConfig>;
|
|
16
16
|
collectionEditable: boolean;
|
|
17
17
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { AdditionalFieldDelegate, CMSType, PropertiesOrBuilders, PropertyOrBuilder } from "@firecms/core";
|
|
3
|
-
import { DraggableProvided } from "@hello-pangea/dnd";
|
|
4
3
|
export declare const PropertyTree: React.MemoExoticComponent<(<M extends {
|
|
5
4
|
[Key: string]: CMSType;
|
|
6
5
|
}>({ namespace, selectedPropertyKey, onPropertyClick, properties, propertiesOrder: propertiesOrderProp, additionalFields, errors, onPropertyMove, onPropertyRemove, className, inferredPropertyKeys, collectionEditable }: {
|
|
@@ -17,13 +16,13 @@ export declare const PropertyTree: React.MemoExoticComponent<(<M extends {
|
|
|
17
16
|
inferredPropertyKeys?: string[];
|
|
18
17
|
collectionEditable: boolean;
|
|
19
18
|
}) => import("react/jsx-runtime").JSX.Element)>;
|
|
20
|
-
export declare function PropertyTreeEntry({ propertyKey, namespace, propertyOrBuilder, additionalField,
|
|
19
|
+
export declare function PropertyTreeEntry({ id, propertyKey, namespace, propertyOrBuilder, additionalField, selectedPropertyKey, errors, onPropertyClick, onPropertyMove, onPropertyRemove, inferredPropertyKeys, collectionEditable }: {
|
|
20
|
+
id: string;
|
|
21
21
|
propertyKey: string;
|
|
22
22
|
namespace?: string;
|
|
23
23
|
propertyOrBuilder: PropertyOrBuilder;
|
|
24
24
|
additionalField?: AdditionalFieldDelegate<any>;
|
|
25
25
|
selectedPropertyKey?: string;
|
|
26
|
-
provided: DraggableProvided;
|
|
27
26
|
errors: Record<string, any>;
|
|
28
27
|
onPropertyClick?: (propertyKey: string, namespace?: string) => void;
|
|
29
28
|
onPropertyMove?: (propertiesOrder: string[], namespace?: string) => void;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export declare function ReferencePropertyField({ existing, multiple, disabled, showErrors }: {
|
|
1
|
+
export declare function ReferencePropertyField({ existing, multiple, disabled, showErrors, asString }: {
|
|
2
2
|
existing: boolean;
|
|
3
3
|
multiple: boolean;
|
|
4
4
|
disabled: boolean;
|
|
5
5
|
showErrors: boolean;
|
|
6
|
+
asString?: boolean;
|
|
6
7
|
}): import("react/jsx-runtime").JSX.Element;
|
|
7
8
|
export declare function CollectionsSelect({ disabled, pathPath, value, handleChange, error, ...props }: {
|
|
8
9
|
disabled: boolean;
|
|
@@ -25,11 +25,11 @@ export interface CollectionConfigControllerProps<EC extends PersistedCollection
|
|
|
25
25
|
}>;
|
|
26
26
|
icon: React.ReactNode;
|
|
27
27
|
};
|
|
28
|
-
getPathSuggestions?: (path?: string) => Promise<string[]>;
|
|
29
28
|
collectionInference?: CollectionInference;
|
|
30
29
|
getData?: (path: string, parentPaths: string[]) => Promise<object[]>;
|
|
31
30
|
getUser?: (uid: string) => USER | null;
|
|
32
31
|
onAnalyticsEvent?: (event: string, params?: object) => void;
|
|
32
|
+
includeIntroView?: boolean;
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* Use this hook to initialise the Collection Editor plugin.
|
|
@@ -42,5 +42,5 @@ export interface CollectionConfigControllerProps<EC extends PersistedCollection
|
|
|
42
42
|
* @param getUser
|
|
43
43
|
* @param collectionInference
|
|
44
44
|
*/
|
|
45
|
-
export declare function useCollectionEditorPlugin<EC extends PersistedCollection = PersistedCollection, USER extends User = User>({ collectionConfigController, configPermissions, reservedGroups, extraView,
|
|
46
|
-
export declare function IntroWidget(
|
|
45
|
+
export declare function useCollectionEditorPlugin<EC extends PersistedCollection = PersistedCollection, USER extends User = User>({ collectionConfigController, configPermissions, reservedGroups, extraView, getUser, collectionInference, getData, onAnalyticsEvent, includeIntroView }: CollectionConfigControllerProps<EC, USER>): FireCMSPlugin<any, any, PersistedCollection>;
|
|
46
|
+
export declare function IntroWidget(): import("react/jsx-runtime").JSX.Element | null;
|
package/package.json
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firecms/collection_editor",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0.0-beta.
|
|
4
|
+
"version": "3.0.0-beta.15",
|
|
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/data_export": "^3.0.0-beta.
|
|
11
|
-
"@firecms/data_import": "^3.0.0-beta.
|
|
12
|
-
"@firecms/data_import_export": "^3.0.0-beta.
|
|
13
|
-
"@firecms/formex": "^3.0.0-beta.
|
|
14
|
-
"@firecms/schema_inference": "^3.0.0-beta.
|
|
15
|
-
"@firecms/ui": "^3.0.0-beta.
|
|
16
|
-
"@hello-pangea/dnd": "^17.0.0",
|
|
10
|
+
"@firecms/data_export": "^3.0.0-beta.15",
|
|
11
|
+
"@firecms/data_import": "^3.0.0-beta.15",
|
|
12
|
+
"@firecms/data_import_export": "^3.0.0-beta.15",
|
|
13
|
+
"@firecms/formex": "^3.0.0-beta.15",
|
|
14
|
+
"@firecms/schema_inference": "^3.0.0-beta.15",
|
|
15
|
+
"@firecms/ui": "^3.0.0-beta.15",
|
|
17
16
|
"json5": "^2.2.3",
|
|
18
17
|
"prism-react-renderer": "^2.4.1"
|
|
19
18
|
},
|
|
@@ -70,5 +69,5 @@
|
|
|
70
69
|
"publishConfig": {
|
|
71
70
|
"access": "public"
|
|
72
71
|
},
|
|
73
|
-
"gitHead": "
|
|
72
|
+
"gitHead": "0abe2ca034f396e389db595f07ef4b24b439c648"
|
|
74
73
|
}
|
|
@@ -49,8 +49,6 @@ export interface ConfigControllerProviderProps {
|
|
|
49
49
|
icon: React.ReactNode
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
-
getPathSuggestions?: (path?: string) => Promise<string[]>;
|
|
53
|
-
|
|
54
52
|
getUser?: (uid: string) => User | null
|
|
55
53
|
|
|
56
54
|
getData?: (path: string, parentPaths: string[]) => Promise<object[]>;
|
|
@@ -67,7 +65,6 @@ export const ConfigControllerProvider = React.memo(
|
|
|
67
65
|
reservedGroups,
|
|
68
66
|
collectionInference,
|
|
69
67
|
extraView,
|
|
70
|
-
getPathSuggestions,
|
|
71
68
|
getUser,
|
|
72
69
|
getData,
|
|
73
70
|
onAnalyticsEvent,
|
|
@@ -230,7 +227,6 @@ export const ConfigControllerProvider = React.memo(
|
|
|
230
227
|
createCollection,
|
|
231
228
|
editProperty,
|
|
232
229
|
configPermissions: configPermissions ?? defaultConfigPermissions,
|
|
233
|
-
getPathSuggestions,
|
|
234
230
|
}}>
|
|
235
231
|
|
|
236
232
|
{children}
|
|
@@ -244,7 +240,6 @@ export const ConfigControllerProvider = React.memo(
|
|
|
244
240
|
getData={getData}
|
|
245
241
|
reservedGroups={reservedGroups}
|
|
246
242
|
extraView={extraView}
|
|
247
|
-
pathSuggestions={getPathSuggestions}
|
|
248
243
|
getUser={getUser}
|
|
249
244
|
handleClose={(collection) => {
|
|
250
245
|
if (currentDialog?.redirect) {
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import { EntityCollection } from "@firecms/core";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* This function is used to infer the configuration of a collection given its path.
|
|
5
|
+
*/
|
|
3
6
|
export type CollectionInference = (path: string, collectionGroup: boolean, parentCollectionPaths: string[]) => Promise<Partial<EntityCollection> | null>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CMSType, Property } from "@firecms/core";
|
|
1
|
+
import { CMSType, NavigationGroupMapping, Property } from "@firecms/core";
|
|
2
2
|
import { PersistedCollection } from "./persisted_collection";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -21,6 +21,9 @@ export interface CollectionsConfigController {
|
|
|
21
21
|
|
|
22
22
|
deleteCollection: (props: DeleteCollectionParams) => Promise<void>;
|
|
23
23
|
|
|
24
|
+
navigationEntries: NavigationGroupMapping[];
|
|
25
|
+
saveNavigationEntries: (entries: NavigationGroupMapping[]) => Promise<void>;
|
|
26
|
+
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
export type UpdateCollectionParams<M extends Record<string, any>> = {
|
|
@@ -28,6 +28,7 @@ export function EditorCollectionAction({
|
|
|
28
28
|
asChild={true}
|
|
29
29
|
title={canEditCollection ? "Edit collection" : "You don't have permissions to edit this collection"}>
|
|
30
30
|
<IconButton
|
|
31
|
+
size={"small"}
|
|
31
32
|
color={"primary"}
|
|
32
33
|
disabled={!canEditCollection}
|
|
33
34
|
onClick={canEditCollection
|
|
@@ -39,7 +40,7 @@ export function EditorCollectionAction({
|
|
|
39
40
|
existingEntities: tableController?.data ?? []
|
|
40
41
|
})
|
|
41
42
|
: undefined}>
|
|
42
|
-
<SettingsIcon/>
|
|
43
|
+
<SettingsIcon size={"small"}/>
|
|
43
44
|
</IconButton>
|
|
44
45
|
</Tooltip>;
|
|
45
46
|
|
|
@@ -48,9 +49,3 @@ export function EditorCollectionAction({
|
|
|
48
49
|
</>
|
|
49
50
|
|
|
50
51
|
}
|
|
51
|
-
|
|
52
|
-
function getObjectOrNull(o?: object): object | null {
|
|
53
|
-
if (o && Object.keys(o).length === 0)
|
|
54
|
-
return o
|
|
55
|
-
return o ?? null;
|
|
56
|
-
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { PluginFormActionProps, useAuthController, useNavigationController } from "@firecms/core";
|
|
2
|
+
import { IconButton, SettingsIcon, Tooltip, } from "@firecms/ui";
|
|
3
|
+
|
|
4
|
+
import { useCollectionEditorController } from "../useCollectionEditorController";
|
|
5
|
+
import { PersistedCollection } from "../types/persisted_collection";
|
|
6
|
+
|
|
7
|
+
export function EditorEntityAction({
|
|
8
|
+
path: fullPath,
|
|
9
|
+
parentCollectionIds,
|
|
10
|
+
collection,
|
|
11
|
+
formContext
|
|
12
|
+
}: PluginFormActionProps) {
|
|
13
|
+
|
|
14
|
+
const authController = useAuthController();
|
|
15
|
+
const navigationController = useNavigationController();
|
|
16
|
+
const collectionEditorController = useCollectionEditorController();
|
|
17
|
+
|
|
18
|
+
const parentCollection = navigationController.getCollectionFromIds(parentCollectionIds);
|
|
19
|
+
|
|
20
|
+
const canEditCollection = collectionEditorController.configPermissions
|
|
21
|
+
? collectionEditorController.configPermissions({
|
|
22
|
+
user: authController.user,
|
|
23
|
+
collection
|
|
24
|
+
}).editCollections
|
|
25
|
+
: true;
|
|
26
|
+
|
|
27
|
+
const isDirty = formContext?.formex.dirty ?? false;
|
|
28
|
+
|
|
29
|
+
const editorButton = <Tooltip
|
|
30
|
+
asChild={true}
|
|
31
|
+
title={canEditCollection ? (isDirty ? "You need to save the document before changing the schema" : "Edit schema for this form") : "You don't have permissions to edit this collection"}>
|
|
32
|
+
<IconButton
|
|
33
|
+
color={"primary"}
|
|
34
|
+
disabled={!canEditCollection || isDirty}
|
|
35
|
+
onClick={canEditCollection
|
|
36
|
+
? () => collectionEditorController?.editCollection({
|
|
37
|
+
id: collection.id,
|
|
38
|
+
fullPath,
|
|
39
|
+
parentCollectionIds,
|
|
40
|
+
parentCollection: parentCollection as PersistedCollection,
|
|
41
|
+
})
|
|
42
|
+
: undefined}>
|
|
43
|
+
<SettingsIcon size={"small"}/>
|
|
44
|
+
</IconButton>
|
|
45
|
+
</Tooltip>;
|
|
46
|
+
|
|
47
|
+
return <>
|
|
48
|
+
{editorButton}
|
|
49
|
+
</>
|
|
50
|
+
|
|
51
|
+
}
|
|
@@ -49,7 +49,7 @@ export function HomePageEditorCollectionAction({
|
|
|
49
49
|
<div>
|
|
50
50
|
{permissions.deleteCollections &&
|
|
51
51
|
<Menu
|
|
52
|
-
trigger={<IconButton>
|
|
52
|
+
trigger={<IconButton size={"small"}>
|
|
53
53
|
<MoreVertIcon size={"small"}/>
|
|
54
54
|
</IconButton>}
|
|
55
55
|
>
|
|
@@ -70,6 +70,7 @@ export function HomePageEditorCollectionAction({
|
|
|
70
70
|
|
|
71
71
|
{permissions.editCollections &&
|
|
72
72
|
<IconButton
|
|
73
|
+
size={"small"}
|
|
73
74
|
onClick={(event) => {
|
|
74
75
|
onEditCollectionClicked();
|
|
75
76
|
}}>
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import React, { useEffect, useState } from "react";
|
|
2
2
|
import { EntityCollection, FieldCaption, IconForView, SearchIconsView, singular, toSnakeCase, } from "@firecms/core";
|
|
3
3
|
import {
|
|
4
|
-
Autocomplete,
|
|
5
|
-
AutocompleteItem,
|
|
6
4
|
BooleanSwitchWithLabel,
|
|
7
5
|
Chip,
|
|
8
6
|
CloseIcon,
|
|
@@ -163,7 +161,7 @@ export function CollectionDetailsForm({
|
|
|
163
161
|
</FieldCaption>
|
|
164
162
|
</div>
|
|
165
163
|
|
|
166
|
-
<div className={cls("col-span-12 "
|
|
164
|
+
<div className={cls("col-span-12 ")}>
|
|
167
165
|
<Field name={"path"}
|
|
168
166
|
as={DebouncedTextField}
|
|
169
167
|
label={"Path"}
|
|
@@ -179,45 +177,65 @@ export function CollectionDetailsForm({
|
|
|
179
177
|
|
|
180
178
|
</div>
|
|
181
179
|
|
|
182
|
-
{!isSubcollection && <div className={"col-span-12 sm:col-span-4 relative"}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
180
|
+
{/*{!isSubcollection && <div className={"col-span-12 sm:col-span-4 relative"}>*/}
|
|
181
|
+
|
|
182
|
+
{/* <TextField error={showErrors && Boolean(errors.group)}*/}
|
|
183
|
+
{/* disabled={isSubmitting}*/}
|
|
184
|
+
{/* value={values.group ?? ""}*/}
|
|
185
|
+
{/* autoComplete="off"*/}
|
|
186
|
+
{/* onChange={(event) => setFieldValue("group", event.target.value)}*/}
|
|
187
|
+
{/* name={"group"}*/}
|
|
188
|
+
{/* inputRef={groupRef}*/}
|
|
189
|
+
{/* label="Group"/>*/}
|
|
190
|
+
{/* <Autocomplete*/}
|
|
191
|
+
{/* open={autoCompleteOpen && (groupOptions ?? []).length > 0}*/}
|
|
192
|
+
{/* setOpen={setAutoCompleteOpen}>*/}
|
|
193
|
+
{/* {groupOptions?.map((group, index) => {*/}
|
|
194
|
+
{/* return <AutocompleteItem*/}
|
|
195
|
+
{/* key={index + "_" + group}*/}
|
|
196
|
+
{/* className={"pr-6 pl-14"}*/}
|
|
197
|
+
{/* onClick={() => {*/}
|
|
198
|
+
{/* setAutoCompleteOpen(false);*/}
|
|
199
|
+
{/* setFieldValue("group", group ?? null);*/}
|
|
200
|
+
{/* }}*/}
|
|
201
|
+
{/* >*/}
|
|
202
|
+
{/* <div className={"flex-grow"}>*/}
|
|
203
|
+
{/* {group}*/}
|
|
204
|
+
{/* </div>*/}
|
|
205
|
+
{/* </AutocompleteItem>;*/}
|
|
206
|
+
{/* })}*/}
|
|
207
|
+
{/* </Autocomplete>*/}
|
|
208
|
+
{/* <FieldCaption>*/}
|
|
209
|
+
{/* {showErrors && Boolean(errors.group) ? errors.group : "Group in the home page"}*/}
|
|
210
|
+
{/* </FieldCaption>*/}
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
{/*</div>}*/}
|
|
215
214
|
|
|
216
215
|
<LayoutModeSwitch
|
|
217
216
|
className={"col-span-12"}
|
|
218
217
|
value={values.openEntityMode ?? "side_panel"}
|
|
219
218
|
onChange={(value) => setFieldValue("openEntityMode", value)}/>
|
|
220
219
|
|
|
220
|
+
<div className={"col-span-12"}>
|
|
221
|
+
<BooleanSwitchWithLabel
|
|
222
|
+
position={"start"}
|
|
223
|
+
size={"large"}
|
|
224
|
+
allowIndeterminate={true}
|
|
225
|
+
label={values.history === null || values.history === undefined ? "Document history revisions enabled if enabled globally" : (
|
|
226
|
+
values.history ? "Document history revisions ENABLED" : "Document history revisions NOT enabled"
|
|
227
|
+
)}
|
|
228
|
+
onValueChange={(v) => setFieldValue("history", v)}
|
|
229
|
+
value={values.history === undefined ? null : values.history}
|
|
230
|
+
/>
|
|
231
|
+
<FieldCaption>
|
|
232
|
+
When enabled, each document in this collection will have a history of changes.
|
|
233
|
+
This is useful for auditing purposes. The data is stored in a subcollection of the document
|
|
234
|
+
in your database, called <b>__history</b>.
|
|
235
|
+
</FieldCaption>
|
|
236
|
+
</div>
|
|
237
|
+
|
|
238
|
+
|
|
221
239
|
<div className={"col-span-12 mt-8"}>
|
|
222
240
|
<ExpandablePanel
|
|
223
241
|
expanded={advancedPanelExpanded}
|
|
@@ -324,6 +342,20 @@ export function CollectionDetailsForm({
|
|
|
324
342
|
))}
|
|
325
343
|
</Select>
|
|
326
344
|
</div>
|
|
345
|
+
|
|
346
|
+
<div className={"col-span-12"}>
|
|
347
|
+
<BooleanSwitchWithLabel
|
|
348
|
+
position={"start"}
|
|
349
|
+
size={"large"}
|
|
350
|
+
label={values.includeJsonView === undefined || values.includeJsonView ? "Include JSON view" : "Do not include JSON view"}
|
|
351
|
+
onValueChange={(v) => setFieldValue("includeJsonView", v)}
|
|
352
|
+
value={values.includeJsonView === undefined ? true : values.includeJsonView}
|
|
353
|
+
/>
|
|
354
|
+
<FieldCaption>
|
|
355
|
+
Include the JSON representation of the document.
|
|
356
|
+
</FieldCaption>
|
|
357
|
+
</div>
|
|
358
|
+
|
|
327
359
|
<div className={"col-span-12"}>
|
|
328
360
|
<Select
|
|
329
361
|
name="customId"
|
|
@@ -408,7 +440,7 @@ export function CollectionDetailsForm({
|
|
|
408
440
|
fullWidth
|
|
409
441
|
>
|
|
410
442
|
<div className={"p-4 overflow-auto min-h-[200px]"}>
|
|
411
|
-
<SearchIconsView selectedIcon={values.icon}
|
|
443
|
+
<SearchIconsView selectedIcon={typeof values.icon === "string" ? values.icon : undefined}
|
|
412
444
|
onIconSelected={(icon: string) => {
|
|
413
445
|
setIconDialogOpen(false);
|
|
414
446
|
setFieldValue("icon", icon);
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
isPropertyBuilder,
|
|
10
10
|
MapProperty,
|
|
11
11
|
mergeDeep,
|
|
12
|
+
NavigationResult,
|
|
12
13
|
Properties,
|
|
13
14
|
PropertiesOrBuilders,
|
|
14
15
|
Property,
|
|
@@ -17,7 +18,6 @@ import {
|
|
|
17
18
|
randomString,
|
|
18
19
|
removeInitialAndTrailingSlashes,
|
|
19
20
|
removeUndefined,
|
|
20
|
-
TopNavigationResult,
|
|
21
21
|
useAuthController,
|
|
22
22
|
useCustomizationController,
|
|
23
23
|
useNavigationController,
|
|
@@ -57,6 +57,7 @@ import { cleanPropertiesFromImport } from "./import/clean_import_data";
|
|
|
57
57
|
import { PersistedCollection } from "../../types/persisted_collection";
|
|
58
58
|
import { Formex, FormexController, useCreateFormex } from "@firecms/formex";
|
|
59
59
|
import { getFullIdPath } from "./util";
|
|
60
|
+
import { EntityActionsEditTab } from "./EntityActionsEditTab";
|
|
60
61
|
|
|
61
62
|
export interface CollectionEditorDialogProps {
|
|
62
63
|
open: boolean;
|
|
@@ -140,7 +141,8 @@ type EditorView = "welcome"
|
|
|
140
141
|
| "properties"
|
|
141
142
|
| "loading"
|
|
142
143
|
| "extra_view"
|
|
143
|
-
| "subcollections"
|
|
144
|
+
| "subcollections"
|
|
145
|
+
| "custom_actions";
|
|
144
146
|
|
|
145
147
|
export function CollectionEditor(props: CollectionEditorDialogProps & {
|
|
146
148
|
handleCancel: () => void,
|
|
@@ -184,7 +186,7 @@ export function CollectionEditor(props: CollectionEditorDialogProps & {
|
|
|
184
186
|
|
|
185
187
|
const {
|
|
186
188
|
groups
|
|
187
|
-
}:
|
|
189
|
+
}: NavigationResult = topLevelNavigation;
|
|
188
190
|
|
|
189
191
|
const initialCollection = collection
|
|
190
192
|
? {
|
|
@@ -325,10 +327,10 @@ function CollectionEditorInternal<M extends Record<string, any>>({
|
|
|
325
327
|
|
|
326
328
|
};
|
|
327
329
|
|
|
328
|
-
const doCollectionInference = (collection: PersistedCollection<any>) => {
|
|
330
|
+
const doCollectionInference = collectionInference ? (collection: PersistedCollection<any>) => {
|
|
329
331
|
if (!collectionInference) return undefined;
|
|
330
332
|
return collectionInference?.(collection.path, collection.collectionGroup ?? false, parentPaths ?? []);
|
|
331
|
-
};
|
|
333
|
+
} : undefined;
|
|
332
334
|
|
|
333
335
|
const inferCollectionFromData = async (newCollection: PersistedCollection<M>) => {
|
|
334
336
|
|
|
@@ -569,6 +571,9 @@ function CollectionEditorInternal<M extends Record<string, any>>({
|
|
|
569
571
|
<Tab value={"subcollections"}>
|
|
570
572
|
Additional views
|
|
571
573
|
</Tab>
|
|
574
|
+
<Tab value={"custom_actions"}>
|
|
575
|
+
Custom actions
|
|
576
|
+
</Tab>
|
|
572
577
|
</Tabs>}
|
|
573
578
|
|
|
574
579
|
<form noValidate
|
|
@@ -645,6 +650,9 @@ function CollectionEditorInternal<M extends Record<string, any>>({
|
|
|
645
650
|
</div>}
|
|
646
651
|
</CollectionDetailsForm>}
|
|
647
652
|
|
|
653
|
+
{currentView === "custom_actions" && collection &&
|
|
654
|
+
<EntityActionsEditTab collection={collection}/>}
|
|
655
|
+
|
|
648
656
|
{currentView === "subcollections" && collection &&
|
|
649
657
|
<SubcollectionsEditTab
|
|
650
658
|
parentCollection={parentCollection}
|
|
@@ -687,6 +695,7 @@ function CollectionEditorInternal<M extends Record<string, any>>({
|
|
|
687
695
|
{isNewCollection && includeTemplates && currentView === "import_data_mapping" &&
|
|
688
696
|
<Button variant={"text"}
|
|
689
697
|
type="button"
|
|
698
|
+
color={"primary"}
|
|
690
699
|
onClick={() => {
|
|
691
700
|
importConfig.setInUse(false);
|
|
692
701
|
return setCurrentView("welcome");
|
|
@@ -698,6 +707,7 @@ function CollectionEditorInternal<M extends Record<string, any>>({
|
|
|
698
707
|
{isNewCollection && includeTemplates && currentView === "import_data_preview" &&
|
|
699
708
|
<Button variant={"text"}
|
|
700
709
|
type="button"
|
|
710
|
+
color={"primary"}
|
|
701
711
|
onClick={() => {
|
|
702
712
|
setCurrentView("import_data_mapping");
|
|
703
713
|
}}>
|
|
@@ -707,6 +717,7 @@ function CollectionEditorInternal<M extends Record<string, any>>({
|
|
|
707
717
|
|
|
708
718
|
{isNewCollection && includeTemplates && currentView === "details" &&
|
|
709
719
|
<Button variant={"text"}
|
|
720
|
+
color={"primary"}
|
|
710
721
|
type="button"
|
|
711
722
|
onClick={() => setCurrentView("welcome")}>
|
|
712
723
|
<ArrowBackIcon/>
|
|
@@ -715,12 +726,14 @@ function CollectionEditorInternal<M extends Record<string, any>>({
|
|
|
715
726
|
|
|
716
727
|
{isNewCollection && currentView === "properties" && <Button variant={"text"}
|
|
717
728
|
type="button"
|
|
729
|
+
color={"primary"}
|
|
718
730
|
onClick={() => setCurrentView("details")}>
|
|
719
731
|
<ArrowBackIcon/>
|
|
720
732
|
Back
|
|
721
733
|
</Button>}
|
|
722
734
|
|
|
723
735
|
<Button variant={"text"}
|
|
736
|
+
color={"primary"}
|
|
724
737
|
onClick={() => {
|
|
725
738
|
handleCancel();
|
|
726
739
|
}}>
|