@firecms/core 3.0.0-beta.8 → 3.0.0-beta.9
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/app/Drawer.d.ts +1 -1
- package/dist/app/Scaffold.d.ts +1 -1
- package/dist/components/ArrayContainer.d.ts +2 -1
- package/dist/components/CircularProgressCenter.d.ts +1 -1
- package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +0 -1
- package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +1 -1
- package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +1 -1
- package/dist/components/EntityPreview.d.ts +1 -1
- package/dist/components/ErrorView.d.ts +1 -1
- package/dist/components/HomePage/DefaultHomePage.d.ts +1 -1
- package/dist/components/HomePage/NavigationCardBinding.d.ts +1 -1
- package/dist/components/PropertyIdCopyTooltip.d.ts +8 -0
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +10 -6
- package/dist/components/common/useColumnsIds.d.ts +2 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/core/DefaultAppBar.d.ts +1 -1
- package/dist/core/DefaultDrawer.d.ts +1 -1
- package/dist/core/DrawerNavigationItem.d.ts +2 -1
- package/dist/core/EntityEditView.d.ts +3 -3
- package/dist/core/FireCMS.d.ts +1 -1
- package/dist/core/NavigationRoutes.d.ts +1 -1
- package/dist/form/PropertyFieldBinding.d.ts +1 -1
- package/dist/form/components/FormikArrayContainer.d.ts +2 -1
- package/dist/form/components/LabelWithIcon.d.ts +1 -1
- package/dist/form/components/LabelWithIconAndTooltip.d.ts +15 -0
- package/dist/form/components/index.d.ts +1 -0
- package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +11 -0
- package/dist/form/field_bindings/{MultiSelectBinding.d.ts → MultiSelectFieldBinding.d.ts} +1 -1
- package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/SelectFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/TextFieldBinding.d.ts +1 -1
- package/dist/form/index.d.ts +3 -3
- package/dist/form/useClearRestoreValue.d.ts +2 -2
- package/dist/hooks/useProjectLog.d.ts +2 -2
- package/dist/index.es.js +14127 -11014
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +19987 -587
- package/dist/index.umd.js.map +1 -1
- package/dist/preview/PropertyPreviewProps.d.ts +1 -1
- package/dist/preview/components/EnumValuesChip.d.ts +1 -1
- package/dist/preview/components/ReferencePreview.d.ts +1 -1
- package/dist/types/auth.d.ts +1 -1
- package/dist/types/collections.d.ts +12 -3
- package/dist/types/datasource.d.ts +35 -22
- package/dist/types/entities.d.ts +1 -0
- package/dist/types/entity_overrides.d.ts +2 -2
- package/dist/types/fields.d.ts +20 -15
- package/dist/types/navigation.d.ts +1 -0
- package/dist/types/properties.d.ts +18 -18
- package/dist/types/side_dialogs_controller.d.ts +10 -0
- package/dist/types/storage.d.ts +75 -0
- package/dist/util/entities.d.ts +1 -1
- package/dist/util/icon_list.d.ts +5 -1
- package/dist/util/icons.d.ts +1 -0
- package/dist/util/index.d.ts +1 -0
- package/dist/util/plurals.d.ts +0 -2
- package/dist/util/property_utils.d.ts +1 -1
- package/dist/util/resolutions.d.ts +15 -1
- package/dist/util/storage.d.ts +1 -1
- package/dist/util/useStorageUploadController.d.ts +2 -2
- package/package.json +15 -17
- package/src/app/Drawer.tsx +1 -1
- package/src/app/Scaffold.tsx +22 -27
- package/src/components/ArrayContainer.tsx +15 -10
- package/src/components/CircularProgressCenter.tsx +1 -1
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +4 -9
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +2 -2
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +4 -2
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +21 -14
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +12 -4
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +17 -19
- package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +19 -7
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +3 -5
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +26 -25
- package/src/components/EntityCollectionView/useSelectionController.tsx +19 -7
- package/src/components/EntityPreview.tsx +30 -31
- package/src/components/ErrorView.tsx +1 -1
- package/src/components/HomePage/DefaultHomePage.tsx +24 -18
- package/src/components/HomePage/NavigationCardBinding.tsx +1 -1
- package/src/components/HomePage/SmallNavigationCard.tsx +1 -2
- package/src/components/PropertyIdCopyTooltip.tsx +48 -0
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +7 -6
- package/src/components/SearchIconsView.tsx +5 -2
- package/src/components/SelectableTable/SelectableTable.tsx +2 -4
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +1 -1
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +54 -7
- package/src/components/VirtualTable/VirtualTable.tsx +33 -9
- package/src/components/VirtualTable/VirtualTableCell.tsx +1 -9
- package/src/components/VirtualTable/VirtualTableProps.tsx +12 -8
- package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +3 -3
- package/src/components/VirtualTable/fields/VirtualTableInput.tsx +2 -1
- package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +2 -1
- package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +14 -28
- package/src/components/common/useColumnsIds.tsx +13 -0
- package/src/components/common/useDataSourceEntityCollectionTableController.tsx +12 -12
- package/src/components/common/useTableSearchHelper.ts +1 -0
- package/src/components/index.tsx +1 -0
- package/src/core/DefaultAppBar.tsx +3 -3
- package/src/core/DefaultDrawer.tsx +18 -12
- package/src/core/DrawerNavigationItem.tsx +31 -27
- package/src/core/EntityEditView.tsx +136 -109
- package/src/core/FireCMS.tsx +2 -2
- package/src/core/NavigationRoutes.tsx +1 -1
- package/src/core/SideDialogs.tsx +1 -0
- package/src/core/field_configs.tsx +5 -5
- package/src/form/PropertyFieldBinding.tsx +24 -14
- package/src/form/components/CustomIdField.tsx +4 -2
- package/src/form/components/FieldHelperText.tsx +1 -1
- package/src/form/components/FormikArrayContainer.tsx +4 -1
- package/src/form/components/LabelWithIcon.tsx +27 -19
- package/src/form/components/LabelWithIconAndTooltip.tsx +28 -0
- package/src/form/components/StorageItemPreview.tsx +1 -0
- package/src/form/components/StorageUploadProgress.tsx +0 -1
- package/src/form/components/index.tsx +1 -0
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +22 -14
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +24 -22
- package/src/form/field_bindings/BlockFieldBinding.tsx +13 -11
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +17 -14
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +8 -7
- package/src/form/field_bindings/MapFieldBinding.tsx +16 -24
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +150 -0
- package/src/form/field_bindings/{MultiSelectBinding.tsx → MultiSelectFieldBinding.tsx} +25 -20
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +9 -7
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +27 -18
- package/src/form/field_bindings/RepeatFieldBinding.tsx +27 -17
- package/src/form/field_bindings/SelectFieldBinding.tsx +17 -10
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +36 -17
- package/src/form/field_bindings/SwitchFieldBinding.tsx +9 -5
- package/src/form/field_bindings/TextFieldBinding.tsx +26 -23
- package/src/form/index.tsx +4 -9
- package/src/form/useClearRestoreValue.tsx +2 -2
- package/src/hooks/data/delete.ts +2 -1
- package/src/hooks/data/save.ts +5 -2
- package/src/hooks/data/useDataSource.tsx +11 -3
- package/src/hooks/useBuildNavigationController.tsx +10 -3
- package/src/hooks/useProjectLog.tsx +18 -7
- package/src/internal/useBuildDataSource.ts +59 -76
- package/src/internal/useBuildSideDialogsController.tsx +1 -0
- package/src/internal/useBuildSideEntityController.tsx +17 -4
- package/src/internal/useUnsavedChangesDialog.tsx +3 -1
- package/src/preview/PropertyPreview.tsx +2 -2
- package/src/preview/PropertyPreviewProps.tsx +1 -1
- package/src/preview/components/BooleanPreview.tsx +1 -1
- package/src/preview/components/EnumValuesChip.tsx +1 -1
- package/src/preview/components/ImagePreview.tsx +4 -2
- package/src/preview/components/ReferencePreview.tsx +2 -13
- package/src/preview/components/UrlComponentPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -2
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +1 -1
- package/src/preview/property_previews/MapPropertyPreview.tsx +1 -1
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +2 -2
- package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
- package/src/preview/util.ts +2 -2
- package/src/types/auth.tsx +1 -1
- package/src/types/collections.ts +15 -4
- package/src/types/datasource.ts +42 -27
- package/src/types/entities.ts +2 -0
- package/src/types/entity_overrides.tsx +2 -2
- package/src/types/fields.tsx +23 -17
- package/src/types/navigation.ts +1 -0
- package/src/types/properties.ts +18 -17
- package/src/types/side_dialogs_controller.tsx +13 -0
- package/src/types/storage.ts +82 -0
- package/src/util/entities.ts +1 -1
- package/src/util/icon_list.ts +14 -9
- package/src/util/icons.tsx +8 -2
- package/src/util/index.ts +1 -0
- package/src/util/plurals.ts +0 -2
- package/src/util/property_utils.tsx +1 -1
- package/src/util/references.ts +3 -0
- package/src/util/resolutions.ts +43 -11
- package/src/util/storage.ts +6 -2
- package/src/util/useStorageUploadController.tsx +15 -7
- package/dist/components/PropertyIdCopyTooltipContent.d.ts +0 -3
- package/dist/form/PropertiesForm.d.ts +0 -8
- package/dist/form/field_bindings/MarkdownFieldBinding.d.ts +0 -9
- package/src/components/PropertyIdCopyTooltipContent.tsx +0 -27
- package/src/form/PropertiesForm.tsx +0 -81
- package/src/form/field_bindings/MarkdownFieldBinding.tsx +0 -695
|
@@ -7,6 +7,7 @@ export function DrawerNavigationItem({
|
|
|
7
7
|
name,
|
|
8
8
|
icon,
|
|
9
9
|
drawerOpen,
|
|
10
|
+
adminMenuOpen,
|
|
10
11
|
tooltipsOpen,
|
|
11
12
|
url,
|
|
12
13
|
onClick
|
|
@@ -15,6 +16,7 @@ export function DrawerNavigationItem({
|
|
|
15
16
|
name: string,
|
|
16
17
|
tooltipsOpen: boolean,
|
|
17
18
|
drawerOpen: boolean,
|
|
19
|
+
adminMenuOpen?: boolean,
|
|
18
20
|
url: string,
|
|
19
21
|
onClick?: () => void,
|
|
20
22
|
}) {
|
|
@@ -24,37 +26,39 @@ export function DrawerNavigationItem({
|
|
|
24
26
|
{icon}
|
|
25
27
|
</div>;
|
|
26
28
|
|
|
27
|
-
const listItem = <
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
29
|
+
const listItem = <div>
|
|
30
|
+
<NavLink
|
|
31
|
+
onClick={onClick}
|
|
32
|
+
style={{
|
|
33
|
+
width: "100%",
|
|
34
|
+
transition: drawerOpen ? "width 150ms ease-in" : undefined
|
|
35
|
+
}}
|
|
36
|
+
className={({ isActive }: any) => cls("rounded-lg truncate",
|
|
37
|
+
"hover:bg-slate-300 hover:bg-opacity-75 dark:hover:bg-slate-800 dark:hover:bg-opacity-75 text-gray-800 dark:text-gray-200 hover:text-gray-900 hover:dark:text-white",
|
|
38
|
+
"flex flex-row items-center mr-8",
|
|
39
|
+
// "transition-all ease-in-out delay-100 duration-300",
|
|
40
|
+
// drawerOpen ? "w-full" : "w-18",
|
|
41
|
+
drawerOpen ? "pl-4 h-12" : "pl-4 h-11",
|
|
42
|
+
"font-medium text-sm",
|
|
43
|
+
isActive ? "bg-slate-200 bg-opacity-60 dark:bg-gray-800 dark:bg-opacity-50" : ""
|
|
44
|
+
)}
|
|
45
|
+
to={url}
|
|
46
|
+
>
|
|
44
47
|
|
|
45
|
-
|
|
48
|
+
{iconWrap}
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
<div
|
|
51
|
+
className={cls(
|
|
52
|
+
drawerOpen ? "opacity-100" : "opacity-0 hidden",
|
|
53
|
+
"ml-4 font-inherit text-inherit"
|
|
54
|
+
)}>
|
|
55
|
+
{name.toUpperCase()}
|
|
56
|
+
</div>
|
|
57
|
+
</NavLink>
|
|
58
|
+
</div>;
|
|
55
59
|
|
|
56
60
|
return <Tooltip
|
|
57
|
-
open={drawerOpen ? false : tooltipsOpen}
|
|
61
|
+
open={drawerOpen || adminMenuOpen ? false : tooltipsOpen}
|
|
58
62
|
side="right"
|
|
59
63
|
title={name}>
|
|
60
64
|
{listItem}
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
EntityCollectionView,
|
|
24
24
|
EntityView,
|
|
25
25
|
ErrorBoundary,
|
|
26
|
+
getFormFieldKeys,
|
|
26
27
|
} from "../components";
|
|
27
28
|
import {
|
|
28
29
|
canCreateEntity,
|
|
@@ -59,9 +60,10 @@ import {
|
|
|
59
60
|
defaultBorderMixin,
|
|
60
61
|
DialogActions,
|
|
61
62
|
IconButton,
|
|
63
|
+
NotesIcon,
|
|
64
|
+
paperMixin,
|
|
62
65
|
Tab,
|
|
63
66
|
Tabs,
|
|
64
|
-
Tooltip,
|
|
65
67
|
Typography
|
|
66
68
|
} from "@firecms/ui";
|
|
67
69
|
import { useSideDialogContext } from "./index";
|
|
@@ -70,8 +72,7 @@ import { useAnalyticsController } from "../hooks/useAnalyticsController";
|
|
|
70
72
|
import { CustomIdField } from "../form/components/CustomIdField";
|
|
71
73
|
import { CustomFieldValidator, getYupEntitySchema } from "../form/validation";
|
|
72
74
|
import { ErrorFocus } from "../form/components/ErrorFocus";
|
|
73
|
-
import {
|
|
74
|
-
import { PropertyFieldBinding } from "../form";
|
|
75
|
+
import { LabelWithIconAndTooltip, PropertyFieldBinding } from "../form";
|
|
75
76
|
import { ValidationError } from "yup";
|
|
76
77
|
|
|
77
78
|
const MAIN_TAB_VALUE = "main_##Q$SC^#S6";
|
|
@@ -92,10 +93,10 @@ export interface EntityEditViewProps<M extends Record<string, any>> {
|
|
|
92
93
|
* This is the default view that is used as the content of a side panel when
|
|
93
94
|
* an entity is opened.
|
|
94
95
|
* You probably don't want to use this view directly since it is bound to the
|
|
95
|
-
* side panel.
|
|
96
|
+
* side panel.
|
|
96
97
|
*/
|
|
97
98
|
export function EntityEditView<M extends Record<string, any>, UserType extends User>({
|
|
98
|
-
entityId
|
|
99
|
+
entityId,
|
|
99
100
|
...props
|
|
100
101
|
}: EntityEditViewProps<M>) {
|
|
101
102
|
const {
|
|
@@ -105,7 +106,7 @@ export function EntityEditView<M extends Record<string, any>, UserType extends U
|
|
|
105
106
|
dataLoadingError
|
|
106
107
|
} = useEntityFetch<M, UserType>({
|
|
107
108
|
path: props.path,
|
|
108
|
-
entityId:
|
|
109
|
+
entityId: entityId,
|
|
109
110
|
collection: props.collection,
|
|
110
111
|
useCache: false
|
|
111
112
|
});
|
|
@@ -114,8 +115,12 @@ export function EntityEditView<M extends Record<string, any>, UserType extends U
|
|
|
114
115
|
return <CircularProgressCenter/>
|
|
115
116
|
}
|
|
116
117
|
|
|
118
|
+
if (entityId && !entity) {
|
|
119
|
+
console.error(`Entity with id ${entityId} not found in collection ${props.collection.path}`);
|
|
120
|
+
}
|
|
121
|
+
|
|
117
122
|
return <EntityEditViewInner<M> {...props}
|
|
118
|
-
entityId={
|
|
123
|
+
entityId={entityId}
|
|
119
124
|
entity={entity}
|
|
120
125
|
dataLoading={dataLoading}/>;
|
|
121
126
|
}
|
|
@@ -131,7 +136,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
131
136
|
onUpdate,
|
|
132
137
|
onClose,
|
|
133
138
|
entity,
|
|
134
|
-
dataLoading
|
|
139
|
+
dataLoading
|
|
135
140
|
}: EntityEditViewProps<M> & {
|
|
136
141
|
entity?: Entity<M>,
|
|
137
142
|
dataLoading: boolean
|
|
@@ -185,14 +190,16 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
185
190
|
|
|
186
191
|
const initialStatus = copy ? "copy" : (entityIdProp ? "existing" : "new");
|
|
187
192
|
const [status, setStatus] = useState<EntityStatus>(initialStatus);
|
|
193
|
+
|
|
188
194
|
const mustSetCustomId: boolean = (status === "new" || status === "copy") &&
|
|
189
195
|
(Boolean(initialResolvedCollection.customId) && initialResolvedCollection.customId !== "optional");
|
|
196
|
+
|
|
190
197
|
const initialEntityId: string | undefined = useMemo((): string | undefined => {
|
|
191
198
|
if (status === "new" || status === "copy") {
|
|
192
199
|
if (mustSetCustomId) {
|
|
193
200
|
return undefined;
|
|
194
201
|
} else {
|
|
195
|
-
return dataSource.generateEntityId(path);
|
|
202
|
+
return dataSource.generateEntityId(path, collection);
|
|
196
203
|
}
|
|
197
204
|
} else {
|
|
198
205
|
return entityIdProp;
|
|
@@ -224,16 +231,9 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
224
231
|
}
|
|
225
232
|
);
|
|
226
233
|
|
|
227
|
-
const
|
|
228
|
-
const baseDataSourceValuesRef = useRef<Partial<EntityValues<M>>>(getDataSourceEntityValues(initialResolvedCollection, status, entity));
|
|
229
|
-
|
|
230
|
-
const mainViewVisible = selectedTabRef.current === MAIN_TAB_VALUE;
|
|
234
|
+
const [selectedTab, setSelectedTab] = useState<string>(defaultSelectedView ?? MAIN_TAB_VALUE);
|
|
231
235
|
|
|
232
|
-
|
|
233
|
-
// const [internalValues, setInternalValues] = useState<EntityValues<M> | undefined>(entity?.values ?? baseDataSourceValuesRef.current as EntityValues<M>);
|
|
234
|
-
|
|
235
|
-
// const modifiedValuesRef = useRef<EntityValues<M> | undefined>(undefined);
|
|
236
|
-
// const modifiedValues = modifiedValuesRef.current;
|
|
236
|
+
const mainViewVisible = selectedTab === MAIN_TAB_VALUE;
|
|
237
237
|
|
|
238
238
|
const subcollections = (collection.subcollections ?? []).filter(c => !c.hideFromNavigation);
|
|
239
239
|
const subcollectionsCount = subcollections?.length ?? 0;
|
|
@@ -246,6 +246,8 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
246
246
|
const [usedEntity, setUsedEntity] = useState<Entity<M> | undefined>(entity);
|
|
247
247
|
const [readOnly, setReadOnly] = useState<boolean | undefined>(undefined);
|
|
248
248
|
|
|
249
|
+
const baseDataSourceValuesRef = useRef<Partial<EntityValues<M>>>(getDataSourceEntityValues(initialResolvedCollection, status, usedEntity));
|
|
250
|
+
|
|
249
251
|
useEffect(() => {
|
|
250
252
|
if (entity)
|
|
251
253
|
setUsedEntity(entity);
|
|
@@ -297,7 +299,6 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
297
299
|
onUpdate({ entity: updatedEntity });
|
|
298
300
|
|
|
299
301
|
if (closeAfterSave) {
|
|
300
|
-
console.log("Closing side dialog")
|
|
301
302
|
sideDialogContext.setBlocked(false);
|
|
302
303
|
sideDialogContext.close(true);
|
|
303
304
|
onClose?.();
|
|
@@ -305,7 +306,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
305
306
|
sideEntityController.replace({
|
|
306
307
|
path,
|
|
307
308
|
entityId: updatedEntity.id,
|
|
308
|
-
selectedSubPath:
|
|
309
|
+
selectedSubPath: MAIN_TAB_VALUE === selectedTab ? undefined : selectedTab,
|
|
309
310
|
updateUrl: true,
|
|
310
311
|
collection,
|
|
311
312
|
});
|
|
@@ -478,7 +479,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
478
479
|
setFieldValue: useCallback(formex.setFieldValue, []),
|
|
479
480
|
values: formex.values,
|
|
480
481
|
collection: resolvedCollection,
|
|
481
|
-
entityId,
|
|
482
|
+
entityId: entityId as string,
|
|
482
483
|
path,
|
|
483
484
|
save,
|
|
484
485
|
formex
|
|
@@ -489,15 +490,15 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
489
490
|
.filter(Boolean) as EntityCustomView[]
|
|
490
491
|
: [];
|
|
491
492
|
|
|
492
|
-
const selectedEntityView = resolvedEntityViews.find(e => e.key ===
|
|
493
|
-
const shouldShowEntityActions = !autoSave && (
|
|
493
|
+
const selectedEntityView = resolvedEntityViews.find(e => e.key === selectedTab);
|
|
494
|
+
const shouldShowEntityActions = !autoSave && (selectedTab === MAIN_TAB_VALUE || selectedEntityView?.includeActions);
|
|
494
495
|
|
|
495
496
|
const customViewsView: React.ReactNode[] | undefined = customViews && resolvedEntityViews
|
|
496
497
|
.map(
|
|
497
498
|
(customView, colIndex) => {
|
|
498
499
|
if (!customView)
|
|
499
500
|
return null;
|
|
500
|
-
if (
|
|
501
|
+
if (selectedTab !== customView.key)
|
|
501
502
|
return null;
|
|
502
503
|
const Builder = customView.Builder;
|
|
503
504
|
if (!Builder) {
|
|
@@ -530,7 +531,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
530
531
|
(subcollection, colIndex) => {
|
|
531
532
|
const subcollectionId = subcollection.id ?? subcollection.path;
|
|
532
533
|
const fullPath = usedEntity ? `${path}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollectionId)}` : undefined;
|
|
533
|
-
if (
|
|
534
|
+
if (selectedTab !== subcollectionId)
|
|
534
535
|
return null;
|
|
535
536
|
return (
|
|
536
537
|
<div
|
|
@@ -566,21 +567,18 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
566
567
|
}, []);
|
|
567
568
|
|
|
568
569
|
const onSideTabClick = (value: string) => {
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
570
|
+
setSelectedTab(value);
|
|
571
|
+
if (status === "existing") {
|
|
572
|
+
sideEntityController.replace({
|
|
573
|
+
path,
|
|
574
|
+
entityId,
|
|
575
|
+
selectedSubPath: value === MAIN_TAB_VALUE ? undefined : value,
|
|
576
|
+
updateUrl: true,
|
|
577
|
+
collection,
|
|
578
|
+
});
|
|
579
|
+
}
|
|
577
580
|
};
|
|
578
581
|
|
|
579
|
-
// const onValuesChanged = useCallback((values?: EntityValues<M>) => {
|
|
580
|
-
// modifiedValuesRef.current = values;
|
|
581
|
-
// }, []);
|
|
582
|
-
|
|
583
|
-
// eslint-disable-next-line n/handle-callback-err
|
|
584
582
|
const onIdUpdateError = useCallback((error: any) => {
|
|
585
583
|
snackbarController.open({
|
|
586
584
|
type: "error",
|
|
@@ -678,7 +676,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
678
676
|
name,
|
|
679
677
|
value,
|
|
680
678
|
property
|
|
681
|
-
}) => dataSource.checkUniqueField(path, name, value, entityId),
|
|
679
|
+
}) => dataSource.checkUniqueField(path, name, value, entityId, collection),
|
|
682
680
|
[dataSource, path, entityId]);
|
|
683
681
|
|
|
684
682
|
const validationSchema = useMemo(() => entityId
|
|
@@ -735,50 +733,76 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
735
733
|
|
|
736
734
|
const formFields = (
|
|
737
735
|
<>
|
|
738
|
-
{(
|
|
736
|
+
{(getFormFieldKeys(resolvedCollection))
|
|
739
737
|
.map((key) => {
|
|
740
738
|
|
|
741
739
|
const property = resolvedCollection.properties[key];
|
|
742
|
-
if (
|
|
743
|
-
|
|
744
|
-
|
|
740
|
+
if (property) {
|
|
741
|
+
|
|
742
|
+
const underlyingValueHasChanged: boolean =
|
|
743
|
+
!!underlyingChanges &&
|
|
744
|
+
Object.keys(underlyingChanges).includes(key) &&
|
|
745
|
+
formex.touched[key];
|
|
746
|
+
|
|
747
|
+
const disabled = (!autoSave && formex.isSubmitting) || isReadOnly(property) || Boolean(property.disabled);
|
|
748
|
+
const hidden = isHidden(property);
|
|
749
|
+
if (hidden) return null;
|
|
750
|
+
const cmsFormFieldProps: PropertyFieldBindingProps<any, M> = {
|
|
751
|
+
propertyKey: key,
|
|
752
|
+
disabled,
|
|
753
|
+
property,
|
|
754
|
+
includeDescription: property.description || property.longDescription,
|
|
755
|
+
underlyingValueHasChanged: underlyingValueHasChanged && !autoSave,
|
|
756
|
+
context: formContext,
|
|
757
|
+
partOfArray: false,
|
|
758
|
+
minimalistView: false,
|
|
759
|
+
autoFocus: false
|
|
760
|
+
};
|
|
761
|
+
|
|
762
|
+
return (
|
|
763
|
+
<div id={`form_field_${key}`}
|
|
764
|
+
key={`field_${resolvedCollection.name}_${key}`}>
|
|
765
|
+
<ErrorBoundary>
|
|
766
|
+
<PropertyFieldBinding {...cmsFormFieldProps}/>
|
|
767
|
+
</ErrorBoundary>
|
|
768
|
+
</div>
|
|
769
|
+
);
|
|
745
770
|
}
|
|
746
771
|
|
|
747
|
-
const
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
);
|
|
772
|
+
const additionalField = resolvedCollection.additionalFields?.find(f => f.key === key);
|
|
773
|
+
if (additionalField && entity) {
|
|
774
|
+
const Builder = additionalField.Builder;
|
|
775
|
+
if (!Builder && !additionalField.value) {
|
|
776
|
+
throw new Error("When using additional fields you need to provide a Builder or a value");
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
const child = Builder
|
|
780
|
+
? <Builder entity={entity} context={context}/>
|
|
781
|
+
: <>{additionalField.value?.({
|
|
782
|
+
entity,
|
|
783
|
+
context
|
|
784
|
+
})}</>;
|
|
785
|
+
return (
|
|
786
|
+
<div>
|
|
787
|
+
<LabelWithIconAndTooltip
|
|
788
|
+
propertyKey={key}
|
|
789
|
+
icon={<NotesIcon size={"small"}/>}
|
|
790
|
+
title={additionalField.name}
|
|
791
|
+
className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
|
|
792
|
+
<div
|
|
793
|
+
className={cls(paperMixin, "min-h-14 p-4 md:p-6 overflow-x-scroll no-scrollbar")}>
|
|
794
|
+
|
|
795
|
+
<ErrorBoundary>
|
|
796
|
+
{child}
|
|
797
|
+
</ErrorBoundary>
|
|
798
|
+
|
|
799
|
+
</div>
|
|
800
|
+
</div>
|
|
801
|
+
);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
console.warn(`Property ${key} not found in collection ${resolvedCollection.name} in properties or additional fields. Skipping.`);
|
|
805
|
+
return null;
|
|
782
806
|
})
|
|
783
807
|
.filter(Boolean)}
|
|
784
808
|
|
|
@@ -861,51 +885,54 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
861
885
|
|
|
862
886
|
function buildForm() {
|
|
863
887
|
|
|
864
|
-
let form =
|
|
888
|
+
let form = <>
|
|
865
889
|
|
|
866
890
|
{pluginActions.length > 0 && <div
|
|
867
891
|
className={cls("w-full flex justify-end items-center sticky top-0 right-0 left-0 z-10 bg-opacity-60 bg-slate-200 dark:bg-opacity-60 dark:bg-slate-800 backdrop-blur-md")}>
|
|
868
892
|
{pluginActions}
|
|
869
893
|
</div>}
|
|
870
894
|
|
|
871
|
-
<div className="
|
|
872
|
-
<div
|
|
873
|
-
className={`w-full py-2 flex flex-col items-start mt-${4 + (pluginActions ? 8 : 0)} lg:mt-${8 + (pluginActions ? 8 : 0)} mb-8`}>
|
|
895
|
+
<div className="h-full overflow-auto">
|
|
874
896
|
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
897
|
+
<div className="pt-12 pb-16 pl-8 pr-8 md:pl-10 md:pr-10">
|
|
898
|
+
<div
|
|
899
|
+
className={`w-full py-2 flex flex-col items-start mt-${4 + (pluginActions ? 8 : 0)} lg:mt-${8 + (pluginActions ? 8 : 0)} mb-8`}>
|
|
900
|
+
|
|
901
|
+
<Typography
|
|
902
|
+
className={"mt-4 flex-grow line-clamp-1 " + inputCollection.hideIdFromForm ? "mb-2" : "mb-0"}
|
|
903
|
+
variant={"h4"}>{title ?? inputCollection.singularName ?? inputCollection.name}
|
|
904
|
+
</Typography>
|
|
905
|
+
<Alert color={"base"} className={"w-full"} size={"small"}>
|
|
906
|
+
<code className={"text-xs select-all"}>{path}/{entityId}</code>
|
|
907
|
+
</Alert>
|
|
908
|
+
</div>
|
|
883
909
|
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
910
|
+
{!collection.hideIdFromForm &&
|
|
911
|
+
<CustomIdField customId={inputCollection.customId}
|
|
912
|
+
entityId={entityId}
|
|
913
|
+
status={status}
|
|
914
|
+
onChange={setEntityId}
|
|
915
|
+
error={entityIdError}
|
|
916
|
+
loading={customIdLoading}
|
|
917
|
+
entity={entity}/>}
|
|
892
918
|
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
919
|
+
{entityId && formContext && <>
|
|
920
|
+
<div className="mt-12 flex flex-col gap-8"
|
|
921
|
+
ref={formRef}>
|
|
896
922
|
|
|
897
|
-
|
|
923
|
+
{formFields}
|
|
898
924
|
|
|
899
|
-
|
|
925
|
+
<ErrorFocus containerRef={formRef}/>
|
|
900
926
|
|
|
901
|
-
|
|
927
|
+
</div>
|
|
902
928
|
|
|
903
|
-
|
|
929
|
+
<div className="h-14"/>
|
|
904
930
|
|
|
905
|
-
|
|
931
|
+
</>}
|
|
906
932
|
|
|
933
|
+
</div>
|
|
907
934
|
</div>
|
|
908
|
-
|
|
935
|
+
</>;
|
|
909
936
|
|
|
910
937
|
if (plugins) {
|
|
911
938
|
plugins.forEach((plugin: FireCMSPlugin) => {
|
|
@@ -1001,7 +1028,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
1001
1028
|
</div>}
|
|
1002
1029
|
|
|
1003
1030
|
<Tabs
|
|
1004
|
-
value={
|
|
1031
|
+
value={selectedTab}
|
|
1005
1032
|
onValueChange={(value) => {
|
|
1006
1033
|
onSideTabClick(value);
|
|
1007
1034
|
}}
|
|
@@ -1035,7 +1062,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
1035
1062
|
role="tabpanel"
|
|
1036
1063
|
hidden={!mainViewVisible}
|
|
1037
1064
|
id={`form_${path}`}
|
|
1038
|
-
className={" w-full"}>
|
|
1065
|
+
className={"relative w-full"}>
|
|
1039
1066
|
|
|
1040
1067
|
{globalLoading
|
|
1041
1068
|
? <CircularProgressCenter/>
|
package/src/core/FireCMS.tsx
CHANGED
|
@@ -28,7 +28,7 @@ import { useProjectLog } from "../hooks/useProjectLog";
|
|
|
28
28
|
*
|
|
29
29
|
* You only need to use this component if you are building a custom app.
|
|
30
30
|
*
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
* @group Core
|
|
33
33
|
*/
|
|
34
34
|
export function FireCMS<UserType extends User, EC extends EntityCollection>(props: FireCMSProps<UserType, EC>) {
|
|
@@ -82,7 +82,7 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
|
|
|
82
82
|
onAnalyticsEvent
|
|
83
83
|
}), []);
|
|
84
84
|
|
|
85
|
-
const accessResponse = useProjectLog(authController, plugins);
|
|
85
|
+
const accessResponse = useProjectLog(authController, dataSourceDelegate, plugins);
|
|
86
86
|
|
|
87
87
|
if (navigationController.navigationLoadingError) {
|
|
88
88
|
return (
|
|
@@ -25,7 +25,7 @@ export type NavigationRoutesProps = {
|
|
|
25
25
|
* or the home route) related to a {@link NavigationController}.
|
|
26
26
|
* This component needs a parent {@link FireCMS}
|
|
27
27
|
*
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
* @group Components
|
|
30
30
|
*/
|
|
31
31
|
export const NavigationRoutes = React.memo<NavigationRoutesProps>(
|
package/src/core/SideDialogs.tsx
CHANGED
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
DateTimeFieldBinding,
|
|
9
9
|
KeyValueFieldBinding,
|
|
10
10
|
MapFieldBinding,
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
MarkdownEditorFieldBinding,
|
|
12
|
+
MultiSelectFieldBinding,
|
|
13
13
|
ReferenceFieldBinding,
|
|
14
14
|
RepeatFieldBinding,
|
|
15
15
|
SelectFieldBinding,
|
|
@@ -77,7 +77,7 @@ export const DEFAULT_FIELD_CONFIGS: Record<string, PropertyConfig<any>> = {
|
|
|
77
77
|
property: {
|
|
78
78
|
dataType: "string",
|
|
79
79
|
markdown: true,
|
|
80
|
-
Field:
|
|
80
|
+
Field: MarkdownEditorFieldBinding
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
83
|
url: {
|
|
@@ -139,7 +139,7 @@ export const DEFAULT_FIELD_CONFIGS: Record<string, PropertyConfig<any>> = {
|
|
|
139
139
|
dataType: "string",
|
|
140
140
|
enumValues: [],
|
|
141
141
|
},
|
|
142
|
-
Field:
|
|
142
|
+
Field: MultiSelectFieldBinding
|
|
143
143
|
}
|
|
144
144
|
},
|
|
145
145
|
number_input: {
|
|
@@ -177,7 +177,7 @@ export const DEFAULT_FIELD_CONFIGS: Record<string, PropertyConfig<any>> = {
|
|
|
177
177
|
dataType: "number",
|
|
178
178
|
enumValues: [],
|
|
179
179
|
},
|
|
180
|
-
Field:
|
|
180
|
+
Field: MultiSelectFieldBinding
|
|
181
181
|
}
|
|
182
182
|
},
|
|
183
183
|
file_upload: {
|