@firecms/collection_editor 3.0.0-canary.18 → 3.0.0-canary.182
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 +10069 -4770
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +10759 -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/CollectionDetailsForm.d.ts +3 -1
- package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +3 -2
- 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/LayoutModeSwitch.d.ts +5 -0
- 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 +24 -35
- package/src/ConfigControllerProvider.tsx +76 -64
- 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 +19 -13
- package/src/ui/NewCollectionButton.tsx +1 -1
- package/src/ui/NewCollectionCard.tsx +3 -3
- package/src/ui/PropertyAddColumnComponent.tsx +11 -6
- package/src/ui/collection_editor/CollectionDetailsForm.tsx +90 -11
- package/src/ui/collection_editor/CollectionEditorDialog.tsx +101 -34
- package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +8 -7
- package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +39 -36
- package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +6 -5
- package/src/ui/collection_editor/EnumForm.tsx +10 -6
- package/src/ui/collection_editor/GetCodeDialog.tsx +56 -26
- package/src/ui/collection_editor/LayoutModeSwitch.tsx +54 -0
- package/src/ui/collection_editor/PropertyEditView.tsx +257 -80
- package/src/ui/collection_editor/PropertyFieldPreview.tsx +7 -10
- package/src/ui/collection_editor/PropertyTree.tsx +9 -7
- package/src/ui/collection_editor/SubcollectionsEditTab.tsx +26 -19
- package/src/ui/collection_editor/UnsavedChangesDialog.tsx +3 -5
- package/src/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +26 -9
- package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +42 -9
- package/src/ui/collection_editor/properties/BlockPropertyField.tsx +32 -20
- package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +54 -47
- package/src/ui/collection_editor/properties/EnumPropertyField.tsx +3 -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/ReferencePropertyField.tsx +2 -0
- package/src/ui/collection_editor/properties/RepeatPropertyField.tsx +0 -1
- package/src/ui/collection_editor/properties/StoragePropertyField.tsx +34 -19
- package/src/ui/collection_editor/properties/StringPropertyField.tsx +1 -10
- package/src/ui/collection_editor/properties/UrlPropertyField.tsx +1 -0
- 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 +36 -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,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}
|
|
@@ -265,7 +277,7 @@ export const ConfigControllerProvider = React.memo(
|
|
|
265
277
|
getData={getData && currentPropertyDialog?.editedCollectionId
|
|
266
278
|
? () => {
|
|
267
279
|
console.debug("get data for property", currentPropertyDialog?.editedCollectionId);
|
|
268
|
-
const resolvedPath = navigation.
|
|
280
|
+
const resolvedPath = navigation.resolveIdsFrom(currentPropertyDialog.editedCollectionId!)
|
|
269
281
|
return getData(resolvedPath, []);
|
|
270
282
|
}
|
|
271
283
|
: undefined}
|
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,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({
|
|
@@ -14,6 +14,7 @@ export function HomePageEditorCollectionAction({
|
|
|
14
14
|
collection
|
|
15
15
|
}: PluginHomePageActionsProps) {
|
|
16
16
|
|
|
17
|
+
|
|
17
18
|
const snackbarController = useSnackbarController();
|
|
18
19
|
const authController = useAuthController();
|
|
19
20
|
const configController = useCollectionsConfigController();
|
|
@@ -24,13 +25,16 @@ export function HomePageEditorCollectionAction({
|
|
|
24
25
|
collection
|
|
25
26
|
});
|
|
26
27
|
|
|
27
|
-
const onEditCollectionClicked =
|
|
28
|
-
collectionEditorController?.editCollection({
|
|
29
|
-
|
|
28
|
+
const onEditCollectionClicked = () => {
|
|
29
|
+
collectionEditorController?.editCollection({
|
|
30
|
+
id: collection.id,
|
|
31
|
+
parentCollectionIds: []
|
|
32
|
+
});
|
|
33
|
+
};
|
|
30
34
|
|
|
31
35
|
const [deleteRequested, setDeleteRequested] = useState(false);
|
|
32
36
|
|
|
33
|
-
const deleteCollection =
|
|
37
|
+
const deleteCollection = () => {
|
|
34
38
|
configController?.deleteCollection({ id: collection.id }).then(() => {
|
|
35
39
|
setDeleteRequested(false);
|
|
36
40
|
snackbarController.open({
|
|
@@ -38,7 +42,7 @@ export function HomePageEditorCollectionAction({
|
|
|
38
42
|
type: "success"
|
|
39
43
|
});
|
|
40
44
|
});
|
|
41
|
-
}
|
|
45
|
+
};
|
|
42
46
|
|
|
43
47
|
return <>
|
|
44
48
|
|
|
@@ -49,11 +53,13 @@ export function HomePageEditorCollectionAction({
|
|
|
49
53
|
<MoreVertIcon size={"small"}/>
|
|
50
54
|
</IconButton>}
|
|
51
55
|
>
|
|
52
|
-
<MenuItem
|
|
53
|
-
|
|
54
|
-
event
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
<MenuItem
|
|
57
|
+
dense={true}
|
|
58
|
+
onClick={(event) => {
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
event.stopPropagation();
|
|
61
|
+
setDeleteRequested(true);
|
|
62
|
+
}}>
|
|
57
63
|
<DeleteIcon/>
|
|
58
64
|
Delete
|
|
59
65
|
</MenuItem>
|
|
@@ -71,7 +77,7 @@ export function HomePageEditorCollectionAction({
|
|
|
71
77
|
</IconButton>}
|
|
72
78
|
</div>
|
|
73
79
|
|
|
74
|
-
<
|
|
80
|
+
<ConfirmationDialog
|
|
75
81
|
open={deleteRequested}
|
|
76
82
|
onAccept={deleteCollection}
|
|
77
83
|
onCancel={() => setDeleteRequested(false)}
|
|
@@ -3,7 +3,7 @@ import { useCollectionEditorController } from "../useCollectionEditorController"
|
|
|
3
3
|
|
|
4
4
|
export function NewCollectionButton() {
|
|
5
5
|
const collectionEditorController = useCollectionEditorController();
|
|
6
|
-
return <div className={"bg-
|
|
6
|
+
return <div className={"bg-surface-50 dark:bg-surface-900 min-w-fit rounded"}>
|
|
7
7
|
<Button className={"min-w-fit"}
|
|
8
8
|
variant={"outlined"}
|
|
9
9
|
onClick={() => collectionEditorController.createCollection({
|