@firecms/collection_editor 3.0.0-alpha.16 → 3.0.0-alpha.18
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/ConfigControllerProvider.d.ts +1 -1
- package/dist/components/RootCollectionSuggestions.d.ts +1 -0
- package/dist/components/collection_editor/CollectionEditorDialog.d.ts +7 -3
- package/dist/components/collection_editor/CollectionPropertiesEditorForm.d.ts +5 -3
- package/dist/components/collection_editor/EntityCustomViewsSelectDialog.d.ts +4 -0
- package/dist/components/collection_editor/PropertyEditView.d.ts +5 -4
- package/dist/components/collection_editor/PropertyFieldPreview.d.ts +4 -3
- package/dist/components/collection_editor/PropertySelectItem.d.ts +2 -2
- package/dist/components/collection_editor/PropertyTree.d.ts +6 -5
- package/dist/components/collection_editor/import/CollectionEditorImportMapping.d.ts +3 -1
- package/dist/components/collection_editor/properties/BlockPropertyField.d.ts +3 -1
- package/dist/components/collection_editor/properties/MapPropertyField.d.ts +3 -1
- package/dist/components/collection_editor/properties/RepeatPropertyField.d.ts +3 -1
- package/dist/components/collection_editor/utils/update_property_for_widget.d.ts +2 -3
- package/dist/index.d.ts +0 -1
- package/dist/index.es.js +2221 -1889
- 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 +6 -1
- package/dist/types/config_controller.d.ts +2 -2
- package/dist/types/persisted_collection.d.ts +3 -2
- package/dist/utils/entities.d.ts +3 -4
- package/dist/utils/icons.d.ts +1 -2
- package/dist/utils/join_collections.d.ts +14 -0
- package/package.json +10 -5
- package/src/ConfigControllerProvider.tsx +177 -0
- package/src/components/EditorCollectionAction.tsx +95 -0
- package/src/components/HomePageEditorCollectionAction.tsx +81 -0
- package/src/components/NewCollectionCard.tsx +45 -0
- package/src/components/RootCollectionSuggestions.tsx +53 -0
- package/src/components/collection_editor/CollectionDetailsForm.tsx +312 -0
- package/src/components/collection_editor/CollectionEditorDialog.tsx +640 -0
- package/src/components/collection_editor/CollectionEditorWelcomeView.tsx +212 -0
- package/src/components/collection_editor/CollectionPropertiesEditorForm.tsx +450 -0
- package/src/components/collection_editor/CollectionYupValidation.tsx +6 -0
- package/src/components/collection_editor/EntityCustomViewsSelectDialog.tsx +29 -0
- package/src/components/collection_editor/EnumForm.tsx +354 -0
- package/src/components/collection_editor/PropertyEditView.tsx +535 -0
- package/src/components/collection_editor/PropertyFieldPreview.tsx +205 -0
- package/src/components/collection_editor/PropertySelectItem.tsx +31 -0
- package/src/components/collection_editor/PropertyTree.tsx +228 -0
- package/src/components/collection_editor/SelectIcons.tsx +72 -0
- package/src/components/collection_editor/SubcollectionsEditTab.tsx +239 -0
- package/src/components/collection_editor/UnsavedChangesDialog.tsx +47 -0
- package/src/components/collection_editor/import/CollectionEditorImportDataPreview.tsx +37 -0
- package/src/components/collection_editor/import/CollectionEditorImportMapping.tsx +236 -0
- package/src/components/collection_editor/import/clean_import_data.ts +53 -0
- package/src/components/collection_editor/properties/BlockPropertyField.tsx +131 -0
- package/src/components/collection_editor/properties/BooleanPropertyField.tsx +36 -0
- package/src/components/collection_editor/properties/CommonPropertyFields.tsx +112 -0
- package/src/components/collection_editor/properties/DateTimePropertyField.tsx +86 -0
- package/src/components/collection_editor/properties/EnumPropertyField.tsx +116 -0
- package/src/components/collection_editor/properties/FieldHelperView.tsx +13 -0
- package/src/components/collection_editor/properties/KeyValuePropertyField.tsx +20 -0
- package/src/components/collection_editor/properties/MapPropertyField.tsx +154 -0
- package/src/components/collection_editor/properties/NumberPropertyField.tsx +38 -0
- package/src/components/collection_editor/properties/ReferencePropertyField.tsx +184 -0
- package/src/components/collection_editor/properties/RepeatPropertyField.tsx +115 -0
- package/src/components/collection_editor/properties/StoragePropertyField.tsx +194 -0
- package/src/components/collection_editor/properties/StringPropertyField.tsx +85 -0
- package/src/components/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +36 -0
- package/src/components/collection_editor/properties/validation/ArrayPropertyValidation.tsx +50 -0
- package/src/components/collection_editor/properties/validation/GeneralPropertyValidation.tsx +49 -0
- package/src/components/collection_editor/properties/validation/NumberPropertyValidation.tsx +99 -0
- package/src/components/collection_editor/properties/validation/StringPropertyValidation.tsx +131 -0
- package/src/components/collection_editor/properties/validation/ValidationPanel.tsx +28 -0
- package/src/components/collection_editor/templates/blog_template.ts +115 -0
- package/src/components/collection_editor/templates/products_template.ts +89 -0
- package/src/components/collection_editor/templates/users_template.ts +34 -0
- package/src/components/collection_editor/util.ts +21 -0
- package/src/components/collection_editor/utils/supported_fields.tsx +28 -0
- package/src/components/collection_editor/utils/update_property_for_widget.ts +258 -0
- package/src/components/collection_editor/utils/useTraceUpdate.tsx +23 -0
- package/src/index.ts +31 -0
- package/src/types/collection_editor_controller.tsx +31 -0
- package/src/types/collection_inference.ts +3 -0
- package/src/types/config_controller.tsx +30 -0
- package/src/types/config_permissions.ts +20 -0
- package/src/types/persisted_collection.ts +7 -0
- package/src/useCollectionEditorController.tsx +9 -0
- package/src/useCollectionEditorPlugin.tsx +103 -0
- package/src/useCollectionsConfigController.tsx +9 -0
- package/src/utils/arrays.ts +3 -0
- package/src/utils/entities.ts +38 -0
- package/src/utils/icons.ts +17 -0
- package/src/utils/join_collections.ts +144 -0
- package/src/utils/synonyms.ts +1952 -0
- package/src/vite-env.d.ts +1 -0
- package/dist/types/editable_properties.d.ts +0 -10
|
@@ -12,9 +12,14 @@ export interface CollectionEditorController {
|
|
|
12
12
|
parentCollection?: EntityCollection<any, any, any>;
|
|
13
13
|
}) => void;
|
|
14
14
|
createCollection: (props: {
|
|
15
|
-
|
|
15
|
+
initialValues?: {
|
|
16
|
+
group?: string;
|
|
17
|
+
path?: string;
|
|
18
|
+
name?: string;
|
|
19
|
+
};
|
|
16
20
|
parentPathSegments: string[];
|
|
17
21
|
parentCollection?: EntityCollection<any, any, any>;
|
|
18
22
|
}) => void;
|
|
19
23
|
configPermissions: CollectionEditorPermissionsBuilder;
|
|
24
|
+
rootPathSuggestions?: string[];
|
|
20
25
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CMSType
|
|
1
|
+
import { CMSType } 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,
|
|
@@ -14,7 +14,7 @@ export interface CollectionsConfigController {
|
|
|
14
14
|
}
|
|
15
15
|
export type SaveCollectionParams<M extends Record<string, any>> = {
|
|
16
16
|
path: string;
|
|
17
|
-
collectionData:
|
|
17
|
+
collectionData: PersistedCollection<M>;
|
|
18
18
|
previousPath?: string;
|
|
19
19
|
parentPathSegments?: string[];
|
|
20
20
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { EntityCollection, User } from "@firecms/core";
|
|
2
|
-
export type PersistedCollection<M extends Record<string, any> = any, AdditionalKey extends string = string, UserType extends User = User> = EntityCollection<M, AdditionalKey, UserType> & {
|
|
1
|
+
import { EntityCollection, Properties, User } from "@firecms/core";
|
|
2
|
+
export type PersistedCollection<M extends Record<string, any> = any, AdditionalKey extends string = string, UserType extends User = User> = Omit<EntityCollection<M, AdditionalKey, UserType>, "properties"> & {
|
|
3
|
+
properties: Properties<M>;
|
|
3
4
|
ownerId: string;
|
|
4
5
|
};
|
package/dist/utils/entities.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Properties, PropertyOrBuilder } from "@firecms/core";
|
|
2
|
-
|
|
3
|
-
export declare function
|
|
4
|
-
export declare function removeNonEditableProperties(properties: EditablePropertiesOrBuilders<any>): Properties;
|
|
1
|
+
import { Properties, PropertiesOrBuilders, PropertyOrBuilder } from "@firecms/core";
|
|
2
|
+
export declare function editableProperty(property: PropertyOrBuilder | PropertyOrBuilder): boolean;
|
|
3
|
+
export declare function removeNonEditableProperties(properties: PropertiesOrBuilders<any>): Properties;
|
package/dist/utils/icons.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const searchIndex: Index;
|
|
1
|
+
export declare const iconsSearch: any;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { EntityCollection } from "@firecms/core";
|
|
2
|
+
import { PersistedCollection } from "../types/persisted_collection";
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param storedCollections
|
|
6
|
+
* @param codedCollections
|
|
7
|
+
*/
|
|
8
|
+
export declare function joinCollectionLists(storedCollections: PersistedCollection[], codedCollections: EntityCollection[] | undefined): EntityCollection[];
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @param target
|
|
12
|
+
* @param source
|
|
13
|
+
*/
|
|
14
|
+
export declare function mergeCollections(target: EntityCollection, source: EntityCollection): EntityCollection;
|
package/package.json
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firecms/collection_editor",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.18",
|
|
4
4
|
"main": "./dist/index.umd.js",
|
|
5
5
|
"module": "./dist/index.es.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"source": "src/index.ts",
|
|
8
|
-
"
|
|
9
|
-
"
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.es.js",
|
|
11
|
+
"require": "./dist/index.umd.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
10
14
|
},
|
|
11
15
|
"peerDependencies": {
|
|
12
16
|
"@firecms/data_import": "^3.0.0-alpha.9",
|
|
@@ -62,10 +66,11 @@
|
|
|
62
66
|
"vite-plugin-fonts": "^0.7.0"
|
|
63
67
|
},
|
|
64
68
|
"files": [
|
|
65
|
-
"dist"
|
|
69
|
+
"dist",
|
|
70
|
+
"src"
|
|
66
71
|
],
|
|
67
72
|
"publishConfig": {
|
|
68
73
|
"access": "public"
|
|
69
74
|
},
|
|
70
|
-
"gitHead": "
|
|
75
|
+
"gitHead": "ab75f612b0aa204b1a3f656367578b6ca65e8c5e"
|
|
71
76
|
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import React, { PropsWithChildren, useCallback, useEffect } from "react";
|
|
2
|
+
import equal from "react-fast-compare"
|
|
3
|
+
|
|
4
|
+
import { CollectionsConfigController } from "./types/config_controller";
|
|
5
|
+
import { EntityCollection, useNavigationContext, User } from "@firecms/core";
|
|
6
|
+
import { CollectionEditorDialog } from "./components/collection_editor/CollectionEditorDialog";
|
|
7
|
+
import { useNavigate } from "react-router";
|
|
8
|
+
import { CollectionEditorController } from "./types/collection_editor_controller";
|
|
9
|
+
import { CollectionEditorPermissionsBuilder } from "./types/config_permissions";
|
|
10
|
+
import { CollectionInference } from "./types/collection_inference";
|
|
11
|
+
|
|
12
|
+
export const ConfigControllerContext = React.createContext<CollectionsConfigController>({} as any);
|
|
13
|
+
export const CollectionEditorContext = React.createContext<CollectionEditorController>({} as any);
|
|
14
|
+
|
|
15
|
+
export interface ConfigControllerProviderProps {
|
|
16
|
+
/**
|
|
17
|
+
* Controller for managing the collections' config.
|
|
18
|
+
*/
|
|
19
|
+
collectionConfigController: CollectionsConfigController;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Callback used to infer the schema from the data.
|
|
23
|
+
*/
|
|
24
|
+
collectionInference?: CollectionInference;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Use this builder to define the permissions for the configuration per user.
|
|
28
|
+
*/
|
|
29
|
+
configPermissions?: CollectionEditorPermissionsBuilder;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Groups that cannot be used to create new collections.
|
|
33
|
+
*/
|
|
34
|
+
reservedGroups?: string[];
|
|
35
|
+
|
|
36
|
+
extraView?: {
|
|
37
|
+
View: React.ComponentType<{
|
|
38
|
+
path: string
|
|
39
|
+
}>,
|
|
40
|
+
icon: React.ReactNode
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
pathSuggestions?: (path?: string) => Promise<string[]>;
|
|
44
|
+
|
|
45
|
+
getUser: (uid: string) => User | null
|
|
46
|
+
|
|
47
|
+
getData?: (path: string) => Promise<object[]>;
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const ConfigControllerProvider = React.memo(
|
|
52
|
+
function ConfigControllerProvider({
|
|
53
|
+
children,
|
|
54
|
+
collectionConfigController,
|
|
55
|
+
configPermissions,
|
|
56
|
+
reservedGroups,
|
|
57
|
+
collectionInference,
|
|
58
|
+
extraView,
|
|
59
|
+
pathSuggestions,
|
|
60
|
+
getUser,
|
|
61
|
+
getData
|
|
62
|
+
}: PropsWithChildren<ConfigControllerProviderProps>) {
|
|
63
|
+
|
|
64
|
+
const navigation = useNavigationContext();
|
|
65
|
+
const navigate = useNavigate();
|
|
66
|
+
|
|
67
|
+
const {
|
|
68
|
+
collections
|
|
69
|
+
} = navigation;
|
|
70
|
+
const existingPaths = collections.map(col => col.path.trim().toLowerCase());
|
|
71
|
+
|
|
72
|
+
const [rootPathSuggestions, setRootPathSuggestions] = React.useState<string[] | undefined>();
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (pathSuggestions) {
|
|
75
|
+
pathSuggestions().then((paths) => {
|
|
76
|
+
setRootPathSuggestions(paths.filter(p => !existingPaths.includes(p.trim().toLowerCase())));
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}, [pathSuggestions]);
|
|
80
|
+
|
|
81
|
+
const [currentDialog, setCurrentDialog] = React.useState<{
|
|
82
|
+
isNewCollection: boolean,
|
|
83
|
+
parentCollection?: EntityCollection,
|
|
84
|
+
editedCollectionPath?: string,
|
|
85
|
+
fullPath?: string,
|
|
86
|
+
parentPathSegments: string[],
|
|
87
|
+
initialValues?: {
|
|
88
|
+
path?: string,
|
|
89
|
+
group?: string,
|
|
90
|
+
name?: string
|
|
91
|
+
},
|
|
92
|
+
}>();
|
|
93
|
+
|
|
94
|
+
const defaultConfigPermissions: CollectionEditorPermissionsBuilder = useCallback(() => ({
|
|
95
|
+
createCollections: true,
|
|
96
|
+
editCollections: true,
|
|
97
|
+
deleteCollections: true
|
|
98
|
+
}), []);
|
|
99
|
+
|
|
100
|
+
const editCollection = useCallback(({ path, fullPath, parentPathSegments, parentCollection }: {
|
|
101
|
+
path?: string,
|
|
102
|
+
fullPath?: string,
|
|
103
|
+
parentPathSegments: string[],
|
|
104
|
+
parentCollection?: EntityCollection
|
|
105
|
+
}) => {
|
|
106
|
+
setCurrentDialog({
|
|
107
|
+
editedCollectionPath: path,
|
|
108
|
+
fullPath,
|
|
109
|
+
parentPathSegments,
|
|
110
|
+
isNewCollection: false,
|
|
111
|
+
parentCollection
|
|
112
|
+
});
|
|
113
|
+
}, []);
|
|
114
|
+
|
|
115
|
+
const createCollection = React.useCallback(({ parentPathSegments, parentCollection, initialValues }: {
|
|
116
|
+
parentPathSegments: string[],
|
|
117
|
+
parentCollection?: EntityCollection<any, any, any>
|
|
118
|
+
initialValues?: {
|
|
119
|
+
group?: string,
|
|
120
|
+
path?: string,
|
|
121
|
+
name?: string
|
|
122
|
+
}
|
|
123
|
+
}) => {
|
|
124
|
+
setCurrentDialog({
|
|
125
|
+
isNewCollection: true,
|
|
126
|
+
parentPathSegments,
|
|
127
|
+
parentCollection,
|
|
128
|
+
initialValues
|
|
129
|
+
});
|
|
130
|
+
}, []);
|
|
131
|
+
|
|
132
|
+
const getPathSuggestions = !pathSuggestions
|
|
133
|
+
? undefined
|
|
134
|
+
: (path?: string) => {
|
|
135
|
+
if (!path && rootPathSuggestions)
|
|
136
|
+
return Promise.resolve(rootPathSuggestions);
|
|
137
|
+
else {
|
|
138
|
+
return pathSuggestions?.(path);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return (
|
|
143
|
+
<ConfigControllerContext.Provider value={collectionConfigController}>
|
|
144
|
+
<CollectionEditorContext.Provider
|
|
145
|
+
value={{
|
|
146
|
+
editCollection,
|
|
147
|
+
createCollection,
|
|
148
|
+
configPermissions: configPermissions ?? defaultConfigPermissions,
|
|
149
|
+
rootPathSuggestions
|
|
150
|
+
}}>
|
|
151
|
+
|
|
152
|
+
{children}
|
|
153
|
+
|
|
154
|
+
<CollectionEditorDialog
|
|
155
|
+
open={Boolean(currentDialog)}
|
|
156
|
+
configController={collectionConfigController}
|
|
157
|
+
isNewCollection={false}
|
|
158
|
+
collectionInference={collectionInference}
|
|
159
|
+
{...currentDialog}
|
|
160
|
+
getData={getData}
|
|
161
|
+
reservedGroups={reservedGroups}
|
|
162
|
+
extraView={extraView}
|
|
163
|
+
pathSuggestions={getPathSuggestions}
|
|
164
|
+
getUser={getUser}
|
|
165
|
+
handleClose={(collection) => {
|
|
166
|
+
if (collection && currentDialog?.isNewCollection && !currentDialog.parentPathSegments.length) {
|
|
167
|
+
const url = navigation.buildUrlCollectionPath(collection.alias ?? collection.path);
|
|
168
|
+
navigate(url);
|
|
169
|
+
}
|
|
170
|
+
setCurrentDialog(undefined);
|
|
171
|
+
}}/>
|
|
172
|
+
|
|
173
|
+
</CollectionEditorContext.Provider>
|
|
174
|
+
|
|
175
|
+
</ConfigControllerContext.Provider>
|
|
176
|
+
);
|
|
177
|
+
}, equal);
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import equal from "react-fast-compare"
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Button,
|
|
5
|
+
CollectionActionsProps,
|
|
6
|
+
IconButton,
|
|
7
|
+
mergeDeep,
|
|
8
|
+
SaveIcon,
|
|
9
|
+
SettingsIcon,
|
|
10
|
+
Tooltip,
|
|
11
|
+
useAuthController,
|
|
12
|
+
useNavigationContext,
|
|
13
|
+
useSnackbarController
|
|
14
|
+
} from "@firecms/core";
|
|
15
|
+
|
|
16
|
+
import { useCollectionEditorController } from "../useCollectionEditorController";
|
|
17
|
+
import { useCollectionsConfigController } from "../useCollectionsConfigController";
|
|
18
|
+
import { PersistedCollection } from "../types/persisted_collection";
|
|
19
|
+
|
|
20
|
+
export function EditorCollectionAction({
|
|
21
|
+
path: fullPath,
|
|
22
|
+
parentPathSegments,
|
|
23
|
+
collection,
|
|
24
|
+
tableController
|
|
25
|
+
}: CollectionActionsProps) {
|
|
26
|
+
|
|
27
|
+
const authController = useAuthController();
|
|
28
|
+
const navigationController = useNavigationContext();
|
|
29
|
+
const collectionEditorController = useCollectionEditorController();
|
|
30
|
+
const configController = useCollectionsConfigController();
|
|
31
|
+
const snackbarController = useSnackbarController();
|
|
32
|
+
|
|
33
|
+
const parentCollection = navigationController.getCollectionFromPaths(parentPathSegments);
|
|
34
|
+
|
|
35
|
+
const canEditCollection = collectionEditorController.configPermissions
|
|
36
|
+
? collectionEditorController.configPermissions({
|
|
37
|
+
user: authController.user,
|
|
38
|
+
collection
|
|
39
|
+
}).editCollections
|
|
40
|
+
: true;
|
|
41
|
+
|
|
42
|
+
let saveDefaultFilterButton = null;
|
|
43
|
+
if (!equal(getObjectOrNull(tableController.filterValues), getObjectOrNull(collection.initialFilter)) ||
|
|
44
|
+
!equal(getObjectOrNull(tableController.sortBy), getObjectOrNull(collection.initialSort))) {
|
|
45
|
+
saveDefaultFilterButton = <Tooltip
|
|
46
|
+
title={tableController.sortBy || tableController.filterValues ? "Save default filter and sort" : "Clear default filter and sort"}>
|
|
47
|
+
<Button
|
|
48
|
+
color={"primary"}
|
|
49
|
+
size={"small"}
|
|
50
|
+
variant={"outlined"}
|
|
51
|
+
onClick={() => configController
|
|
52
|
+
?.saveCollection({
|
|
53
|
+
path: collection.path,
|
|
54
|
+
parentPathSegments,
|
|
55
|
+
collectionData: mergeDeep(collection as PersistedCollection,
|
|
56
|
+
{
|
|
57
|
+
initialFilter: tableController.filterValues ?? null,
|
|
58
|
+
initialSort: tableController.sortBy ?? null
|
|
59
|
+
})
|
|
60
|
+
}).then(() => {
|
|
61
|
+
snackbarController.open({
|
|
62
|
+
type: "success",
|
|
63
|
+
message: "Default config saved"
|
|
64
|
+
});
|
|
65
|
+
})}>
|
|
66
|
+
<SaveIcon/>
|
|
67
|
+
{/*{tableController.sortBy || tableController.filterValues ? "Save default filter and sort" : "Clear default filter and sort"}*/}
|
|
68
|
+
</Button>
|
|
69
|
+
</Tooltip>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const editorButton = <Tooltip
|
|
73
|
+
title={canEditCollection ? "Edit collection" : "You don't have permissions to edit this collection"}>
|
|
74
|
+
<IconButton
|
|
75
|
+
color={"primary"}
|
|
76
|
+
disabled={!canEditCollection}
|
|
77
|
+
onClick={canEditCollection
|
|
78
|
+
? () => collectionEditorController?.editCollection({ path: collection.path, fullPath, parentPathSegments, parentCollection })
|
|
79
|
+
: undefined}>
|
|
80
|
+
<SettingsIcon/>
|
|
81
|
+
</IconButton>
|
|
82
|
+
</Tooltip>;
|
|
83
|
+
|
|
84
|
+
return <>
|
|
85
|
+
{canEditCollection && saveDefaultFilterButton}
|
|
86
|
+
{editorButton}
|
|
87
|
+
</>
|
|
88
|
+
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function getObjectOrNull(o?: object): object | null {
|
|
92
|
+
if (o && Object.keys(o).length === 0)
|
|
93
|
+
return o
|
|
94
|
+
return o ?? null;
|
|
95
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DeleteConfirmationDialog,
|
|
3
|
+
DeleteIcon,
|
|
4
|
+
IconButton,
|
|
5
|
+
Menu,
|
|
6
|
+
MenuItem,
|
|
7
|
+
MoreVertIcon,
|
|
8
|
+
PluginHomePageActionsProps,
|
|
9
|
+
SettingsIcon,
|
|
10
|
+
useAuthController
|
|
11
|
+
} from "@firecms/core";
|
|
12
|
+
import { useCollectionEditorController } from "../useCollectionEditorController";
|
|
13
|
+
import { useCallback, useState } from "react";
|
|
14
|
+
import { useCollectionsConfigController } from "../useCollectionsConfigController";
|
|
15
|
+
|
|
16
|
+
export function HomePageEditorCollectionAction({
|
|
17
|
+
path,
|
|
18
|
+
collection
|
|
19
|
+
}: PluginHomePageActionsProps) {
|
|
20
|
+
|
|
21
|
+
const authController = useAuthController();
|
|
22
|
+
const configController = useCollectionsConfigController();
|
|
23
|
+
const collectionEditorController = useCollectionEditorController();
|
|
24
|
+
|
|
25
|
+
const permissions = collectionEditorController.configPermissions({
|
|
26
|
+
user: authController.user,
|
|
27
|
+
collection
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const onEditCollectionClicked = useCallback(() => {
|
|
31
|
+
collectionEditorController?.editCollection({ path, parentPathSegments: [] });
|
|
32
|
+
}, [collectionEditorController, path]);
|
|
33
|
+
|
|
34
|
+
const [deleteRequested, setDeleteRequested] = useState(false);
|
|
35
|
+
|
|
36
|
+
const deleteCollection = useCallback(() => {
|
|
37
|
+
configController?.deleteCollection({ path });
|
|
38
|
+
}, [path, configController]);
|
|
39
|
+
|
|
40
|
+
return <>
|
|
41
|
+
|
|
42
|
+
<div>
|
|
43
|
+
{permissions.deleteCollections &&
|
|
44
|
+
<Menu
|
|
45
|
+
trigger={<IconButton>
|
|
46
|
+
<MoreVertIcon size={"small"}/>
|
|
47
|
+
</IconButton>}
|
|
48
|
+
>
|
|
49
|
+
<MenuItem onClick={(event) => {
|
|
50
|
+
event.preventDefault();
|
|
51
|
+
event.stopPropagation();
|
|
52
|
+
setDeleteRequested(true);
|
|
53
|
+
}}>
|
|
54
|
+
<DeleteIcon/>
|
|
55
|
+
Delete
|
|
56
|
+
</MenuItem>
|
|
57
|
+
|
|
58
|
+
</Menu>
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
{permissions.editCollections &&
|
|
63
|
+
<IconButton
|
|
64
|
+
onClick={(event) => {
|
|
65
|
+
onEditCollectionClicked();
|
|
66
|
+
}}>
|
|
67
|
+
<SettingsIcon size={"small"}/>
|
|
68
|
+
</IconButton>}
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<DeleteConfirmationDialog
|
|
72
|
+
open={deleteRequested}
|
|
73
|
+
onAccept={deleteCollection}
|
|
74
|
+
onCancel={() => setDeleteRequested(false)}
|
|
75
|
+
title={<>Delete this collection?</>}
|
|
76
|
+
body={<> This will <b>not
|
|
77
|
+
delete any data</b>, only
|
|
78
|
+
the collection in the CMS</>}/>
|
|
79
|
+
</>;
|
|
80
|
+
|
|
81
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { AddIcon, Card, cn, PluginHomePageAdditionalCardsProps, Typography, useAuthController } from "@firecms/core";
|
|
2
|
+
import { useCollectionEditorController } from "../useCollectionEditorController";
|
|
3
|
+
|
|
4
|
+
export function NewCollectionCard({
|
|
5
|
+
group,
|
|
6
|
+
context
|
|
7
|
+
}: PluginHomePageAdditionalCardsProps) {
|
|
8
|
+
|
|
9
|
+
if (!context.navigation.topLevelNavigation)
|
|
10
|
+
throw Error("Navigation not ready in FireCMSHomePage");
|
|
11
|
+
|
|
12
|
+
const authController = useAuthController();
|
|
13
|
+
|
|
14
|
+
const collectionEditorController = useCollectionEditorController();
|
|
15
|
+
const canCreateCollections = collectionEditorController.configPermissions
|
|
16
|
+
? collectionEditorController.configPermissions({
|
|
17
|
+
user: authController.user,
|
|
18
|
+
}).createCollections
|
|
19
|
+
: true;
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<Card className={cn("h-full p-4 min-h-[124px]")}
|
|
23
|
+
onClick={collectionEditorController && canCreateCollections
|
|
24
|
+
? () => collectionEditorController.createCollection({
|
|
25
|
+
initialValues: group ? { group } : undefined,
|
|
26
|
+
parentPathSegments: []
|
|
27
|
+
})
|
|
28
|
+
: undefined}>
|
|
29
|
+
|
|
30
|
+
<div
|
|
31
|
+
className="flex flex-col items-start h-full w-full items-center justify-center h-full w-full flex-grow flex-col">
|
|
32
|
+
<AddIcon color="primary"/>
|
|
33
|
+
<Typography color="primary"
|
|
34
|
+
variant={"caption"}
|
|
35
|
+
className={"font-medium"}>{"Add new collection".toUpperCase()}</Typography>
|
|
36
|
+
|
|
37
|
+
{!canCreateCollections &&
|
|
38
|
+
<Typography variant={"caption"}>You don't have permissions to create
|
|
39
|
+
collections</Typography>
|
|
40
|
+
}
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
</Card>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { AddIcon, Chip, Collapse, Typography, unslugify, useAuthController, useNavigationContext } from "@firecms/core";
|
|
2
|
+
import { useCollectionEditorController } from "../useCollectionEditorController";
|
|
3
|
+
import React from "react";
|
|
4
|
+
|
|
5
|
+
export function RootCollectionSuggestions() {
|
|
6
|
+
|
|
7
|
+
const authController = useAuthController();
|
|
8
|
+
const navigationContext = useNavigationContext();
|
|
9
|
+
|
|
10
|
+
const collectionEditorController = useCollectionEditorController();
|
|
11
|
+
const canCreateCollections = collectionEditorController.configPermissions
|
|
12
|
+
? collectionEditorController.configPermissions({
|
|
13
|
+
user: authController.user
|
|
14
|
+
}).createCollections
|
|
15
|
+
: true;
|
|
16
|
+
|
|
17
|
+
const rootPathSuggestions = collectionEditorController.rootPathSuggestions ?? [];
|
|
18
|
+
|
|
19
|
+
const showSuggestions = rootPathSuggestions.length > 3 || (navigationContext.collections.length === 0 && rootPathSuggestions.length > 0);
|
|
20
|
+
return <Collapse
|
|
21
|
+
in={showSuggestions}>
|
|
22
|
+
|
|
23
|
+
<div
|
|
24
|
+
className={"flex flex-col gap-1 p-2"}>
|
|
25
|
+
|
|
26
|
+
<Typography variant={"body2"} color={"secondary"}>
|
|
27
|
+
Create a collection from your data:
|
|
28
|
+
</Typography>
|
|
29
|
+
|
|
30
|
+
<div
|
|
31
|
+
className={"flex flex-row gap-1 overflow-scroll no-scrollbar "}>
|
|
32
|
+
{rootPathSuggestions.map((path) => {
|
|
33
|
+
return (
|
|
34
|
+
<div key={path}>
|
|
35
|
+
<Chip
|
|
36
|
+
icon={<AddIcon size={"small"}/>}
|
|
37
|
+
colorScheme={"cyanLighter"}
|
|
38
|
+
onClick={collectionEditorController && canCreateCollections
|
|
39
|
+
? () => collectionEditorController.createCollection({
|
|
40
|
+
initialValues: { path, name: unslugify(path) },
|
|
41
|
+
parentPathSegments: []
|
|
42
|
+
})
|
|
43
|
+
: undefined}
|
|
44
|
+
size="small">
|
|
45
|
+
{path}
|
|
46
|
+
</Chip>
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
})}
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</Collapse>
|
|
53
|
+
}
|