@firecms/collection_editor 3.0.0-canary.15 → 3.0.0-canary.151
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 +4921 -3536
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +6846 -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/types/config_permissions.d.ts +2 -2
- package/dist/types/persisted_collection.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/PropertyEditView.d.ts +8 -0
- 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/import/CollectionEditorImportMapping.d.ts +7 -0
- 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 +17 -11
- package/dist/utils/collections.d.ts +6 -0
- package/package.json +21 -35
- 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/types/config_permissions.ts +1 -1
- package/src/types/persisted_collection.ts +2 -3
- package/src/ui/CollectionViewHeaderAction.tsx +10 -5
- 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 +11 -6
- package/src/ui/collection_editor/CollectionDetailsForm.tsx +70 -9
- package/src/ui/collection_editor/CollectionEditorDialog.tsx +61 -34
- package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +8 -7
- package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +37 -34
- package/src/ui/collection_editor/EnumForm.tsx +5 -2
- package/src/ui/collection_editor/GetCodeDialog.tsx +52 -21
- package/src/ui/collection_editor/PropertyEditView.tsx +255 -80
- package/src/ui/collection_editor/PropertyFieldPreview.tsx +4 -7
- 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 +40 -9
- package/src/ui/collection_editor/properties/BlockPropertyField.tsx +32 -20
- 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 +7 -6
- 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 +32 -17
- package/src/ui/collection_editor/properties/StringPropertyField.tsx +1 -10
- package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +2 -2
- package/src/ui/collection_editor/templates/pages_template.ts +1 -6
- package/src/useCollectionEditorPlugin.tsx +41 -31
- package/src/utils/collections.ts +30 -0
- package/dist/ui/RootCollectionSuggestions.d.ts +0 -3
- package/dist/ui/collection_editor/PropertySelectItem.d.ts +0 -8
- package/src/ui/RootCollectionSuggestions.tsx +0 -63
- package/src/ui/collection_editor/PropertySelectItem.tsx +0 -32
|
@@ -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,6 +1,6 @@
|
|
|
1
1
|
import { EntityCollection } from "@firecms/core";
|
|
2
2
|
|
|
3
|
-
export type CollectionEditorPermissionsBuilder<
|
|
3
|
+
export type CollectionEditorPermissionsBuilder<USER = any, EC extends EntityCollection = EntityCollection> = (params: { user: USER | null, collection?: EC }) => CollectionEditorPermissions;
|
|
4
4
|
|
|
5
5
|
export type CollectionEditorPermissions = {
|
|
6
6
|
/**
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { EntityCollection, User } from "@firecms/core";
|
|
2
2
|
|
|
3
|
-
export type PersistedCollection<M extends Record<string, any> = any,
|
|
4
|
-
= Omit<EntityCollection<M,
|
|
5
|
-
// properties: Properties<M>;
|
|
3
|
+
export type PersistedCollection<M extends Record<string, any> = any, USER extends User = User>
|
|
4
|
+
= Omit<EntityCollection<M, USER>, "subcollections"> & {
|
|
6
5
|
ownerId?: string;
|
|
7
6
|
subcollections?: PersistedCollection<any, any>[];
|
|
8
7
|
editable?: boolean;
|
|
@@ -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,21 +19,25 @@ 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
|
-
className={onHover ? "bg-white dark:bg-
|
|
32
|
+
className={onHover ? "bg-white dark:bg-surface-950" : "hidden"}
|
|
29
33
|
onClick={() => {
|
|
30
34
|
collectionEditorController.editProperty({
|
|
31
35
|
propertyKey,
|
|
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"}>
|
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
CollectionActionsProps,
|
|
5
|
-
mergeDeep,
|
|
6
|
-
useAuthController,
|
|
7
|
-
useNavigationController,
|
|
8
|
-
useSnackbarController
|
|
9
|
-
} from "@firecms/core";
|
|
10
|
-
import { Button, IconButton, SaveIcon, SettingsIcon, Tooltip, UndoIcon, } from "@firecms/ui";
|
|
1
|
+
import { CollectionActionsProps, useAuthController, useNavigationController } from "@firecms/core";
|
|
2
|
+
import { IconButton, SettingsIcon, Tooltip, } from "@firecms/ui";
|
|
11
3
|
|
|
12
4
|
import { useCollectionEditorController } from "../useCollectionEditorController";
|
|
13
|
-
import { useCollectionsConfigController } from "../useCollectionsConfigController";
|
|
14
5
|
import { PersistedCollection } from "../types/persisted_collection";
|
|
15
6
|
|
|
16
7
|
export function EditorCollectionAction({
|
|
@@ -23,8 +14,6 @@ export function EditorCollectionAction({
|
|
|
23
14
|
const authController = useAuthController();
|
|
24
15
|
const navigationController = useNavigationController();
|
|
25
16
|
const collectionEditorController = useCollectionEditorController();
|
|
26
|
-
const configController = useCollectionsConfigController();
|
|
27
|
-
const snackbarController = useSnackbarController();
|
|
28
17
|
|
|
29
18
|
const parentCollection = navigationController.getCollectionFromIds(parentCollectionIds);
|
|
30
19
|
|
|
@@ -35,68 +24,26 @@ export function EditorCollectionAction({
|
|
|
35
24
|
}).editCollections
|
|
36
25
|
: true;
|
|
37
26
|
|
|
38
|
-
let saveDefaultFilterButton = null;
|
|
39
|
-
if (!equal(getObjectOrNull(tableController.filterValues), getObjectOrNull(collection.initialFilter)) ||
|
|
40
|
-
!equal(getObjectOrNull(tableController.sortBy), getObjectOrNull(collection.initialSort))) {
|
|
41
|
-
saveDefaultFilterButton = <>
|
|
42
|
-
{(collection.initialFilter || collection.initialSort) && <Tooltip
|
|
43
|
-
title={"Reset to default filter and sort"}>
|
|
44
|
-
<Button
|
|
45
|
-
color={"primary"}
|
|
46
|
-
size={"small"}
|
|
47
|
-
variant={"text"}
|
|
48
|
-
onClick={() => {
|
|
49
|
-
tableController.clearFilter?.();
|
|
50
|
-
if (collection?.initialFilter)
|
|
51
|
-
tableController.setFilterValues?.(collection?.initialFilter);
|
|
52
|
-
if (collection?.initialSort)
|
|
53
|
-
tableController.setSortBy?.(collection?.initialSort);
|
|
54
|
-
}}>
|
|
55
|
-
<UndoIcon/>
|
|
56
|
-
</Button>
|
|
57
|
-
</Tooltip>}
|
|
58
|
-
|
|
59
|
-
<Tooltip
|
|
60
|
-
title={tableController.sortBy || tableController.filterValues ? "Save default filter and sort" : "Clear default filter and sort"}>
|
|
61
|
-
<Button
|
|
62
|
-
color={"primary"}
|
|
63
|
-
size={"small"}
|
|
64
|
-
variant={"outlined"}
|
|
65
|
-
onClick={() => configController
|
|
66
|
-
?.saveCollection({
|
|
67
|
-
id: collection.id,
|
|
68
|
-
parentCollectionIds,
|
|
69
|
-
collectionData: mergeDeep(collection as PersistedCollection,
|
|
70
|
-
{
|
|
71
|
-
initialFilter: tableController.filterValues ?? null,
|
|
72
|
-
initialSort: tableController.sortBy ?? null
|
|
73
|
-
})
|
|
74
|
-
}).then(() => {
|
|
75
|
-
snackbarController.open({
|
|
76
|
-
type: "success",
|
|
77
|
-
message: "Default config saved"
|
|
78
|
-
});
|
|
79
|
-
})}>
|
|
80
|
-
<SaveIcon/>
|
|
81
|
-
</Button>
|
|
82
|
-
</Tooltip>
|
|
83
|
-
</>;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
27
|
const editorButton = <Tooltip
|
|
28
|
+
asChild={true}
|
|
87
29
|
title={canEditCollection ? "Edit collection" : "You don't have permissions to edit this collection"}>
|
|
88
30
|
<IconButton
|
|
89
31
|
color={"primary"}
|
|
90
32
|
disabled={!canEditCollection}
|
|
91
33
|
onClick={canEditCollection
|
|
92
|
-
? () => collectionEditorController?.editCollection({
|
|
34
|
+
? () => collectionEditorController?.editCollection({
|
|
35
|
+
id: collection.id,
|
|
36
|
+
fullPath,
|
|
37
|
+
parentCollectionIds,
|
|
38
|
+
parentCollection: parentCollection as PersistedCollection,
|
|
39
|
+
existingEntities: tableController?.data ?? []
|
|
40
|
+
})
|
|
93
41
|
: undefined}>
|
|
94
42
|
<SettingsIcon/>
|
|
95
43
|
</IconButton>
|
|
96
44
|
</Tooltip>;
|
|
97
45
|
|
|
98
46
|
return <>
|
|
99
|
-
{canEditCollection && saveDefaultFilterButton}
|
|
100
47
|
{editorButton}
|
|
101
48
|
</>
|
|
102
49
|
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import equal from "react-fast-compare"
|
|
2
|
+
|
|
3
|
+
import { CollectionActionsProps, mergeDeep, useAuthController, useSnackbarController } from "@firecms/core";
|
|
4
|
+
import { Button, SaveIcon, Tooltip, UndoIcon, } from "@firecms/ui";
|
|
5
|
+
|
|
6
|
+
import { useCollectionEditorController } from "../useCollectionEditorController";
|
|
7
|
+
import { useCollectionsConfigController } from "../useCollectionsConfigController";
|
|
8
|
+
import { PersistedCollection } from "../types/persisted_collection";
|
|
9
|
+
|
|
10
|
+
export function EditorCollectionActionStart({
|
|
11
|
+
path: fullPath,
|
|
12
|
+
parentCollectionIds,
|
|
13
|
+
collection,
|
|
14
|
+
tableController
|
|
15
|
+
}: CollectionActionsProps) {
|
|
16
|
+
|
|
17
|
+
const authController = useAuthController();
|
|
18
|
+
const collectionEditorController = useCollectionEditorController();
|
|
19
|
+
const configController = useCollectionsConfigController();
|
|
20
|
+
const snackbarController = useSnackbarController();
|
|
21
|
+
|
|
22
|
+
const canEditCollection = collectionEditorController.configPermissions
|
|
23
|
+
? collectionEditorController.configPermissions({
|
|
24
|
+
user: authController.user,
|
|
25
|
+
collection
|
|
26
|
+
}).editCollections
|
|
27
|
+
: true;
|
|
28
|
+
|
|
29
|
+
let saveDefaultFilterButton = null;
|
|
30
|
+
if (!equal(getObjectOrNull(tableController.filterValues), getObjectOrNull(collection.initialFilter)) ||
|
|
31
|
+
!equal(getObjectOrNull(tableController.sortBy), getObjectOrNull(collection.initialSort))) {
|
|
32
|
+
saveDefaultFilterButton = <>
|
|
33
|
+
<Tooltip
|
|
34
|
+
asChild={true}
|
|
35
|
+
title={tableController.sortBy || tableController.filterValues ? "Save default filter and sort" : "Clear default filter and sort"}>
|
|
36
|
+
<Button
|
|
37
|
+
color={"primary"}
|
|
38
|
+
size={"small"}
|
|
39
|
+
variant={"outlined"}
|
|
40
|
+
onClick={() => configController
|
|
41
|
+
?.saveCollection({
|
|
42
|
+
id: collection.id,
|
|
43
|
+
parentCollectionIds,
|
|
44
|
+
collectionData: mergeDeep(collection as PersistedCollection,
|
|
45
|
+
{
|
|
46
|
+
initialFilter: tableController.filterValues ?? null,
|
|
47
|
+
initialSort: tableController.sortBy ?? null
|
|
48
|
+
})
|
|
49
|
+
}).then(() => {
|
|
50
|
+
snackbarController.open({
|
|
51
|
+
type: "success",
|
|
52
|
+
message: "Default config saved"
|
|
53
|
+
});
|
|
54
|
+
})}>
|
|
55
|
+
<SaveIcon/>
|
|
56
|
+
</Button>
|
|
57
|
+
</Tooltip>
|
|
58
|
+
|
|
59
|
+
{(collection.initialFilter || collection.initialSort) && <Tooltip
|
|
60
|
+
title={"Reset to default filter and sort"}>
|
|
61
|
+
<Button
|
|
62
|
+
color={"primary"}
|
|
63
|
+
size={"small"}
|
|
64
|
+
variant={"text"}
|
|
65
|
+
onClick={() => {
|
|
66
|
+
tableController.clearFilter?.();
|
|
67
|
+
if (collection?.initialFilter)
|
|
68
|
+
tableController.setFilterValues?.(collection?.initialFilter);
|
|
69
|
+
if (collection?.initialSort)
|
|
70
|
+
tableController.setSortBy?.(collection?.initialSort);
|
|
71
|
+
}}>
|
|
72
|
+
<UndoIcon/>
|
|
73
|
+
</Button>
|
|
74
|
+
</Tooltip>}
|
|
75
|
+
</>;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return <>
|
|
79
|
+
{canEditCollection && saveDefaultFilterButton}
|
|
80
|
+
</>
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function getObjectOrNull(o?: object): object | null {
|
|
85
|
+
if (o && Object.keys(o).length === 0)
|
|
86
|
+
return o
|
|
87
|
+
return o ?? null;
|
|
88
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
ConfirmationDialog,
|
|
3
3
|
PluginHomePageActionsProps,
|
|
4
4
|
useAuthController,
|
|
5
5
|
useSnackbarController
|
|
6
6
|
} from "@firecms/core";
|
|
7
7
|
import { DeleteIcon, IconButton, Menu, MenuItem, MoreVertIcon, SettingsIcon, } from "@firecms/ui";
|
|
8
8
|
import { useCollectionEditorController } from "../useCollectionEditorController";
|
|
9
|
-
import {
|
|
9
|
+
import { useState } from "react";
|
|
10
10
|
import { useCollectionsConfigController } from "../useCollectionsConfigController";
|
|
11
11
|
|
|
12
12
|
export function HomePageEditorCollectionAction({
|
|
@@ -24,13 +24,16 @@ export function HomePageEditorCollectionAction({
|
|
|
24
24
|
collection
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
-
const onEditCollectionClicked =
|
|
28
|
-
collectionEditorController?.editCollection({
|
|
29
|
-
|
|
27
|
+
const onEditCollectionClicked = () => {
|
|
28
|
+
collectionEditorController?.editCollection({
|
|
29
|
+
id: collection.id,
|
|
30
|
+
parentCollectionIds: []
|
|
31
|
+
});
|
|
32
|
+
};
|
|
30
33
|
|
|
31
34
|
const [deleteRequested, setDeleteRequested] = useState(false);
|
|
32
35
|
|
|
33
|
-
const deleteCollection =
|
|
36
|
+
const deleteCollection = () => {
|
|
34
37
|
configController?.deleteCollection({ id: collection.id }).then(() => {
|
|
35
38
|
setDeleteRequested(false);
|
|
36
39
|
snackbarController.open({
|
|
@@ -38,7 +41,7 @@ export function HomePageEditorCollectionAction({
|
|
|
38
41
|
type: "success"
|
|
39
42
|
});
|
|
40
43
|
});
|
|
41
|
-
}
|
|
44
|
+
};
|
|
42
45
|
|
|
43
46
|
return <>
|
|
44
47
|
|
|
@@ -49,11 +52,13 @@ export function HomePageEditorCollectionAction({
|
|
|
49
52
|
<MoreVertIcon size={"small"}/>
|
|
50
53
|
</IconButton>}
|
|
51
54
|
>
|
|
52
|
-
<MenuItem
|
|
53
|
-
|
|
54
|
-
event
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
<MenuItem
|
|
56
|
+
dense={true}
|
|
57
|
+
onClick={(event) => {
|
|
58
|
+
event.preventDefault();
|
|
59
|
+
event.stopPropagation();
|
|
60
|
+
setDeleteRequested(true);
|
|
61
|
+
}}>
|
|
57
62
|
<DeleteIcon/>
|
|
58
63
|
Delete
|
|
59
64
|
</MenuItem>
|
|
@@ -71,7 +76,7 @@ export function HomePageEditorCollectionAction({
|
|
|
71
76
|
</IconButton>}
|
|
72
77
|
</div>
|
|
73
78
|
|
|
74
|
-
<
|
|
79
|
+
<ConfirmationDialog
|
|
75
80
|
open={deleteRequested}
|
|
76
81
|
onAccept={deleteCollection}
|
|
77
82
|
onCancel={() => setDeleteRequested(false)}
|
|
@@ -3,14 +3,16 @@ import { useCollectionEditorController } from "../useCollectionEditorController"
|
|
|
3
3
|
|
|
4
4
|
export function NewCollectionButton() {
|
|
5
5
|
const collectionEditorController = useCollectionEditorController();
|
|
6
|
-
return <
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
return <div className={"bg-surface-50 dark:bg-surface-900 min-w-fit rounded"}>
|
|
7
|
+
<Button className={"min-w-fit"}
|
|
8
|
+
variant={"outlined"}
|
|
9
|
+
onClick={() => collectionEditorController.createCollection({
|
|
10
|
+
parentCollectionIds: [],
|
|
11
|
+
redirect: true,
|
|
12
|
+
sourceClick: "new_collection_button"
|
|
13
|
+
})}>
|
|
14
|
+
<AddIcon/>
|
|
15
|
+
New collection
|
|
16
|
+
</Button>
|
|
17
|
+
</div>
|
|
16
18
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PluginHomePageAdditionalCardsProps, useAuthController } from "@firecms/core";
|
|
2
|
-
import { AddIcon, Card,
|
|
2
|
+
import { AddIcon, Card, cls, Typography } from "@firecms/ui";
|
|
3
3
|
import { useCollectionEditorController } from "../useCollectionEditorController";
|
|
4
4
|
|
|
5
5
|
export function NewCollectionCard({
|
|
@@ -20,7 +20,7 @@ export function NewCollectionCard({
|
|
|
20
20
|
: true;
|
|
21
21
|
|
|
22
22
|
return (
|
|
23
|
-
<Card className={
|
|
23
|
+
<Card className={cls("h-full p-4 min-h-[124px]")}
|
|
24
24
|
onClick={collectionEditorController && canCreateCollections
|
|
25
25
|
? () => collectionEditorController.createCollection({
|
|
26
26
|
initialValues: group ? { group } : undefined,
|
|
@@ -31,7 +31,7 @@ export function NewCollectionCard({
|
|
|
31
31
|
: undefined}>
|
|
32
32
|
|
|
33
33
|
<div
|
|
34
|
-
className="flex
|
|
34
|
+
className="flex items-center justify-center h-full w-full flex-grow flex-col">
|
|
35
35
|
<AddIcon color="primary" size={"large"}/>
|
|
36
36
|
<Typography color="primary"
|
|
37
37
|
variant={"caption"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getDefaultPropertiesOrder, useAuthController } from "@firecms/core";
|
|
1
|
+
import { EntityTableController, getDefaultPropertiesOrder, useAuthController } from "@firecms/core";
|
|
2
2
|
import { AddIcon, Tooltip } from "@firecms/ui";
|
|
3
3
|
import { useCollectionEditorController } from "../useCollectionEditorController";
|
|
4
4
|
import { PersistedCollection } from "../types/persisted_collection";
|
|
@@ -6,11 +6,13 @@ import { PersistedCollection } from "../types/persisted_collection";
|
|
|
6
6
|
export function PropertyAddColumnComponent({
|
|
7
7
|
fullPath,
|
|
8
8
|
parentCollectionIds,
|
|
9
|
-
collection
|
|
9
|
+
collection,
|
|
10
|
+
tableController
|
|
10
11
|
}: {
|
|
11
12
|
fullPath: string,
|
|
12
13
|
parentCollectionIds: string[],
|
|
13
14
|
collection: PersistedCollection;
|
|
15
|
+
tableController: EntityTableController;
|
|
14
16
|
}) {
|
|
15
17
|
|
|
16
18
|
const authController = useAuthController();
|
|
@@ -23,16 +25,19 @@ export function PropertyAddColumnComponent({
|
|
|
23
25
|
: true;
|
|
24
26
|
|
|
25
27
|
return (
|
|
26
|
-
<Tooltip
|
|
28
|
+
<Tooltip
|
|
29
|
+
asChild={true}
|
|
30
|
+
title={canEditCollection ? "Add new property" : "You don't have permission to add new properties"}>
|
|
27
31
|
<div
|
|
28
|
-
className={"p-0.5 w-20 h-full flex items-center justify-center cursor-pointer bg-
|
|
29
|
-
// className={onHover ? "bg-white dark:bg-
|
|
32
|
+
className={"p-0.5 w-20 h-full flex items-center justify-center cursor-pointer bg-surface-100 bg-opacity-40 hover:bg-surface-100 dark:bg-surface-950 dark:bg-opacity-40 dark:hover:bg-surface-950"}
|
|
33
|
+
// className={onHover ? "bg-white dark:bg-surface-950" : undefined}
|
|
30
34
|
onClick={() => {
|
|
31
35
|
collectionEditorController.editProperty({
|
|
32
36
|
editedCollectionId: collection.id,
|
|
33
37
|
parentCollectionIds,
|
|
34
38
|
currentPropertiesOrder: getDefaultPropertiesOrder(collection),
|
|
35
|
-
collection
|
|
39
|
+
collection,
|
|
40
|
+
existingEntities: tableController.data
|
|
36
41
|
});
|
|
37
42
|
}}>
|
|
38
43
|
<AddIcon color={"inherit"}/>
|
|
@@ -5,7 +5,8 @@ import {
|
|
|
5
5
|
AutocompleteItem,
|
|
6
6
|
BooleanSwitchWithLabel,
|
|
7
7
|
Chip,
|
|
8
|
-
|
|
8
|
+
ClearIcon,
|
|
9
|
+
cls,
|
|
9
10
|
Container,
|
|
10
11
|
DebouncedTextField,
|
|
11
12
|
Dialog,
|
|
@@ -21,6 +22,7 @@ import {
|
|
|
21
22
|
} from "@firecms/ui";
|
|
22
23
|
|
|
23
24
|
import { Field, getIn, useFormex } from "@firecms/formex";
|
|
25
|
+
import { useCollectionEditorController } from "../../useCollectionEditorController";
|
|
24
26
|
|
|
25
27
|
export function CollectionDetailsForm({
|
|
26
28
|
isNewCollection,
|
|
@@ -51,9 +53,15 @@ export function CollectionDetailsForm({
|
|
|
51
53
|
submitCount
|
|
52
54
|
} = useFormex<EntityCollection>();
|
|
53
55
|
|
|
56
|
+
const collectionEditor = useCollectionEditorController();
|
|
57
|
+
|
|
54
58
|
const [iconDialogOpen, setIconDialogOpen] = useState(false);
|
|
55
59
|
const [advancedPanelExpanded, setAdvancedPanelExpanded] = useState(false);
|
|
56
60
|
|
|
61
|
+
const updateDatabaseId = (databaseId: string) => {
|
|
62
|
+
setFieldValue("databaseId", databaseId ?? undefined);
|
|
63
|
+
}
|
|
64
|
+
|
|
57
65
|
const updateName = (name: string) => {
|
|
58
66
|
setFieldValue("name", name);
|
|
59
67
|
|
|
@@ -80,6 +88,8 @@ export function CollectionDetailsForm({
|
|
|
80
88
|
}
|
|
81
89
|
}, [errors.id]);
|
|
82
90
|
|
|
91
|
+
const DatabaseField = collectionEditor.components?.DatabaseField ?? DefaultDatabaseField;
|
|
92
|
+
|
|
83
93
|
const collectionIcon = <IconForView collectionOrView={values}/>;
|
|
84
94
|
|
|
85
95
|
const groupOptions = groups?.filter((group) => !reservedGroups?.includes(group));
|
|
@@ -112,11 +122,15 @@ export function CollectionDetailsForm({
|
|
|
112
122
|
|
|
113
123
|
<div>
|
|
114
124
|
<div
|
|
115
|
-
className="flex flex-row py-2 pt-3 items-center">
|
|
125
|
+
className="flex flex-row gap-2 py-2 pt-3 items-center">
|
|
116
126
|
<Typography variant={!isNewCollection ? "h5" : "h4"} className={"flex-grow"}>
|
|
117
127
|
{isNewCollection ? "New collection" : `${values?.name} collection`}
|
|
118
128
|
</Typography>
|
|
119
|
-
<
|
|
129
|
+
<DatabaseField databaseId={values.databaseId}
|
|
130
|
+
onDatabaseIdUpdate={updateDatabaseId}/>
|
|
131
|
+
|
|
132
|
+
<Tooltip title={"Change icon"}
|
|
133
|
+
asChild={true}>
|
|
120
134
|
<IconButton
|
|
121
135
|
shape={"square"}
|
|
122
136
|
onClick={() => setIconDialogOpen(true)}>
|
|
@@ -139,14 +153,15 @@ export function CollectionDetailsForm({
|
|
|
139
153
|
value={values.name ?? ""}
|
|
140
154
|
onChange={(e: any) => updateName(e.target.value)}
|
|
141
155
|
label={"Name"}
|
|
156
|
+
autoFocus={true}
|
|
142
157
|
required
|
|
143
158
|
error={showErrors && Boolean(errors.name)}/>
|
|
144
159
|
<FieldCaption error={touched.name && Boolean(errors.name)}>
|
|
145
|
-
{touched.name && Boolean(errors.name) ? errors.name : "Name of
|
|
160
|
+
{touched.name && Boolean(errors.name) ? errors.name : "Name of this collection, usually a plural name (e.g. Products)"}
|
|
146
161
|
</FieldCaption>
|
|
147
162
|
</div>
|
|
148
163
|
|
|
149
|
-
<div className={
|
|
164
|
+
<div className={cls("col-span-12 ", isSubcollection ? "" : "sm:col-span-8")}>
|
|
150
165
|
<Field name={"path"}
|
|
151
166
|
as={DebouncedTextField}
|
|
152
167
|
label={"Path"}
|
|
@@ -190,7 +205,7 @@ export function CollectionDetailsForm({
|
|
|
190
205
|
})}
|
|
191
206
|
</Autocomplete>
|
|
192
207
|
<FieldCaption>
|
|
193
|
-
{showErrors && Boolean(errors.group) ? errors.group : "Group
|
|
208
|
+
{showErrors && Boolean(errors.group) ? errors.group : "Group in the home page"}
|
|
194
209
|
</FieldCaption>
|
|
195
210
|
</div>}
|
|
196
211
|
|
|
@@ -199,7 +214,7 @@ export function CollectionDetailsForm({
|
|
|
199
214
|
expanded={advancedPanelExpanded}
|
|
200
215
|
onExpandedChange={setAdvancedPanelExpanded}
|
|
201
216
|
title={
|
|
202
|
-
<div className="flex flex-row text-
|
|
217
|
+
<div className="flex flex-row text-surface-500">
|
|
203
218
|
<SettingsIcon/>
|
|
204
219
|
<Typography variant={"subtitle2"}
|
|
205
220
|
className="ml-2">
|
|
@@ -216,7 +231,7 @@ export function CollectionDetailsForm({
|
|
|
216
231
|
label={"Collection id"}
|
|
217
232
|
error={showErrors && Boolean(errors.id)}/>
|
|
218
233
|
<FieldCaption error={touched.id && Boolean(errors.id)}>
|
|
219
|
-
{touched.id && Boolean(errors.id) ? errors.id : "This id identifies this collection"}
|
|
234
|
+
{touched.id && Boolean(errors.id) ? errors.id : "This id identifies this collection. Typically the same as the path."}
|
|
220
235
|
</FieldCaption>
|
|
221
236
|
</div>
|
|
222
237
|
|
|
@@ -235,6 +250,35 @@ export function CollectionDetailsForm({
|
|
|
235
250
|
{showErrors && Boolean(errors.singularName) ? errors.singularName : "Optionally define a singular name for your entities"}
|
|
236
251
|
</FieldCaption>
|
|
237
252
|
</div>
|
|
253
|
+
<div className={"col-span-12"}>
|
|
254
|
+
<TextField
|
|
255
|
+
error={showErrors && Boolean(errors.sideDialogWidth)}
|
|
256
|
+
name={"sideDialogWidth"}
|
|
257
|
+
type={"number"}
|
|
258
|
+
aria-describedby={"sideDialogWidth-helper"}
|
|
259
|
+
onChange={(e) => {
|
|
260
|
+
setFieldTouched("sideDialogWidth", true);
|
|
261
|
+
const value = e.target.value;
|
|
262
|
+
if (!value) {
|
|
263
|
+
setFieldValue("sideDialogWidth", null);
|
|
264
|
+
} else if (!isNaN(Number(value))) {
|
|
265
|
+
setFieldValue("sideDialogWidth", Number(value));
|
|
266
|
+
}
|
|
267
|
+
}}
|
|
268
|
+
endAdornment={<IconButton
|
|
269
|
+
size={"small"}
|
|
270
|
+
onClick={() => {
|
|
271
|
+
setFieldValue("sideDialogWidth", null);
|
|
272
|
+
}}
|
|
273
|
+
disabled={!values.sideDialogWidth}>
|
|
274
|
+
<ClearIcon size={"small"}/>
|
|
275
|
+
</IconButton>}
|
|
276
|
+
value={values.sideDialogWidth ?? ""}
|
|
277
|
+
label={"Side dialog width"}/>
|
|
278
|
+
<FieldCaption error={showErrors && Boolean(errors.singularName)}>
|
|
279
|
+
{showErrors && Boolean(errors.singularName) ? errors.singularName : "Optionally define the width (in pixels) of entities side dialog. Default is 768px"}
|
|
280
|
+
</FieldCaption>
|
|
281
|
+
</div>
|
|
238
282
|
<div className={"col-span-12"}>
|
|
239
283
|
<TextField
|
|
240
284
|
error={showErrors && Boolean(errors.description)}
|
|
@@ -272,7 +316,7 @@ export function CollectionDetailsForm({
|
|
|
272
316
|
<div className={"col-span-12"}>
|
|
273
317
|
<Select
|
|
274
318
|
name="customId"
|
|
275
|
-
label="
|
|
319
|
+
label="Document IDs generation"
|
|
276
320
|
position={"item-aligned"}
|
|
277
321
|
disabled={customIdValue === "code_defined"}
|
|
278
322
|
onValueChange={(v) => {
|
|
@@ -363,3 +407,20 @@ export function CollectionDetailsForm({
|
|
|
363
407
|
</div>
|
|
364
408
|
);
|
|
365
409
|
}
|
|
410
|
+
|
|
411
|
+
function DefaultDatabaseField({
|
|
412
|
+
databaseId,
|
|
413
|
+
onDatabaseIdUpdate
|
|
414
|
+
}: { databaseId?: string, onDatabaseIdUpdate: (databaseId: string) => void }) {
|
|
415
|
+
|
|
416
|
+
return <Tooltip title={"Database ID"}
|
|
417
|
+
side={"top"}
|
|
418
|
+
align={"start"}>
|
|
419
|
+
<TextField size={"smallest"}
|
|
420
|
+
invisible={true}
|
|
421
|
+
inputClassName={"text-end"}
|
|
422
|
+
value={databaseId ?? ""}
|
|
423
|
+
onChange={(e: any) => onDatabaseIdUpdate(e.target.value)}
|
|
424
|
+
placeholder={"(default)"}></TextField>
|
|
425
|
+
</Tooltip>
|
|
426
|
+
}
|