@firecms/collection_editor 3.0.0 → 3.1.0-canary.02232f4
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 +6 -0
- package/dist/api/generateCollectionApi.d.ts +71 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.es.js +15234 -8138
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +15199 -8103
- package/dist/index.umd.js.map +1 -1
- package/dist/locales/de.d.ts +120 -0
- package/dist/locales/en.d.ts +120 -0
- package/dist/locales/es.d.ts +120 -0
- package/dist/locales/fr.d.ts +120 -0
- package/dist/locales/hi.d.ts +120 -0
- package/dist/locales/it.d.ts +120 -0
- package/dist/locales/pt.d.ts +120 -0
- package/dist/types/collection_editor_controller.d.ts +14 -0
- package/dist/types/collection_inference.d.ts +8 -2
- package/dist/types/config_controller.d.ts +31 -1
- package/dist/ui/AddKanbanColumnAction.d.ts +11 -0
- package/dist/ui/KanbanSetupAction.d.ts +10 -0
- package/dist/ui/collection_editor/AICollectionGeneratorPopover.d.ts +37 -0
- package/dist/ui/collection_editor/AIModifiedPathsContext.d.ts +20 -0
- package/dist/ui/collection_editor/CollectionDetailsForm.d.ts +2 -3
- package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +24 -0
- package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +4 -1
- package/dist/ui/collection_editor/CollectionJsonImportDialog.d.ts +7 -0
- package/dist/ui/collection_editor/CollectionYupValidation.d.ts +9 -13
- package/dist/ui/collection_editor/DisplaySettingsForm.d.ts +3 -0
- package/dist/ui/collection_editor/EntityActionsEditTab.d.ts +2 -1
- package/dist/ui/collection_editor/ExtendSettingsForm.d.ts +14 -0
- package/dist/ui/collection_editor/GeneralSettingsForm.d.ts +7 -0
- package/dist/ui/collection_editor/KanbanConfigSection.d.ts +4 -0
- package/dist/ui/collection_editor/PropertyEditView.d.ts +6 -1
- package/dist/ui/collection_editor/PropertyTree.d.ts +2 -1
- package/dist/ui/collection_editor/SubcollectionsEditTab.d.ts +2 -1
- package/dist/ui/collection_editor/ViewModeSwitch.d.ts +6 -0
- package/dist/ui/collection_editor/properties/EnumPropertyField.d.ts +2 -1
- package/dist/ui/collection_editor/properties/conditions/ConditionsEditor.d.ts +10 -0
- package/dist/ui/collection_editor/properties/conditions/ConditionsPanel.d.ts +2 -0
- package/dist/ui/collection_editor/properties/conditions/EnumConditionsEditor.d.ts +6 -0
- package/dist/ui/collection_editor/properties/conditions/index.d.ts +6 -0
- package/dist/ui/collection_editor/properties/conditions/property_paths.d.ts +19 -0
- package/dist/useCollectionEditorPlugin.d.ts +7 -1
- package/dist/utils/validateCollectionJson.d.ts +22 -0
- package/package.json +15 -15
- package/src/ConfigControllerProvider.tsx +82 -47
- package/src/api/generateCollectionApi.ts +119 -0
- package/src/api/index.ts +1 -0
- package/src/index.ts +28 -1
- package/src/locales/de.ts +125 -0
- package/src/locales/en.ts +145 -0
- package/src/locales/es.ts +125 -0
- package/src/locales/fr.ts +125 -0
- package/src/locales/hi.ts +125 -0
- package/src/locales/it.ts +125 -0
- package/src/locales/pt.ts +125 -0
- package/src/types/collection_editor_controller.tsx +16 -3
- package/src/types/collection_inference.ts +15 -2
- package/src/types/config_controller.tsx +37 -1
- package/src/ui/AddKanbanColumnAction.tsx +203 -0
- package/src/ui/EditorCollectionAction.tsx +3 -3
- package/src/ui/EditorCollectionActionStart.tsx +1 -2
- package/src/ui/EditorEntityAction.tsx +3 -2
- package/src/ui/HomePageEditorCollectionAction.tsx +41 -13
- package/src/ui/KanbanSetupAction.tsx +38 -0
- package/src/ui/MissingReferenceWidget.tsx +1 -1
- package/src/ui/NewCollectionButton.tsx +4 -2
- package/src/ui/NewCollectionCard.tsx +7 -4
- package/src/ui/PropertyAddColumnComponent.tsx +4 -3
- package/src/ui/collection_editor/AICollectionGeneratorPopover.tsx +243 -0
- package/src/ui/collection_editor/AIModifiedPathsContext.tsx +88 -0
- package/src/ui/collection_editor/CollectionDetailsForm.tsx +222 -268
- package/src/ui/collection_editor/CollectionEditorDialog.tsx +270 -204
- package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +138 -71
- package/src/ui/collection_editor/CollectionJsonImportDialog.tsx +171 -0
- package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +202 -101
- package/src/ui/collection_editor/DisplaySettingsForm.tsx +335 -0
- package/src/ui/collection_editor/EntityActionsEditTab.tsx +106 -97
- package/src/ui/collection_editor/EntityActionsSelectDialog.tsx +8 -10
- package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +5 -7
- package/src/ui/collection_editor/EnumForm.tsx +153 -102
- package/src/ui/collection_editor/ExtendSettingsForm.tsx +94 -0
- package/src/ui/collection_editor/GeneralSettingsForm.tsx +335 -0
- package/src/ui/collection_editor/GetCodeDialog.tsx +63 -41
- package/src/ui/collection_editor/KanbanConfigSection.tsx +209 -0
- package/src/ui/collection_editor/LayoutModeSwitch.tsx +27 -43
- package/src/ui/collection_editor/PropertyEditView.tsx +272 -199
- package/src/ui/collection_editor/PropertyFieldPreview.tsx +1 -1
- package/src/ui/collection_editor/PropertyTree.tsx +130 -58
- package/src/ui/collection_editor/SubcollectionsEditTab.tsx +169 -163
- package/src/ui/collection_editor/UnsavedChangesDialog.tsx +0 -2
- package/src/ui/collection_editor/ViewModeSwitch.tsx +43 -0
- package/src/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +6 -3
- package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +5 -2
- package/src/ui/collection_editor/properties/BlockPropertyField.tsx +0 -2
- package/src/ui/collection_editor/properties/BooleanPropertyField.tsx +4 -1
- package/src/ui/collection_editor/properties/CommonPropertyFields.tsx +6 -4
- package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +126 -42
- package/src/ui/collection_editor/properties/EnumPropertyField.tsx +32 -24
- package/src/ui/collection_editor/properties/MapPropertyField.tsx +8 -9
- package/src/ui/collection_editor/properties/MarkdownPropertyField.tsx +128 -53
- package/src/ui/collection_editor/properties/NumberPropertyField.tsx +3 -1
- package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +6 -9
- package/src/ui/collection_editor/properties/StoragePropertyField.tsx +65 -49
- package/src/ui/collection_editor/properties/StringPropertyField.tsx +3 -1
- package/src/ui/collection_editor/properties/UrlPropertyField.tsx +12 -10
- package/src/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +23 -4
- package/src/ui/collection_editor/properties/conditions/ConditionsEditor.tsx +866 -0
- package/src/ui/collection_editor/properties/conditions/ConditionsPanel.tsx +28 -0
- package/src/ui/collection_editor/properties/conditions/EnumConditionsEditor.tsx +599 -0
- package/src/ui/collection_editor/properties/conditions/index.ts +6 -0
- package/src/ui/collection_editor/properties/conditions/property_paths.ts +92 -0
- package/src/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +5 -2
- package/src/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +7 -5
- package/src/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +10 -7
- package/src/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +11 -9
- package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +5 -2
- package/src/useCollectionEditorPlugin.tsx +53 -22
- package/src/utils/validateCollectionJson.ts +380 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import React, { useCallback, useMemo, useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
EntityCollection,
|
|
4
|
+
getPropertyInPath,
|
|
5
|
+
ResolvedStringProperty,
|
|
6
|
+
resolveCollection,
|
|
7
|
+
resolveEnumValues,
|
|
8
|
+
toSnakeCase,
|
|
9
|
+
useAuthController,
|
|
10
|
+
useCustomizationController
|
|
11
|
+
} from "@firecms/core";
|
|
12
|
+
import {
|
|
13
|
+
AddIcon,
|
|
14
|
+
Button,
|
|
15
|
+
cls,
|
|
16
|
+
defaultBorderMixin,
|
|
17
|
+
Dialog,
|
|
18
|
+
DialogActions,
|
|
19
|
+
DialogContent,
|
|
20
|
+
IconButton,
|
|
21
|
+
TextField,
|
|
22
|
+
Typography
|
|
23
|
+
} from "@firecms/ui";
|
|
24
|
+
import { useCollectionsConfigController } from "../useCollectionsConfigController";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Component rendered at the end of the Kanban board to add new columns (enum values).
|
|
28
|
+
* Opens a dialog to input a new enum value for the column property.
|
|
29
|
+
*/
|
|
30
|
+
export function AddKanbanColumnAction({
|
|
31
|
+
collection,
|
|
32
|
+
fullPath,
|
|
33
|
+
parentCollectionIds,
|
|
34
|
+
columnProperty
|
|
35
|
+
}: {
|
|
36
|
+
collection: EntityCollection;
|
|
37
|
+
fullPath: string;
|
|
38
|
+
parentCollectionIds: string[];
|
|
39
|
+
columnProperty: string;
|
|
40
|
+
}) {
|
|
41
|
+
const [dialogOpen, setDialogOpen] = useState(false);
|
|
42
|
+
const [newValueLabel, setNewValueLabel] = useState("");
|
|
43
|
+
const [saving, setSaving] = useState(false);
|
|
44
|
+
|
|
45
|
+
const configController = useCollectionsConfigController();
|
|
46
|
+
const authController = useAuthController();
|
|
47
|
+
const customizationController = useCustomizationController();
|
|
48
|
+
|
|
49
|
+
const resolvedCollection = useMemo(() => resolveCollection({
|
|
50
|
+
collection,
|
|
51
|
+
path: fullPath,
|
|
52
|
+
propertyConfigs: customizationController.propertyConfigs,
|
|
53
|
+
authController
|
|
54
|
+
}), [collection, fullPath, customizationController.propertyConfigs, authController]);
|
|
55
|
+
|
|
56
|
+
// Get current enum values
|
|
57
|
+
const currentEnumValues = useMemo(() => {
|
|
58
|
+
const property = getPropertyInPath(resolvedCollection.properties, columnProperty);
|
|
59
|
+
if (!property || !('dataType' in property) || property.dataType !== "string") {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
const stringProperty = property as ResolvedStringProperty;
|
|
63
|
+
if (!stringProperty.enumValues) {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
return resolveEnumValues(stringProperty.enumValues) ?? [];
|
|
67
|
+
}, [resolvedCollection, columnProperty]);
|
|
68
|
+
|
|
69
|
+
const handleAddColumn = useCallback(async () => {
|
|
70
|
+
if (!newValueLabel.trim() || !configController) return;
|
|
71
|
+
|
|
72
|
+
setSaving(true);
|
|
73
|
+
try {
|
|
74
|
+
// Check for property in persisted collection first, then resolved collection
|
|
75
|
+
// This handles code-defined properties that aren't in the persisted config
|
|
76
|
+
let property = collection?.properties?.[columnProperty];
|
|
77
|
+
let isCodeDefinedProperty = false;
|
|
78
|
+
|
|
79
|
+
if (!property || typeof property === 'function') {
|
|
80
|
+
// Property not in persisted config - check resolved collection
|
|
81
|
+
property = resolvedCollection.properties?.[columnProperty];
|
|
82
|
+
isCodeDefinedProperty = true;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Type guard: property must be an object with dataType === "string"
|
|
86
|
+
if (!property || typeof property === 'function' || !('dataType' in property) || property.dataType !== "string") {
|
|
87
|
+
console.error("Column property not found or not a string. Property:", property);
|
|
88
|
+
setSaving(false);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Now we know property is a StringProperty
|
|
93
|
+
const stringProperty = property as { dataType: "string"; enumValues?: any; name?: string };
|
|
94
|
+
|
|
95
|
+
// Create new enum value
|
|
96
|
+
const newId = toSnakeCase(newValueLabel.trim());
|
|
97
|
+
const newEnumValue = {
|
|
98
|
+
id: newId,
|
|
99
|
+
label: newValueLabel.trim()
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// Get existing enum values from the resolved property (current runtime values)
|
|
103
|
+
// Use currentEnumValues which is already computed from resolvedCollection
|
|
104
|
+
const existingEnumValues = currentEnumValues.map(ev => ({
|
|
105
|
+
id: ev.id,
|
|
106
|
+
label: ev.label
|
|
107
|
+
}));
|
|
108
|
+
|
|
109
|
+
// Add new enum value
|
|
110
|
+
const updatedEnumValues = [...existingEnumValues, newEnumValue];
|
|
111
|
+
|
|
112
|
+
// Build the property to save
|
|
113
|
+
// If it's code-defined, we create a minimal override with just enumValues
|
|
114
|
+
const updatedProperty = isCodeDefinedProperty
|
|
115
|
+
? {
|
|
116
|
+
dataType: "string" as const,
|
|
117
|
+
name: stringProperty.name || columnProperty,
|
|
118
|
+
enumValues: updatedEnumValues
|
|
119
|
+
}
|
|
120
|
+
: {
|
|
121
|
+
...property,
|
|
122
|
+
enumValues: updatedEnumValues
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
// Save the updated property
|
|
126
|
+
await configController.saveProperty({
|
|
127
|
+
path: fullPath,
|
|
128
|
+
propertyKey: columnProperty,
|
|
129
|
+
property: updatedProperty as any,
|
|
130
|
+
parentCollectionIds
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
setNewValueLabel("");
|
|
134
|
+
setDialogOpen(false);
|
|
135
|
+
} catch (error) {
|
|
136
|
+
console.error("Error adding new column:", error);
|
|
137
|
+
} finally {
|
|
138
|
+
setSaving(false);
|
|
139
|
+
}
|
|
140
|
+
}, [newValueLabel, configController, collection, columnProperty, fullPath, parentCollectionIds]);
|
|
141
|
+
|
|
142
|
+
const handleKeyDown = (e: React.KeyboardEvent) => {
|
|
143
|
+
if (e.key === "Enter" && newValueLabel.trim()) {
|
|
144
|
+
handleAddColumn();
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
return (
|
|
149
|
+
<>
|
|
150
|
+
<div
|
|
151
|
+
className={cls(
|
|
152
|
+
"border h-full w-80 min-w-80 mx-2 flex flex-col items-center justify-center rounded-md",
|
|
153
|
+
"bg-surface-50 dark:bg-surface-950 hover:bg-surface-100 dark:hover:bg-surface-900",
|
|
154
|
+
"cursor-pointer transition-colors duration-200 ease-in-out",
|
|
155
|
+
defaultBorderMixin
|
|
156
|
+
)}
|
|
157
|
+
onClick={() => setDialogOpen(true)}
|
|
158
|
+
>
|
|
159
|
+
<IconButton size="large" className="opacity-60 hover:opacity-100">
|
|
160
|
+
<AddIcon size="large" />
|
|
161
|
+
</IconButton>
|
|
162
|
+
<Typography variant="caption" color="secondary" className="mt-2">
|
|
163
|
+
Add Column
|
|
164
|
+
</Typography>
|
|
165
|
+
</div>
|
|
166
|
+
|
|
167
|
+
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
|
|
168
|
+
<DialogContent className="max-w-md">
|
|
169
|
+
<Typography variant="h6" className="mb-4">
|
|
170
|
+
Add New Column
|
|
171
|
+
</Typography>
|
|
172
|
+
<Typography variant="body2" color="secondary" className="mb-4">
|
|
173
|
+
Add a new option to the "{columnProperty}" property.
|
|
174
|
+
This will create a new column in the Kanban board.
|
|
175
|
+
</Typography>
|
|
176
|
+
<TextField
|
|
177
|
+
label="Column Name"
|
|
178
|
+
value={newValueLabel}
|
|
179
|
+
onChange={(e) => setNewValueLabel(e.target.value)}
|
|
180
|
+
onKeyDown={handleKeyDown}
|
|
181
|
+
autoFocus
|
|
182
|
+
disabled={saving}
|
|
183
|
+
/>
|
|
184
|
+
</DialogContent>
|
|
185
|
+
<DialogActions>
|
|
186
|
+
<Button
|
|
187
|
+
variant="text"
|
|
188
|
+
onClick={() => setDialogOpen(false)}
|
|
189
|
+
disabled={saving}
|
|
190
|
+
>
|
|
191
|
+
Cancel
|
|
192
|
+
</Button>
|
|
193
|
+
<Button
|
|
194
|
+
onClick={handleAddColumn}
|
|
195
|
+
disabled={saving || !newValueLabel.trim()}
|
|
196
|
+
>
|
|
197
|
+
{saving ? "Adding..." : "Add Column"}
|
|
198
|
+
</Button>
|
|
199
|
+
</DialogActions>
|
|
200
|
+
</Dialog>
|
|
201
|
+
</>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CollectionActionsProps, useAuthController, useNavigationController } from "@firecms/core";
|
|
1
|
+
import { CollectionActionsProps, useAuthController, useNavigationController, useTranslation } from "@firecms/core";
|
|
2
2
|
import { IconButton, SettingsIcon, Tooltip, } from "@firecms/ui";
|
|
3
3
|
|
|
4
4
|
import { useCollectionEditorController } from "../useCollectionEditorController";
|
|
@@ -16,7 +16,7 @@ export function EditorCollectionAction({
|
|
|
16
16
|
const collectionEditorController = useCollectionEditorController();
|
|
17
17
|
|
|
18
18
|
const parentCollection = navigationController.getCollectionFromIds(parentCollectionIds);
|
|
19
|
-
|
|
19
|
+
const { t } = useTranslation();
|
|
20
20
|
const canEditCollection = collectionEditorController.configPermissions
|
|
21
21
|
? collectionEditorController.configPermissions({
|
|
22
22
|
user: authController.user,
|
|
@@ -26,7 +26,7 @@ export function EditorCollectionAction({
|
|
|
26
26
|
|
|
27
27
|
const editorButton = <Tooltip
|
|
28
28
|
asChild={true}
|
|
29
|
-
title={canEditCollection ? "
|
|
29
|
+
title={canEditCollection ? t("edit_collection") : t("no_permissions_edit_collection")}>
|
|
30
30
|
<IconButton
|
|
31
31
|
size={"small"}
|
|
32
32
|
color={"primary"}
|
|
@@ -35,7 +35,7 @@ export function EditorCollectionActionStart({
|
|
|
35
35
|
title={tableController.sortBy || tableController.filterValues ? "Save default filter and sort" : "Clear default filter and sort"}>
|
|
36
36
|
<Button
|
|
37
37
|
size={"small"}
|
|
38
|
-
variant={"
|
|
38
|
+
variant={"text"}
|
|
39
39
|
onClick={() => configController
|
|
40
40
|
?.saveCollection({
|
|
41
41
|
id: collection.id,
|
|
@@ -58,7 +58,6 @@ export function EditorCollectionActionStart({
|
|
|
58
58
|
{(collection.initialFilter || collection.initialSort) && <Tooltip
|
|
59
59
|
title={"Reset to default filter and sort"}>
|
|
60
60
|
<Button
|
|
61
|
-
color={"primary"}
|
|
62
61
|
size={"small"}
|
|
63
62
|
variant={"text"}
|
|
64
63
|
onClick={() => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PluginFormActionProps, useAuthController, useNavigationController } from "@firecms/core";
|
|
1
|
+
import { PluginFormActionProps, useAuthController, useNavigationController, useTranslation } from "@firecms/core";
|
|
2
2
|
import { IconButton, SettingsIcon, Tooltip, } from "@firecms/ui";
|
|
3
3
|
|
|
4
4
|
import { useCollectionEditorController } from "../useCollectionEditorController";
|
|
@@ -14,6 +14,7 @@ export function EditorEntityAction({
|
|
|
14
14
|
const authController = useAuthController();
|
|
15
15
|
const navigationController = useNavigationController();
|
|
16
16
|
const collectionEditorController = useCollectionEditorController();
|
|
17
|
+
const { t } = useTranslation();
|
|
17
18
|
|
|
18
19
|
const parentCollection = navigationController.getCollectionFromIds(parentCollectionIds);
|
|
19
20
|
|
|
@@ -28,7 +29,7 @@ export function EditorEntityAction({
|
|
|
28
29
|
|
|
29
30
|
const editorButton = <Tooltip
|
|
30
31
|
asChild={true}
|
|
31
|
-
title={canEditCollection ? (isDirty ? "
|
|
32
|
+
title={canEditCollection ? (isDirty ? t("save_before_changing_schema") : t("edit_schema_for_this_form")) : t("no_permissions_to_edit_collection")}>
|
|
32
33
|
<IconButton
|
|
33
34
|
color={"primary"}
|
|
34
35
|
disabled={!canEditCollection || isDirty}
|
|
@@ -4,26 +4,31 @@ import {
|
|
|
4
4
|
useAuthController,
|
|
5
5
|
useSnackbarController
|
|
6
6
|
} from "@firecms/core";
|
|
7
|
-
import { DeleteIcon, IconButton, Menu, MenuItem, MoreVertIcon, SettingsIcon, } from "@firecms/ui";
|
|
7
|
+
import { ContentCopyIcon, DeleteIcon, IconButton, Menu, MenuItem, MoreVertIcon, SettingsIcon, } from "@firecms/ui";
|
|
8
8
|
import { useCollectionEditorController } from "../useCollectionEditorController";
|
|
9
9
|
import { useState } from "react";
|
|
10
10
|
import { useCollectionsConfigController } from "../useCollectionsConfigController";
|
|
11
11
|
|
|
12
12
|
export function HomePageEditorCollectionAction({
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
path,
|
|
14
|
+
collection
|
|
15
|
+
}: PluginHomePageActionsProps) {
|
|
17
16
|
|
|
18
17
|
const snackbarController = useSnackbarController();
|
|
19
18
|
const authController = useAuthController();
|
|
20
19
|
const configController = useCollectionsConfigController();
|
|
21
20
|
const collectionEditorController = useCollectionEditorController();
|
|
22
21
|
|
|
23
|
-
const permissions = collectionEditorController
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
const permissions = collectionEditorController?.configPermissions
|
|
23
|
+
? collectionEditorController.configPermissions({
|
|
24
|
+
user: authController.user,
|
|
25
|
+
collection
|
|
26
|
+
})
|
|
27
|
+
: {
|
|
28
|
+
createCollections: false,
|
|
29
|
+
editCollections: false,
|
|
30
|
+
deleteCollections: false
|
|
31
|
+
};
|
|
27
32
|
|
|
28
33
|
const onEditCollectionClicked = () => {
|
|
29
34
|
collectionEditorController?.editCollection({
|
|
@@ -32,6 +37,17 @@ export function HomePageEditorCollectionAction({
|
|
|
32
37
|
});
|
|
33
38
|
};
|
|
34
39
|
|
|
40
|
+
const onDuplicateCollectionClicked = () => {
|
|
41
|
+
// Use copyFrom to duplicate the collection with all properties
|
|
42
|
+
// The editor will handle clearing name, path, and id
|
|
43
|
+
collectionEditorController?.createCollection({
|
|
44
|
+
copyFrom: collection,
|
|
45
|
+
parentCollectionIds: [],
|
|
46
|
+
redirect: true,
|
|
47
|
+
sourceClick: "home_page_duplicate"
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
|
|
35
51
|
const [deleteRequested, setDeleteRequested] = useState(false);
|
|
36
52
|
|
|
37
53
|
const deleteCollection = () => {
|
|
@@ -50,9 +66,21 @@ export function HomePageEditorCollectionAction({
|
|
|
50
66
|
{permissions.deleteCollections &&
|
|
51
67
|
<Menu
|
|
52
68
|
trigger={<IconButton size={"small"}>
|
|
53
|
-
<MoreVertIcon size={"small"}/>
|
|
69
|
+
<MoreVertIcon size={"small"} />
|
|
54
70
|
</IconButton>}
|
|
55
71
|
>
|
|
72
|
+
{permissions.createCollections &&
|
|
73
|
+
<MenuItem
|
|
74
|
+
dense={true}
|
|
75
|
+
onClick={(event) => {
|
|
76
|
+
event.preventDefault();
|
|
77
|
+
event.stopPropagation();
|
|
78
|
+
onDuplicateCollectionClicked();
|
|
79
|
+
}}>
|
|
80
|
+
<ContentCopyIcon />
|
|
81
|
+
Duplicate
|
|
82
|
+
</MenuItem>
|
|
83
|
+
}
|
|
56
84
|
<MenuItem
|
|
57
85
|
dense={true}
|
|
58
86
|
onClick={(event) => {
|
|
@@ -60,7 +88,7 @@ export function HomePageEditorCollectionAction({
|
|
|
60
88
|
event.stopPropagation();
|
|
61
89
|
setDeleteRequested(true);
|
|
62
90
|
}}>
|
|
63
|
-
<DeleteIcon/>
|
|
91
|
+
<DeleteIcon />
|
|
64
92
|
Delete
|
|
65
93
|
</MenuItem>
|
|
66
94
|
|
|
@@ -74,7 +102,7 @@ export function HomePageEditorCollectionAction({
|
|
|
74
102
|
onClick={(event) => {
|
|
75
103
|
onEditCollectionClicked();
|
|
76
104
|
}}>
|
|
77
|
-
<SettingsIcon size={"small"}/>
|
|
105
|
+
<SettingsIcon size={"small"} />
|
|
78
106
|
</IconButton>}
|
|
79
107
|
</div>
|
|
80
108
|
|
|
@@ -85,7 +113,7 @@ export function HomePageEditorCollectionAction({
|
|
|
85
113
|
title={<>Delete this collection?</>}
|
|
86
114
|
body={<> This will <b>not
|
|
87
115
|
delete any data</b>, only
|
|
88
|
-
the collection in the CMS</>}/>
|
|
116
|
+
the collection in the CMS</>} />
|
|
89
117
|
</>;
|
|
90
118
|
|
|
91
119
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { EntityCollection, useNavigationController } from "@firecms/core";
|
|
3
|
+
import { Button } from "@firecms/ui";
|
|
4
|
+
import { useCollectionEditorController } from "../useCollectionEditorController";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Component rendered when Kanban view is missing orderProperty configuration.
|
|
8
|
+
* Provides a CTA button to open the collection editor to configure Kanban.
|
|
9
|
+
*/
|
|
10
|
+
export function KanbanSetupAction({
|
|
11
|
+
collection,
|
|
12
|
+
fullPath,
|
|
13
|
+
parentCollectionIds
|
|
14
|
+
}: {
|
|
15
|
+
collection: EntityCollection;
|
|
16
|
+
fullPath: string;
|
|
17
|
+
parentCollectionIds: string[];
|
|
18
|
+
}) {
|
|
19
|
+
const collectionEditorController = useCollectionEditorController();
|
|
20
|
+
|
|
21
|
+
const handleConfigureClick = () => {
|
|
22
|
+
collectionEditorController.editCollection({
|
|
23
|
+
id: collection.id,
|
|
24
|
+
parentCollectionIds,
|
|
25
|
+
initialView: "display",
|
|
26
|
+
expandKanban: true
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<Button
|
|
32
|
+
variant="outlined"
|
|
33
|
+
onClick={handleConfigureClick}
|
|
34
|
+
>
|
|
35
|
+
Configure Kanban
|
|
36
|
+
</Button>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -11,7 +11,7 @@ export function MissingReferenceWidget({ path: pathProp }: {
|
|
|
11
11
|
const collectionEditor = useCollectionEditorController();
|
|
12
12
|
return <div className={"p-1 flex flex-col items-center"}>
|
|
13
13
|
<ErrorView error={"No collection for path: " + path}/>
|
|
14
|
-
<Button className={"mx-2"}
|
|
14
|
+
<Button className={"mx-2"}
|
|
15
15
|
size={"small"}
|
|
16
16
|
onClick={() => {
|
|
17
17
|
collectionEditor.createCollection({
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import { AddIcon, Button } from "@firecms/ui";
|
|
2
|
+
import { useTranslation } from "@firecms/core";
|
|
2
3
|
import { useCollectionEditorController } from "../useCollectionEditorController";
|
|
3
4
|
|
|
4
5
|
export function NewCollectionButton() {
|
|
6
|
+
const { t } = useTranslation();
|
|
5
7
|
const collectionEditorController = useCollectionEditorController();
|
|
6
8
|
return <div className={"bg-surface-50 dark:bg-surface-900 min-w-fit rounded"}>
|
|
7
9
|
<Button className={"min-w-fit"}
|
|
8
|
-
|
|
10
|
+
|
|
9
11
|
onClick={() => collectionEditorController.createCollection({
|
|
10
12
|
parentCollectionIds: [],
|
|
11
13
|
redirect: true,
|
|
12
14
|
sourceClick: "new_collection_button"
|
|
13
15
|
})}>
|
|
14
16
|
<AddIcon/>
|
|
15
|
-
|
|
17
|
+
{t("new_collection")}
|
|
16
18
|
</Button>
|
|
17
19
|
</div>
|
|
18
20
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PluginHomePageAdditionalCardsProps, useAuthController } from "@firecms/core";
|
|
1
|
+
import { PluginHomePageAdditionalCardsProps, useAuthController, useTranslation } from "@firecms/core";
|
|
2
2
|
import { AddIcon, Card, cls, Typography } from "@firecms/ui";
|
|
3
3
|
import { useCollectionEditorController } from "../useCollectionEditorController";
|
|
4
4
|
|
|
@@ -12,6 +12,8 @@ export function NewCollectionCard({
|
|
|
12
12
|
|
|
13
13
|
const authController = useAuthController();
|
|
14
14
|
|
|
15
|
+
const { t } = useTranslation();
|
|
16
|
+
|
|
15
17
|
const collectionEditorController = useCollectionEditorController();
|
|
16
18
|
const canCreateCollections = collectionEditorController.configPermissions
|
|
17
19
|
? collectionEditorController.configPermissions({
|
|
@@ -35,11 +37,12 @@ export function NewCollectionCard({
|
|
|
35
37
|
<AddIcon color="primary" size={"large"}/>
|
|
36
38
|
<Typography color="primary"
|
|
37
39
|
variant={"caption"}
|
|
38
|
-
className={"font-medium"}>{"
|
|
40
|
+
className={"font-medium"}>{t("add_new_collection").toUpperCase()}</Typography>
|
|
39
41
|
|
|
40
42
|
{!canCreateCollections &&
|
|
41
|
-
<Typography variant={"caption"}>
|
|
42
|
-
|
|
43
|
+
<Typography variant={"caption"}>
|
|
44
|
+
{t("no_permissions_create_collection")}
|
|
45
|
+
</Typography>
|
|
43
46
|
}
|
|
44
47
|
</div>
|
|
45
48
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EntityTableController, getDefaultPropertiesOrder, useAuthController } from "@firecms/core";
|
|
1
|
+
import { EntityTableController, getDefaultPropertiesOrder, useAuthController, useTranslation } 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";
|
|
@@ -17,6 +17,7 @@ export function PropertyAddColumnComponent({
|
|
|
17
17
|
|
|
18
18
|
const authController = useAuthController();
|
|
19
19
|
const collectionEditorController = useCollectionEditorController();
|
|
20
|
+
const { t } = useTranslation();
|
|
20
21
|
const canEditCollection = collectionEditorController.configPermissions
|
|
21
22
|
? collectionEditorController.configPermissions({
|
|
22
23
|
user: authController.user,
|
|
@@ -27,9 +28,9 @@ export function PropertyAddColumnComponent({
|
|
|
27
28
|
return (
|
|
28
29
|
<Tooltip
|
|
29
30
|
asChild={true}
|
|
30
|
-
title={canEditCollection ? "
|
|
31
|
+
title={canEditCollection ? t("add_new_property") : t("no_permission_add_properties")}>
|
|
31
32
|
<div
|
|
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={"p-0.5 w-20 h-full flex items-center justify-center cursor-pointer bg-surface-100 bg-opacity-40 bg-surface-100/40 hover:bg-surface-100 dark:bg-surface-950 dark:bg-opacity-40 dark:bg-surface-950/40 dark:hover:bg-surface-950"}
|
|
33
34
|
// className={onHover ? "bg-white dark:bg-surface-950" : undefined}
|
|
34
35
|
onClick={() => {
|
|
35
36
|
collectionEditorController.editProperty({
|