@firecms/core 3.0.0-beta.11 → 3.0.0-beta.13
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/Scaffold.d.ts +4 -0
- package/dist/components/ArrayContainer.d.ts +14 -3
- package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +2 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +15 -1
- package/dist/components/EntityCollectionTable/index.d.ts +1 -1
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +8 -0
- package/dist/components/EntityJsonPreview.d.ts +3 -0
- package/dist/components/PropertyIdCopyTooltip.d.ts +1 -1
- package/dist/components/SelectableTable/SelectableTable.d.ts +12 -2
- package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +1 -1
- package/dist/components/UnsavedChangesDialog.d.ts +8 -0
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +13 -0
- package/dist/components/common/default_entity_actions.d.ts +0 -2
- package/dist/components/common/index.d.ts +1 -1
- package/dist/components/common/useColumnsIds.d.ts +1 -0
- package/dist/components/common/{useDataSourceEntityCollectionTableController.d.ts → useDataSourceTableController.d.ts} +10 -2
- package/dist/components/common/useDebouncedCallback.d.ts +1 -0
- package/dist/components/common/useScrollRestoration.d.ts +14 -0
- package/dist/contexts/BreacrumbsContext.d.ts +8 -0
- package/dist/core/DefaultAppBar.d.ts +8 -2
- package/dist/core/EntityEditView.d.ts +36 -21
- package/dist/core/EntityEditViewFormActions.d.ts +2 -0
- package/dist/core/FireCMS.d.ts +2 -2
- package/dist/core/FireCMSRouter.d.ts +4 -0
- package/dist/core/NavigationRoutes.d.ts +0 -1
- package/dist/core/SideDialogs.d.ts +4 -2
- package/dist/core/index.d.ts +2 -1
- package/dist/form/EntityForm.d.ts +49 -0
- package/dist/form/EntityFormActions.d.ts +17 -0
- package/dist/form/PropertyFieldBinding.d.ts +1 -1
- package/dist/form/components/FormEntry.d.ts +6 -0
- package/dist/form/components/FormLayout.d.ts +5 -0
- package/dist/form/components/index.d.ts +2 -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/MapFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
- package/dist/form/index.d.ts +16 -16
- package/dist/hooks/data/save.d.ts +1 -1
- package/dist/hooks/data/useEntityFetch.d.ts +2 -1
- package/dist/hooks/useBreadcrumbsController.d.ts +26 -0
- package/dist/hooks/useBuildNavigationController.d.ts +4 -1
- package/dist/hooks/useModeController.d.ts +1 -2
- package/dist/index.es.js +15842 -14396
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +15833 -14389
- package/dist/index.umd.js.map +1 -1
- package/dist/internal/useBuildDataSource.d.ts +3 -2
- package/dist/internal/useBuildSideEntityController.d.ts +3 -3
- package/dist/internal/useUnsavedChangesDialog.d.ts +7 -9
- package/dist/routes/CustomCMSRoute.d.ts +4 -0
- package/dist/routes/FireCMSRoute.d.ts +1 -0
- package/dist/routes/HomePageRoute.d.ts +3 -0
- package/dist/types/collections.d.ts +36 -10
- package/dist/types/datasource.d.ts +2 -2
- package/dist/types/dialogs_controller.d.ts +7 -3
- package/dist/types/entities.d.ts +1 -1
- package/dist/types/entity_actions.d.ts +10 -0
- package/dist/types/fields.d.ts +13 -3
- package/dist/types/firecms.d.ts +1 -1
- package/dist/types/navigation.d.ts +33 -12
- package/dist/types/plugins.d.ts +2 -0
- package/dist/types/properties.d.ts +40 -4
- package/dist/types/side_entity_controller.d.ts +6 -1
- package/dist/util/builders.d.ts +1 -1
- package/dist/util/createFormexStub.d.ts +2 -0
- package/dist/util/entity_actions.d.ts +2 -0
- package/dist/util/entity_cache.d.ts +23 -0
- package/dist/util/index.d.ts +1 -0
- package/dist/util/navigation_from_path.d.ts +6 -1
- package/dist/util/navigation_utils.d.ts +13 -1
- package/dist/util/objects.d.ts +1 -1
- package/dist/util/property_utils.d.ts +2 -2
- package/dist/util/references.d.ts +2 -2
- package/dist/util/resolutions.d.ts +12 -2
- package/package.json +20 -21
- package/src/app/Scaffold.tsx +13 -3
- package/src/components/ArrayContainer.tsx +60 -24
- package/src/components/CircularProgressCenter.tsx +1 -1
- package/src/components/DeleteEntityDialog.tsx +5 -3
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +46 -23
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +10 -4
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +18 -1
- package/src/components/EntityCollectionTable/index.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -3
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +10 -13
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +105 -47
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +4 -2
- package/src/components/EntityJsonPreview.tsx +66 -0
- package/src/components/EntityPreview.tsx +10 -3
- package/src/components/EntityView.tsx +4 -1
- package/src/components/NotFoundPage.tsx +2 -2
- package/src/components/PropertyIdCopyTooltip.tsx +2 -3
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +14 -7
- package/src/components/SelectableTable/SelectableTable.tsx +18 -3
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +7 -7
- package/src/components/UnsavedChangesDialog.tsx +42 -0
- package/src/components/VirtualTable/VirtualTable.tsx +48 -3
- package/src/components/VirtualTable/VirtualTableProps.tsx +15 -0
- package/src/components/VirtualTable/fields/VirtualTableInput.tsx +1 -1
- package/src/components/common/default_entity_actions.tsx +37 -37
- package/src/components/common/index.ts +1 -1
- package/src/components/common/useColumnsIds.tsx +1 -1
- package/src/components/common/useDataSourceTableController.tsx +420 -0
- package/src/components/common/useDebouncedCallback.tsx +20 -0
- package/src/components/common/useScrollRestoration.tsx +68 -0
- package/src/contexts/BreacrumbsContext.tsx +38 -0
- package/src/contexts/DialogsProvider.tsx +3 -2
- package/src/contexts/ModeController.tsx +1 -3
- package/src/core/DefaultAppBar.tsx +59 -17
- package/src/core/DefaultDrawer.tsx +1 -1
- package/src/core/EntityEditView.tsx +354 -1000
- package/src/core/EntityEditViewFormActions.tsx +199 -0
- package/src/core/EntitySidePanel.tsx +85 -15
- package/src/core/FireCMS.tsx +20 -16
- package/src/core/FireCMSRouter.tsx +17 -0
- package/src/core/NavigationRoutes.tsx +23 -32
- package/src/core/SideDialogs.tsx +20 -11
- package/src/core/index.tsx +4 -2
- package/src/form/EntityForm.tsx +782 -0
- package/src/form/EntityFormActions.tsx +169 -0
- package/src/form/PropertyFieldBinding.tsx +21 -16
- package/src/form/components/FormEntry.tsx +22 -0
- package/src/form/components/FormLayout.tsx +16 -0
- package/src/form/components/LabelWithIcon.tsx +6 -3
- package/src/form/components/StorageUploadProgress.tsx +1 -1
- package/src/form/components/index.tsx +2 -0
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +8 -5
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +5 -2
- package/src/form/field_bindings/BlockFieldBinding.tsx +5 -3
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -0
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +1 -1
- package/src/form/field_bindings/MapFieldBinding.tsx +14 -16
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +15 -8
- package/src/form/field_bindings/MultiSelectFieldBinding.tsx +3 -3
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +2 -2
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +1 -1
- package/src/form/field_bindings/RepeatFieldBinding.tsx +13 -4
- package/src/form/field_bindings/SelectFieldBinding.tsx +2 -2
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +11 -6
- package/src/form/field_bindings/SwitchFieldBinding.tsx +1 -0
- package/src/form/field_bindings/TextFieldBinding.tsx +1 -0
- package/src/form/index.tsx +16 -32
- package/src/form/validation.ts +12 -6
- package/src/hooks/data/save.ts +25 -30
- package/src/hooks/data/useCollectionFetch.tsx +1 -1
- package/src/hooks/data/useEntityFetch.tsx +5 -1
- package/src/hooks/useBreadcrumbsController.tsx +31 -0
- package/src/hooks/useBuildModeController.tsx +15 -28
- package/src/hooks/useBuildNavigationController.tsx +81 -24
- package/src/hooks/useFireCMSContext.tsx +0 -30
- package/src/hooks/useLargeLayout.tsx +0 -35
- package/src/hooks/useModeController.tsx +1 -2
- package/src/hooks/useResolvedNavigationFrom.tsx +4 -6
- package/src/internal/useBuildDataSource.ts +9 -5
- package/src/internal/useBuildSideDialogsController.tsx +3 -2
- package/src/internal/useBuildSideEntityController.tsx +135 -88
- package/src/internal/useUnsavedChangesDialog.tsx +126 -92
- package/src/preview/PropertyPreview.tsx +12 -10
- package/src/preview/components/UrlComponentPreview.tsx +17 -18
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +4 -3
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +4 -3
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +4 -2
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +4 -3
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +4 -2
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +4 -2
- package/src/preview/property_previews/MapPropertyPreview.tsx +3 -2
- package/src/routes/CustomCMSRoute.tsx +21 -0
- package/src/routes/FireCMSRoute.tsx +246 -0
- package/src/routes/HomePageRoute.tsx +17 -0
- package/src/types/collections.ts +45 -13
- package/src/types/datasource.ts +2 -1
- package/src/types/dialogs_controller.tsx +7 -3
- package/src/types/entities.ts +1 -1
- package/src/types/entity_actions.tsx +12 -0
- package/src/types/fields.tsx +18 -3
- package/src/types/firecms.tsx +1 -1
- package/src/types/navigation.ts +41 -16
- package/src/types/plugins.tsx +2 -0
- package/src/types/properties.ts +48 -4
- package/src/types/side_dialogs_controller.tsx +2 -0
- package/src/types/side_entity_controller.tsx +11 -1
- package/src/util/builders.ts +5 -3
- package/src/util/createFormexStub.tsx +62 -0
- package/src/util/entity_actions.ts +28 -0
- package/src/util/entity_cache.ts +204 -0
- package/src/util/index.ts +1 -0
- package/src/util/join_collections.ts +6 -1
- package/src/util/navigation_from_path.ts +18 -7
- package/src/util/navigation_utils.ts +115 -14
- package/src/util/objects.ts +9 -2
- package/src/util/parent_references_from_path.ts +3 -3
- package/src/util/property_utils.tsx +7 -3
- package/src/util/references.ts +8 -6
- package/src/util/resolutions.ts +41 -12
- package/src/util/useStorageUploadController.tsx +60 -23
- package/src/components/common/useDataSourceEntityCollectionTableController.tsx +0 -236
- /package/src/util/{common.tsx → common.ts} +0 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Entity, EntityAction, FireCMSContext, ResolvedEntityCollection, SideEntityController } from "../types";
|
|
3
|
+
import { Button, cls, defaultBorderMixin, DialogActions, IconButton, LoadingButton, Typography } from "@firecms/ui";
|
|
4
|
+
import { FormexController } from "@firecms/formex";
|
|
5
|
+
import { useFireCMSContext, useSideEntityController } from "../hooks";
|
|
6
|
+
|
|
7
|
+
export interface EntityFormActionsProps {
|
|
8
|
+
collection: ResolvedEntityCollection;
|
|
9
|
+
path: string;
|
|
10
|
+
entity?: Entity;
|
|
11
|
+
layout: "bottom" | "side";
|
|
12
|
+
savingError?: Error;
|
|
13
|
+
formex: FormexController<any>;
|
|
14
|
+
disabled: boolean;
|
|
15
|
+
status: "new" | "existing" | "copy";
|
|
16
|
+
pluginActions: React.ReactNode[];
|
|
17
|
+
openEntityMode: "side_panel" | "full_screen";
|
|
18
|
+
showDefaultActions?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function EntityFormActions({
|
|
22
|
+
collection,
|
|
23
|
+
entity,
|
|
24
|
+
layout,
|
|
25
|
+
savingError,
|
|
26
|
+
formex,
|
|
27
|
+
disabled,
|
|
28
|
+
status,
|
|
29
|
+
pluginActions,
|
|
30
|
+
openEntityMode
|
|
31
|
+
}: EntityFormActionsProps) {
|
|
32
|
+
|
|
33
|
+
const context = useFireCMSContext();
|
|
34
|
+
const sideEntityController = useSideEntityController();
|
|
35
|
+
|
|
36
|
+
return layout === "bottom"
|
|
37
|
+
? buildBottomActions({
|
|
38
|
+
savingError,
|
|
39
|
+
entity,
|
|
40
|
+
collection,
|
|
41
|
+
context,
|
|
42
|
+
sideEntityController,
|
|
43
|
+
isSubmitting: formex.isSubmitting,
|
|
44
|
+
disabled,
|
|
45
|
+
status,
|
|
46
|
+
pluginActions,
|
|
47
|
+
openEntityMode
|
|
48
|
+
})
|
|
49
|
+
: buildSideActions({
|
|
50
|
+
savingError,
|
|
51
|
+
entity,
|
|
52
|
+
collection,
|
|
53
|
+
context,
|
|
54
|
+
sideEntityController,
|
|
55
|
+
isSubmitting: formex.isSubmitting,
|
|
56
|
+
disabled,
|
|
57
|
+
status,
|
|
58
|
+
pluginActions,
|
|
59
|
+
openEntityMode
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
type ActionsViewProps<M extends object> = {
|
|
64
|
+
savingError: Error | undefined,
|
|
65
|
+
entity: Entity<M> | undefined,
|
|
66
|
+
formActions?: EntityAction[],
|
|
67
|
+
collection: ResolvedEntityCollection,
|
|
68
|
+
context: FireCMSContext,
|
|
69
|
+
sideEntityController: SideEntityController,
|
|
70
|
+
isSubmitting: boolean,
|
|
71
|
+
disabled: boolean,
|
|
72
|
+
status: "new" | "existing" | "copy",
|
|
73
|
+
pluginActions?: React.ReactNode[],
|
|
74
|
+
openEntityMode: "side_panel" | "full_screen";
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
function buildBottomActions<M extends object>({
|
|
78
|
+
savingError,
|
|
79
|
+
entity,
|
|
80
|
+
formActions,
|
|
81
|
+
collection,
|
|
82
|
+
context,
|
|
83
|
+
sideEntityController,
|
|
84
|
+
isSubmitting,
|
|
85
|
+
disabled,
|
|
86
|
+
status,
|
|
87
|
+
pluginActions,
|
|
88
|
+
openEntityMode
|
|
89
|
+
}: ActionsViewProps<M>) {
|
|
90
|
+
|
|
91
|
+
return <DialogActions position={"absolute"}>
|
|
92
|
+
{savingError &&
|
|
93
|
+
<div className="text-right">
|
|
94
|
+
<Typography color={"error"}>{savingError.message}</Typography>
|
|
95
|
+
</div>
|
|
96
|
+
}
|
|
97
|
+
{entity && (formActions ?? []).length > 0 && <div className="flex-grow flex overflow-auto no-scrollbar">
|
|
98
|
+
{(formActions ?? []).map(action => (
|
|
99
|
+
<IconButton
|
|
100
|
+
key={action.name}
|
|
101
|
+
color="primary"
|
|
102
|
+
onClick={(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
|
103
|
+
event.stopPropagation();
|
|
104
|
+
if (entity)
|
|
105
|
+
action.onClick({
|
|
106
|
+
entity,
|
|
107
|
+
fullPath: collection.path,
|
|
108
|
+
collection: collection,
|
|
109
|
+
context,
|
|
110
|
+
sideEntityController,
|
|
111
|
+
openEntityMode: openEntityMode
|
|
112
|
+
});
|
|
113
|
+
}}>
|
|
114
|
+
{action.icon}
|
|
115
|
+
</IconButton>
|
|
116
|
+
))}
|
|
117
|
+
</div>}
|
|
118
|
+
{pluginActions}
|
|
119
|
+
<Button variant="text" disabled={disabled || isSubmitting} type="reset">
|
|
120
|
+
{status === "existing" ? "Discard" : "Clear"}
|
|
121
|
+
</Button>
|
|
122
|
+
<Button variant={"filled"} color="primary" type="submit"
|
|
123
|
+
disabled={disabled || isSubmitting}>
|
|
124
|
+
{status === "existing" && "Save"}
|
|
125
|
+
{status === "copy" && "Create copy"}
|
|
126
|
+
{status === "new" && "Create"}
|
|
127
|
+
</Button>
|
|
128
|
+
|
|
129
|
+
</DialogActions>;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function buildSideActions<M extends object>({
|
|
133
|
+
savingError,
|
|
134
|
+
entity,
|
|
135
|
+
formActions,
|
|
136
|
+
collection,
|
|
137
|
+
context,
|
|
138
|
+
sideEntityController,
|
|
139
|
+
isSubmitting,
|
|
140
|
+
disabled,
|
|
141
|
+
status,
|
|
142
|
+
pluginActions
|
|
143
|
+
}: ActionsViewProps<M>) {
|
|
144
|
+
|
|
145
|
+
return <div
|
|
146
|
+
className={cls("overflow-auto h-full flex flex-col gap-2 w-80 2xl:w-96 px-4 py-16 sticky top-0 border-l", defaultBorderMixin)}>
|
|
147
|
+
<LoadingButton fullWidth={true}
|
|
148
|
+
variant="filled"
|
|
149
|
+
color="primary"
|
|
150
|
+
type="submit"
|
|
151
|
+
size={"large"}
|
|
152
|
+
disabled={disabled || isSubmitting}>
|
|
153
|
+
{status === "existing" && "Save"}
|
|
154
|
+
{status === "copy" && "Create copy"}
|
|
155
|
+
{status === "new" && "Create"}
|
|
156
|
+
</LoadingButton>
|
|
157
|
+
<Button fullWidth={true} variant="text" disabled={disabled || isSubmitting} type="reset">
|
|
158
|
+
{status === "existing" ? "Discard" : "Clear"}
|
|
159
|
+
</Button>
|
|
160
|
+
|
|
161
|
+
{pluginActions}
|
|
162
|
+
|
|
163
|
+
{savingError &&
|
|
164
|
+
<div className="text-right">
|
|
165
|
+
<Typography color={"error"}>{savingError.message}</Typography>
|
|
166
|
+
</div>
|
|
167
|
+
}
|
|
168
|
+
</div>;
|
|
169
|
+
}
|
|
@@ -5,19 +5,19 @@ import { Field, FieldProps as FormexFieldProps, getIn } from "@firecms/formex";
|
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
CMSType,
|
|
8
|
-
EntityCollection,
|
|
9
8
|
FieldProps,
|
|
10
9
|
FireCMSPlugin,
|
|
11
10
|
PluginFieldBuilderParams,
|
|
12
11
|
Property,
|
|
13
12
|
PropertyFieldBindingProps,
|
|
14
13
|
PropertyOrBuilder,
|
|
14
|
+
ResolvedEntityCollection,
|
|
15
15
|
ResolvedProperty
|
|
16
16
|
} from "../types";
|
|
17
17
|
import { ReadOnlyFieldBinding } from "./field_bindings/ReadOnlyFieldBinding";
|
|
18
18
|
|
|
19
19
|
import { isHidden, isPropertyBuilder, isReadOnly, resolveProperty } from "../util";
|
|
20
|
-
import { useCustomizationController } from "../hooks";
|
|
20
|
+
import { useAuthController, useCustomizationController } from "../hooks";
|
|
21
21
|
import { Typography } from "@firecms/ui";
|
|
22
22
|
import { getFieldConfig, getFieldId } from "../core";
|
|
23
23
|
import { ErrorBoundary } from "../components";
|
|
@@ -74,7 +74,7 @@ export const PropertyFieldBinding = React.memo(PropertyFieldBindingInternal, (a:
|
|
|
74
74
|
return false;
|
|
75
75
|
}) as typeof PropertyFieldBindingInternal;
|
|
76
76
|
|
|
77
|
-
function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Record<string, any> =
|
|
77
|
+
function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Record<string, any> = any>
|
|
78
78
|
({
|
|
79
79
|
propertyKey,
|
|
80
80
|
property,
|
|
@@ -87,9 +87,10 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
|
|
|
87
87
|
autoFocus,
|
|
88
88
|
index,
|
|
89
89
|
size,
|
|
90
|
-
onPropertyChange
|
|
90
|
+
onPropertyChange,
|
|
91
91
|
}: PropertyFieldBindingProps<T, M>): ReactElement<PropertyFieldBindingProps<T, M>> {
|
|
92
92
|
|
|
93
|
+
const authController = useAuthController();
|
|
93
94
|
const customizationController = useCustomizationController();
|
|
94
95
|
|
|
95
96
|
return (
|
|
@@ -107,10 +108,11 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
|
|
|
107
108
|
path: context.path,
|
|
108
109
|
entityId: context.entityId,
|
|
109
110
|
propertyConfigs: customizationController.propertyConfigs,
|
|
110
|
-
index
|
|
111
|
+
index,
|
|
112
|
+
authController
|
|
111
113
|
});
|
|
112
114
|
|
|
113
|
-
const disabled = disabledProp || isReadOnly(resolvedProperty) || Boolean(resolvedProperty?.disabled);
|
|
115
|
+
const disabled = disabledProp || isReadOnly(resolvedProperty) || Boolean(resolvedProperty?.disabled) || context.disabled;
|
|
114
116
|
|
|
115
117
|
if (resolvedProperty === null || isHidden(resolvedProperty)) {
|
|
116
118
|
return <></>;
|
|
@@ -139,7 +141,8 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
|
|
|
139
141
|
path: context.path,
|
|
140
142
|
entityId: context.entityId,
|
|
141
143
|
propertyConfigs: customizationController.propertyConfigs,
|
|
142
|
-
index
|
|
144
|
+
index,
|
|
145
|
+
authController
|
|
143
146
|
});
|
|
144
147
|
Component = configProperty.Field as ComponentType<FieldProps<T>>;
|
|
145
148
|
}
|
|
@@ -147,7 +150,9 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
|
|
|
147
150
|
console.warn(`No field component found for property ${propertyKey}`);
|
|
148
151
|
console.warn("Property:", property);
|
|
149
152
|
return (
|
|
150
|
-
<div
|
|
153
|
+
<div className={"w-full"}>
|
|
154
|
+
{`Currently the field ${resolvedProperty.dataType} is not supported`}
|
|
155
|
+
</div>
|
|
151
156
|
);
|
|
152
157
|
}
|
|
153
158
|
|
|
@@ -175,7 +180,7 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
|
|
|
175
180
|
|
|
176
181
|
}
|
|
177
182
|
|
|
178
|
-
type ResolvedPropertyFieldBindingProps<T extends CMSType = CMSType, M extends Record<string, any> =
|
|
183
|
+
type ResolvedPropertyFieldBindingProps<T extends CMSType = CMSType, M extends Record<string, any> = any> =
|
|
179
184
|
Omit<PropertyFieldBindingProps<T, M>, "property">
|
|
180
185
|
& {
|
|
181
186
|
property: ResolvedProperty<T>
|
|
@@ -199,11 +204,11 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
|
|
|
199
204
|
},
|
|
200
205
|
formexFieldProps
|
|
201
206
|
}:
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
+
{
|
|
208
|
+
Component: ComponentType<FieldProps<T, any, M>>,
|
|
209
|
+
componentProps: ResolvedPropertyFieldBindingProps<T, M>,
|
|
210
|
+
formexFieldProps: FormexFieldProps<T, any>
|
|
211
|
+
}) {
|
|
207
212
|
|
|
208
213
|
const { plugins } = useCustomizationController();
|
|
209
214
|
|
|
@@ -296,7 +301,7 @@ const shouldPropertyReRender = (property: PropertyOrBuilder | ResolvedProperty,
|
|
|
296
301
|
|
|
297
302
|
interface UseWrappedComponentParams<T extends CMSType = CMSType, M extends Record<string, any> = any> {
|
|
298
303
|
path?: string,
|
|
299
|
-
collection?:
|
|
304
|
+
collection?: ResolvedEntityCollection<M>,
|
|
300
305
|
propertyKey: string,
|
|
301
306
|
property: ResolvedProperty<T>,
|
|
302
307
|
Component: ComponentType<FieldProps<T, any, M>>,
|
|
@@ -327,7 +332,7 @@ function useWrappedComponent<T extends CMSType = CMSType, M extends Record<strin
|
|
|
327
332
|
Field: Component,
|
|
328
333
|
plugin,
|
|
329
334
|
path,
|
|
330
|
-
collection
|
|
335
|
+
collection,
|
|
331
336
|
};
|
|
332
337
|
const enabled = plugin.form?.fieldBuilderEnabled?.(params);
|
|
333
338
|
if (enabled === undefined || enabled)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ErrorBoundary } from "../../components";
|
|
3
|
+
|
|
4
|
+
export function FormEntry({
|
|
5
|
+
propertyKey,
|
|
6
|
+
widthPercentage = 100,
|
|
7
|
+
children
|
|
8
|
+
}: {
|
|
9
|
+
propertyKey: string;
|
|
10
|
+
widthPercentage?: number;
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
}) {
|
|
13
|
+
return (
|
|
14
|
+
<div id={`form_field_${propertyKey}`}
|
|
15
|
+
className={"relative"}
|
|
16
|
+
style={{ width: widthPercentage === 100 ? "100%" : `calc(${widthPercentage}% - 8px)` }}>
|
|
17
|
+
<ErrorBoundary>
|
|
18
|
+
{children}
|
|
19
|
+
</ErrorBoundary>
|
|
20
|
+
</div>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { cls } from "@firecms/ui";
|
|
3
|
+
|
|
4
|
+
export function FormLayout({
|
|
5
|
+
children,
|
|
6
|
+
className
|
|
7
|
+
}: {
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
className?: string;
|
|
10
|
+
}) {
|
|
11
|
+
return (
|
|
12
|
+
<div className={cls("flex flex-wrap gap-x-4 w-full space-y-8", className)}>
|
|
13
|
+
{children}
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { forwardRef } from "react";
|
|
2
|
+
import { cls } from "@firecms/ui";
|
|
2
3
|
|
|
3
4
|
interface LabelWithIconProps {
|
|
4
5
|
icon: React.ReactNode;
|
|
@@ -23,9 +24,11 @@ export const LabelWithIcon = forwardRef<HTMLDivElement, LabelWithIconProps>(
|
|
|
23
24
|
return (
|
|
24
25
|
<div
|
|
25
26
|
ref={ref}
|
|
26
|
-
className={
|
|
27
|
+
className={cls("inline-flex items-center my-0.5",
|
|
28
|
+
small ? "gap-1" : "gap-2",
|
|
29
|
+
className)}
|
|
27
30
|
>
|
|
28
|
-
|
|
31
|
+
{icon}
|
|
29
32
|
<span
|
|
30
33
|
className={`text-start font-medium text-${small ? "base" : "sm"} origin-top-left transform ${
|
|
31
34
|
small ? "translate-x-2 scale-75" : ""
|
|
@@ -33,7 +36,7 @@ export const LabelWithIcon = forwardRef<HTMLDivElement, LabelWithIconProps>(
|
|
|
33
36
|
>
|
|
34
37
|
{(title ?? "") + (required ? " *" : "")}
|
|
35
38
|
</span>
|
|
36
|
-
|
|
39
|
+
</div>
|
|
37
40
|
);
|
|
38
41
|
}
|
|
39
42
|
);
|
|
@@ -92,7 +92,7 @@ export function StorageUploadProgress({
|
|
|
92
92
|
`min-w-[${imageSize}px] min-h-[${imageSize}px]`)}>
|
|
93
93
|
|
|
94
94
|
{loading &&
|
|
95
|
-
<Skeleton className="w-full h-full"/>}
|
|
95
|
+
<Skeleton className="m-4 w-full h-full"/>}
|
|
96
96
|
|
|
97
97
|
{error && <ErrorView title={"Error uploading file"}
|
|
98
98
|
error={error}/>}
|
|
@@ -5,6 +5,7 @@ import { PropertyFieldBinding } from "../PropertyFieldBinding";
|
|
|
5
5
|
import { ExpandablePanel, Typography } from "@firecms/ui";
|
|
6
6
|
import { getArrayResolvedProperties, getIconForProperty, isReadOnly } from "../../util";
|
|
7
7
|
import { useClearRestoreValue } from "../useClearRestoreValue";
|
|
8
|
+
import { useAuthController } from "../../hooks";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Array field used for custom
|
|
@@ -20,21 +21,24 @@ export function ArrayCustomShapedFieldBinding<T extends Array<any>>({
|
|
|
20
21
|
showError,
|
|
21
22
|
isSubmitting,
|
|
22
23
|
setValue,
|
|
23
|
-
minimalistView,
|
|
24
|
+
minimalistView: minimalistViewProp,
|
|
24
25
|
property,
|
|
25
26
|
includeDescription,
|
|
26
|
-
underlyingValueHasChanged,
|
|
27
27
|
context,
|
|
28
28
|
disabled
|
|
29
29
|
}: FieldProps<T, any, any>) {
|
|
30
30
|
|
|
31
|
+
const authController = useAuthController();
|
|
32
|
+
const minimalistView = minimalistViewProp || property.minimalistView;
|
|
33
|
+
|
|
31
34
|
let resolvedProperties = "resolvedProperties" in property ? property.resolvedProperties : undefined;
|
|
32
35
|
if (!resolvedProperties) {
|
|
33
36
|
resolvedProperties = getArrayResolvedProperties({
|
|
34
37
|
propertyValue: value,
|
|
35
38
|
propertyKey,
|
|
36
39
|
property,
|
|
37
|
-
ignoreMissingFields: false
|
|
40
|
+
ignoreMissingFields: false,
|
|
41
|
+
authController
|
|
38
42
|
})
|
|
39
43
|
}
|
|
40
44
|
|
|
@@ -52,7 +56,7 @@ export function ArrayCustomShapedFieldBinding<T extends Array<any>>({
|
|
|
52
56
|
icon={getIconForProperty(property, "small")}
|
|
53
57
|
required={property.validation?.required}
|
|
54
58
|
title={property.name}
|
|
55
|
-
className={"flex-grow text-text-secondary dark:text-text-secondary-dark"}/>
|
|
59
|
+
className={"h-8 flex-grow text-text-secondary dark:text-text-secondary-dark"}/>
|
|
56
60
|
{Array.isArray(value) && <Typography variant={"caption"} className={"px-4"}>({value.length})</Typography>}
|
|
57
61
|
</>);
|
|
58
62
|
|
|
@@ -63,7 +67,6 @@ export function ArrayCustomShapedFieldBinding<T extends Array<any>>({
|
|
|
63
67
|
disabled: disabled || thisDisabled,
|
|
64
68
|
property: childProperty,
|
|
65
69
|
includeDescription,
|
|
66
|
-
underlyingValueHasChanged,
|
|
67
70
|
context,
|
|
68
71
|
partOfArray: true,
|
|
69
72
|
minimalistView: false,
|
|
@@ -25,13 +25,15 @@ export function ArrayOfReferencesFieldBinding({
|
|
|
25
25
|
showError,
|
|
26
26
|
disabled,
|
|
27
27
|
isSubmitting,
|
|
28
|
-
minimalistView,
|
|
28
|
+
minimalistView: minimalistViewProp,
|
|
29
29
|
property,
|
|
30
30
|
includeDescription,
|
|
31
31
|
setValue,
|
|
32
32
|
setFieldValue
|
|
33
33
|
}: ArrayOfReferencesFieldProps) {
|
|
34
34
|
|
|
35
|
+
const minimalistView = minimalistViewProp || property.minimalistView;
|
|
36
|
+
|
|
35
37
|
const ofProperty = property.of as ResolvedProperty;
|
|
36
38
|
if (ofProperty.dataType !== "reference") {
|
|
37
39
|
throw Error("ArrayOfReferencesField expected a property containing references");
|
|
@@ -104,7 +106,7 @@ export function ArrayOfReferencesFieldBinding({
|
|
|
104
106
|
icon={getIconForProperty(property, "small")}
|
|
105
107
|
required={property.validation?.required}
|
|
106
108
|
title={property.name}
|
|
107
|
-
className={"flex flex-grow text-text-secondary dark:text-text-secondary-dark"}/>
|
|
109
|
+
className={"h-8 flex flex-grow text-text-secondary dark:text-text-secondary-dark"}/>
|
|
108
110
|
{Array.isArray(value) && <Typography variant={"caption"} className={"px-4"}>({value.length})</Typography>}
|
|
109
111
|
</>);
|
|
110
112
|
|
|
@@ -118,6 +120,7 @@ export function ArrayOfReferencesFieldBinding({
|
|
|
118
120
|
value={value}
|
|
119
121
|
disabled={isSubmitting}
|
|
120
122
|
buildEntry={buildEntry}
|
|
123
|
+
canAddElements={false}
|
|
121
124
|
addLabel={property.name ? "Add reference to " + property.name : "Add reference"}
|
|
122
125
|
newDefaultEntry={property.of.defaultValue}
|
|
123
126
|
onValueChange={(value) => setFieldValue(propertyKey, value)}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
2
|
|
|
3
3
|
import { Field, useFormex } from "@firecms/formex";
|
|
4
4
|
|
|
@@ -28,7 +28,7 @@ export function BlockFieldBinding<T extends Array<any>>({
|
|
|
28
28
|
isSubmitting,
|
|
29
29
|
setValue,
|
|
30
30
|
setFieldValue,
|
|
31
|
-
minimalistView,
|
|
31
|
+
minimalistView: minimalistViewProp,
|
|
32
32
|
property,
|
|
33
33
|
includeDescription,
|
|
34
34
|
underlyingValueHasChanged,
|
|
@@ -36,6 +36,8 @@ export function BlockFieldBinding<T extends Array<any>>({
|
|
|
36
36
|
disabled
|
|
37
37
|
}: FieldProps<T>) {
|
|
38
38
|
|
|
39
|
+
const minimalistView = minimalistViewProp || property.minimalistView;
|
|
40
|
+
|
|
39
41
|
if (!property.oneOf)
|
|
40
42
|
throw Error("ArrayOneOfField misconfiguration. Property `oneOf` not set");
|
|
41
43
|
|
|
@@ -86,7 +88,7 @@ export function BlockFieldBinding<T extends Array<any>>({
|
|
|
86
88
|
buildEntry={buildEntry}
|
|
87
89
|
onInternalIdAdded={setLastAddedId}
|
|
88
90
|
disabled={isSubmitting || Boolean(property.disabled)}
|
|
89
|
-
|
|
91
|
+
canAddElements={!property.disabled}
|
|
90
92
|
onValueChange={(value) => setFieldValue(propertyKey, value)}
|
|
91
93
|
newDefaultEntry={{
|
|
92
94
|
[property.oneOf!.typeField ?? DEFAULT_ONE_OF_TYPE]: firstOneOfKey,
|
|
@@ -329,7 +329,7 @@ function MapKeyValueRow<T extends Record<string, any>>({
|
|
|
329
329
|
addLabel={fieldKey ? `Add to ${fieldKey}` : "Add"}
|
|
330
330
|
size={"small"}
|
|
331
331
|
disabled={disabled || !fieldKey}
|
|
332
|
-
|
|
332
|
+
canAddElements={true}
|
|
333
333
|
onValueChange={(newValue) => {
|
|
334
334
|
setValue({
|
|
335
335
|
...value,
|
|
@@ -5,7 +5,7 @@ import { ErrorBoundary } from "../../components";
|
|
|
5
5
|
import { getIconForProperty, isHidden, isReadOnly, pick } from "../../util";
|
|
6
6
|
import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
|
|
7
7
|
import { PropertyFieldBinding } from "../PropertyFieldBinding";
|
|
8
|
-
import { ExpandablePanel, InputLabel, Select, SelectItem } from "@firecms/ui";
|
|
8
|
+
import { cls, ExpandablePanel, InputLabel, Select, SelectItem } from "@firecms/ui";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Field that renders the children property fields
|
|
@@ -21,9 +21,8 @@ export function MapFieldBinding({
|
|
|
21
21
|
error,
|
|
22
22
|
disabled,
|
|
23
23
|
property,
|
|
24
|
-
minimalistView,
|
|
24
|
+
minimalistView: minimalistViewProp,
|
|
25
25
|
includeDescription,
|
|
26
|
-
underlyingValueHasChanged,
|
|
27
26
|
autoFocus,
|
|
28
27
|
context,
|
|
29
28
|
onPropertyChange
|
|
@@ -31,6 +30,7 @@ export function MapFieldBinding({
|
|
|
31
30
|
|
|
32
31
|
const pickOnlySomeKeys = property.pickOnlySomeKeys || false;
|
|
33
32
|
const expanded = property.expanded === undefined ? true : property.expanded;
|
|
33
|
+
const minimalistView = minimalistViewProp || property.minimalistView;
|
|
34
34
|
|
|
35
35
|
if (!property.properties) {
|
|
36
36
|
throw Error(`You need to specify a 'properties' prop (or specify a custom field) in your map property ${propertyKey}`);
|
|
@@ -51,7 +51,7 @@ export function MapFieldBinding({
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
const mapFormView = <>
|
|
54
|
-
<div className="py-1 flex flex-col space-y-2">
|
|
54
|
+
<div className={cls("py-1 flex flex-col space-y-2", minimalistView && property.widthPercentage !== undefined ? "mt-8" : undefined)}>
|
|
55
55
|
{Object.entries(mapProperties)
|
|
56
56
|
.filter(([_, property]) => !isHidden(property))
|
|
57
57
|
.map(([entryKey, childProperty], index) => {
|
|
@@ -61,7 +61,6 @@ export function MapFieldBinding({
|
|
|
61
61
|
disabled: disabled || thisDisabled,
|
|
62
62
|
property: childProperty,
|
|
63
63
|
includeDescription,
|
|
64
|
-
underlyingValueHasChanged,
|
|
65
64
|
context,
|
|
66
65
|
partOfArray: false,
|
|
67
66
|
minimalistView: false,
|
|
@@ -76,7 +75,7 @@ export function MapFieldBinding({
|
|
|
76
75
|
};
|
|
77
76
|
|
|
78
77
|
return (
|
|
79
|
-
<div key={`map-${propertyKey}-${index}`}>
|
|
78
|
+
<div key={`map-${propertyKey}-${index}`} className={"relative"}>
|
|
80
79
|
<ErrorBoundary>
|
|
81
80
|
<PropertyFieldBinding
|
|
82
81
|
{...fieldBindingProps}/>
|
|
@@ -94,15 +93,6 @@ export function MapFieldBinding({
|
|
|
94
93
|
</>
|
|
95
94
|
;
|
|
96
95
|
|
|
97
|
-
const title = (
|
|
98
|
-
<LabelWithIconAndTooltip
|
|
99
|
-
propertyKey={propertyKey}
|
|
100
|
-
icon={getIconForProperty(property, "small")}
|
|
101
|
-
required={property.validation?.required}
|
|
102
|
-
title={property.name}
|
|
103
|
-
className={"text-text-secondary dark:text-text-secondary-dark"}/>
|
|
104
|
-
);
|
|
105
|
-
|
|
106
96
|
return (
|
|
107
97
|
<ErrorBoundary>
|
|
108
98
|
|
|
@@ -112,8 +102,16 @@ export function MapFieldBinding({
|
|
|
112
102
|
expanded
|
|
113
103
|
});
|
|
114
104
|
}}
|
|
105
|
+
className={property.widthPercentage !== undefined ? "mt-8" : undefined}
|
|
115
106
|
innerClassName={"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2 bg-white dark:bg-surface-900"}
|
|
116
|
-
title={
|
|
107
|
+
title={<LabelWithIconAndTooltip
|
|
108
|
+
propertyKey={propertyKey}
|
|
109
|
+
icon={getIconForProperty(property, "small")}
|
|
110
|
+
required={property.validation?.required}
|
|
111
|
+
title={property.name}
|
|
112
|
+
className={"text-text-secondary dark:text-text-secondary-dark"}/>}>
|
|
113
|
+
{mapFormView}
|
|
114
|
+
</ExpandablePanel>}
|
|
117
115
|
|
|
118
116
|
{minimalistView && mapFormView}
|
|
119
117
|
|