@firecms/core 3.0.0-beta.10 → 3.0.0-beta.11
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/components/ArrayContainer.d.ts +17 -5
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +2 -2
- package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +6 -3
- package/dist/components/common/useDataSourceEntityCollectionTableController.d.ts +1 -1
- package/dist/core/EntityEditView.d.ts +1 -1
- package/dist/core/FireCMS.d.ts +1 -1
- package/dist/form/PropertyFieldBinding.d.ts +1 -1
- package/dist/form/components/index.d.ts +0 -1
- package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/ReferenceFieldBinding.d.ts +2 -2
- package/dist/form/field_bindings/SwitchFieldBinding.d.ts +1 -2
- package/dist/hooks/data/delete.d.ts +4 -4
- package/dist/hooks/data/save.d.ts +3 -3
- package/dist/hooks/data/useCollectionFetch.d.ts +1 -1
- package/dist/hooks/data/useEntityFetch.d.ts +3 -3
- package/dist/hooks/useAuthController.d.ts +1 -1
- package/dist/hooks/useBuildNavigationController.d.ts +3 -3
- package/dist/hooks/useFireCMSContext.d.ts +1 -1
- package/dist/hooks/useResolvedNavigationFrom.d.ts +3 -3
- package/dist/hooks/useValidateAuthenticator.d.ts +3 -3
- package/dist/index.es.js +17515 -14786
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +17912 -15184
- 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/util.d.ts +3 -3
- package/dist/types/auth.d.ts +7 -9
- package/dist/types/collections.d.ts +14 -13
- package/dist/types/datasource.d.ts +0 -4
- package/dist/types/entity_actions.d.ts +4 -4
- package/dist/types/entity_callbacks.d.ts +16 -16
- package/dist/types/export_import.d.ts +4 -4
- package/dist/types/fields.d.ts +18 -2
- package/dist/types/firecms.d.ts +2 -2
- package/dist/types/firecms_context.d.ts +1 -1
- package/dist/types/permissions.d.ts +4 -4
- package/dist/types/plugins.d.ts +8 -8
- package/dist/types/property_config.d.ts +0 -2
- package/dist/types/user.d.ts +1 -0
- package/dist/util/builders.d.ts +2 -2
- package/dist/util/entities.d.ts +1 -1
- package/dist/util/icon_synonyms.d.ts +0 -1
- package/dist/util/icons.d.ts +3 -1
- package/dist/util/objects.d.ts +1 -0
- package/dist/util/permissions.d.ts +4 -4
- package/dist/util/property_utils.d.ts +2 -2
- package/dist/util/resolutions.d.ts +6 -6
- package/package.json +131 -125
- package/src/app/Scaffold.tsx +4 -4
- package/src/components/ArrayContainer.tsx +79 -17
- package/src/components/CircularProgressCenter.tsx +1 -1
- package/src/components/ConfirmationDialog.tsx +2 -2
- package/src/components/DeleteEntityDialog.tsx +9 -18
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +4 -1
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +14 -14
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +2 -2
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +6 -4
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +8 -9
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +5 -11
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +2 -2
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +5 -5
- package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +2 -2
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +79 -69
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +9 -10
- package/src/components/EntityCollectionView/useSelectionController.tsx +5 -4
- package/src/components/EntityPreview.tsx +39 -30
- package/src/components/EntityView.tsx +5 -5
- package/src/components/ErrorView.tsx +3 -3
- package/src/components/HomePage/DefaultHomePage.tsx +1 -0
- package/src/components/HomePage/FavouritesView.tsx +6 -11
- package/src/components/HomePage/NavigationCard.tsx +1 -1
- package/src/components/HomePage/NavigationCardBinding.tsx +4 -9
- package/src/components/HomePage/NavigationGroup.tsx +1 -1
- package/src/components/PropertyConfigBadge.tsx +1 -1
- package/src/components/PropertyIdCopyTooltip.tsx +1 -1
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +2 -2
- package/src/components/SelectableTable/SelectableTable.tsx +2 -2
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +4 -2
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +3 -1
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +7 -5
- package/src/components/VirtualTable/VirtualTableHeader.tsx +8 -8
- package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +1 -1
- package/src/components/VirtualTable/VirtualTableRow.tsx +1 -1
- package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +1 -1
- package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +2 -0
- package/src/components/common/useDataSourceEntityCollectionTableController.tsx +2 -2
- package/src/contexts/SnackbarProvider.tsx +2 -0
- package/src/core/DefaultAppBar.tsx +12 -11
- package/src/core/DefaultDrawer.tsx +11 -9
- package/src/core/DrawerNavigationItem.tsx +4 -4
- package/src/core/EntityEditView.tsx +50 -52
- package/src/core/FireCMS.tsx +5 -5
- package/src/core/SideDialogs.tsx +1 -1
- package/src/core/field_configs.tsx +4 -4
- package/src/form/PropertyFieldBinding.tsx +27 -20
- package/src/form/components/CustomIdField.tsx +2 -0
- package/src/form/components/StorageItemPreview.tsx +3 -3
- package/src/form/components/index.tsx +0 -1
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +3 -2
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +16 -10
- package/src/form/field_bindings/BlockFieldBinding.tsx +41 -23
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +10 -7
- package/src/form/field_bindings/MapFieldBinding.tsx +58 -39
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +4 -4
- package/src/form/field_bindings/RepeatFieldBinding.tsx +25 -20
- package/src/form/field_bindings/SelectFieldBinding.tsx +5 -4
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +1 -1
- package/src/form/field_bindings/SwitchFieldBinding.tsx +25 -25
- package/src/form/field_bindings/TextFieldBinding.tsx +3 -3
- package/src/hooks/data/delete.ts +4 -4
- package/src/hooks/data/save.ts +7 -8
- package/src/hooks/data/useCollectionFetch.tsx +2 -2
- package/src/hooks/data/useEntityFetch.tsx +5 -5
- package/src/hooks/useAuthController.tsx +1 -1
- package/src/hooks/useBuildNavigationController.tsx +5 -6
- package/src/hooks/useFireCMSContext.tsx +5 -5
- package/src/hooks/useResolvedNavigationFrom.tsx +5 -5
- package/src/hooks/useValidateAuthenticator.tsx +3 -3
- package/src/internal/useBuildDataSource.ts +1 -1
- package/src/internal/useUnsavedChangesDialog.tsx +2 -2
- package/src/preview/PropertyPreview.tsx +3 -3
- package/src/preview/PropertyPreviewProps.tsx +1 -1
- package/src/preview/components/BooleanPreview.tsx +1 -1
- package/src/preview/components/EmptyValue.tsx +1 -1
- package/src/preview/components/EnumValuesChip.tsx +1 -1
- package/src/preview/components/ImagePreview.tsx +5 -6
- package/src/preview/components/UrlComponentPreview.tsx +4 -4
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +2 -2
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +2 -2
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -2
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +2 -2
- package/src/preview/property_previews/MapPropertyPreview.tsx +4 -4
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +12 -12
- package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
- package/src/preview/util.ts +10 -10
- package/src/types/auth.tsx +8 -12
- package/src/types/collections.ts +14 -13
- package/src/types/datasource.ts +0 -5
- package/src/types/entity_actions.tsx +4 -4
- package/src/types/entity_callbacks.ts +18 -18
- package/src/types/export_import.ts +4 -4
- package/src/types/fields.tsx +20 -2
- package/src/types/firecms.tsx +2 -2
- package/src/types/firecms_context.tsx +1 -1
- package/src/types/permissions.ts +5 -5
- package/src/types/plugins.tsx +8 -8
- package/src/types/property_config.tsx +0 -2
- package/src/types/user.ts +2 -0
- package/src/util/builders.ts +6 -6
- package/src/util/entities.ts +3 -1
- package/src/util/icon_list.ts +1 -0
- package/src/util/icon_synonyms.ts +0 -1
- package/src/util/icons.tsx +12 -8
- package/src/util/objects.ts +20 -0
- package/src/util/permissions.ts +8 -8
- package/src/util/property_utils.tsx +10 -3
- package/src/util/references.ts +8 -2
- package/src/util/resolutions.ts +8 -8
- package/src/util/useStorageUploadController.tsx +1 -1
- package/dist/form/components/FormikArrayContainer.d.ts +0 -19
- package/src/form/components/FormikArrayContainer.tsx +0 -47
|
@@ -77,19 +77,21 @@ export const DefaultAppBar = function DefaultAppBar({
|
|
|
77
77
|
|
|
78
78
|
const user = userProp ?? authController.user;
|
|
79
79
|
|
|
80
|
-
let avatarComponent: JSX.Element;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
let avatarComponent: JSX.Element | null;
|
|
81
|
+
|
|
82
|
+
if (user) {
|
|
83
|
+
const initial = user?.displayName
|
|
84
|
+
? user.displayName[0].toUpperCase()
|
|
85
|
+
: (user?.email ? user.email[0].toUpperCase() : "A");
|
|
86
|
+
avatarComponent = <Avatar src={user.photoURL ?? undefined}>
|
|
87
|
+
{initial}
|
|
88
|
+
</Avatar>;
|
|
84
89
|
} else if (user === undefined || authController.initialLoading) {
|
|
85
90
|
avatarComponent = <div className={"p-1 flex justify-center"}>
|
|
86
91
|
<Skeleton className={"w-10 h-10 rounded-full"}/>
|
|
87
92
|
</div>;
|
|
88
93
|
} else {
|
|
89
|
-
|
|
90
|
-
? user.displayName[0].toUpperCase()
|
|
91
|
-
: (user?.email ? user.email[0].toUpperCase() : "A");
|
|
92
|
-
avatarComponent = <Avatar>{initial}</Avatar>;
|
|
94
|
+
avatarComponent = null;
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
return (
|
|
@@ -108,7 +110,7 @@ export const DefaultAppBar = function DefaultAppBar({
|
|
|
108
110
|
|
|
109
111
|
{navigation && <div className="mr-8 hidden lg:block">
|
|
110
112
|
<ReactLink
|
|
111
|
-
className="visited:text-inherit visited:dark:text-inherit"
|
|
113
|
+
className="visited:text-inherit visited:dark:text-inherit block"
|
|
112
114
|
to={navigation?.basePath ?? "/"}
|
|
113
115
|
>
|
|
114
116
|
<div className={"flex flex-row gap-4"}>
|
|
@@ -120,8 +122,7 @@ export const DefaultAppBar = function DefaultAppBar({
|
|
|
120
122
|
|
|
121
123
|
{typeof title === "string"
|
|
122
124
|
? <Typography variant="subtitle1"
|
|
123
|
-
noWrap
|
|
124
|
-
className={cls("transition-all", drawerOpen ? "ml-2" : "")}>
|
|
125
|
+
noWrap>
|
|
125
126
|
{title}
|
|
126
127
|
</Typography>
|
|
127
128
|
: title}
|
|
@@ -79,13 +79,13 @@ export function DefaultDrawer({
|
|
|
79
79
|
<DrawerLogo logo={logo}/>
|
|
80
80
|
|
|
81
81
|
<div className={"mt-4 flex-grow overflow-scroll no-scrollbar"}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
style={{
|
|
83
|
+
maskImage: "linear-gradient(to bottom, transparent 0, black 20px, black calc(100% - 20px), transparent 100%)",
|
|
84
|
+
}}>
|
|
85
85
|
|
|
86
86
|
{groupsWithoutAdmin.map((group) => (
|
|
87
87
|
<div
|
|
88
|
-
className={"bg-
|
|
88
|
+
className={"bg-surface-50 dark:bg-surface-800 dark:bg-opacity-30 my-4 rounded-lg ml-3 mr-1"}
|
|
89
89
|
key={`drawer_group_${group}`}>
|
|
90
90
|
{buildGroupHeader(group)}
|
|
91
91
|
{Object.values(navigationEntries)
|
|
@@ -93,7 +93,8 @@ export function DefaultDrawer({
|
|
|
93
93
|
.map((view, index) =>
|
|
94
94
|
<DrawerNavigationItem
|
|
95
95
|
key={`navigation_${index}`}
|
|
96
|
-
icon={<IconForView collectionOrView={view.collection ?? view.view}
|
|
96
|
+
icon={<IconForView collectionOrView={view.collection ?? view.view}
|
|
97
|
+
size={"small"}/>}
|
|
97
98
|
tooltipsOpen={tooltipsOpen}
|
|
98
99
|
adminMenuOpen={adminMenuOpen}
|
|
99
100
|
drawerOpen={drawerOpen}
|
|
@@ -112,7 +113,7 @@ export function DefaultDrawer({
|
|
|
112
113
|
trigger={
|
|
113
114
|
<IconButton
|
|
114
115
|
shape={"square"}
|
|
115
|
-
className={"m-4 text-
|
|
116
|
+
className={"m-4 text-surface-900 dark:text-white w-fit"}>
|
|
116
117
|
<Tooltip title={"Admin"}
|
|
117
118
|
open={tooltipsOpen}
|
|
118
119
|
side={"right"} sideOffset={28}>
|
|
@@ -163,18 +164,19 @@ export function DrawerLogo({ logo }: {
|
|
|
163
164
|
transition: "padding 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms",
|
|
164
165
|
padding: drawerOpen ? "32px 144px 0px 24px" : "72px 12px 0px 12px"
|
|
165
166
|
}}
|
|
166
|
-
className={cls("cursor-pointer ml-
|
|
167
|
+
className={cls("cursor-pointer rounded ml-3 mr-1")}>
|
|
167
168
|
|
|
168
169
|
<Tooltip title={"Home"}
|
|
169
170
|
sideOffset={20}
|
|
170
171
|
side="right">
|
|
171
172
|
<Link
|
|
173
|
+
className={"block"}
|
|
172
174
|
to={navigation.basePath}>
|
|
173
175
|
{logo
|
|
174
176
|
? <img src={logo}
|
|
175
177
|
alt="Logo"
|
|
176
|
-
className={cls("max-w-full max-h-full",
|
|
177
|
-
drawerOpen
|
|
178
|
+
className={cls("max-w-full max-h-full transition-all",
|
|
179
|
+
drawerOpen ? "w-[96px] h-[96px]" : "w-[32px] h-[32px]")}/>
|
|
178
180
|
: <FireCMSLogo/>}
|
|
179
181
|
|
|
180
182
|
</Link>
|
|
@@ -22,7 +22,7 @@ export function DrawerNavigationItem({
|
|
|
22
22
|
}) {
|
|
23
23
|
|
|
24
24
|
const iconWrap = <div
|
|
25
|
-
className={"text-
|
|
25
|
+
className={"text-text-secondary dark:text-text-secondary-dark"}>
|
|
26
26
|
{icon}
|
|
27
27
|
</div>;
|
|
28
28
|
|
|
@@ -34,13 +34,13 @@ export function DrawerNavigationItem({
|
|
|
34
34
|
transition: drawerOpen ? "width 150ms ease-in" : undefined
|
|
35
35
|
}}
|
|
36
36
|
className={({ isActive }: any) => cls("rounded-lg truncate",
|
|
37
|
-
"hover:bg-
|
|
37
|
+
"hover:bg-surface-accent-300 hover:bg-opacity-75 dark:hover:bg-surface-accent-800 dark:hover:bg-opacity-75 text-text-primary dark:text-surface-200 hover:text-surface-900 hover:dark:text-white",
|
|
38
38
|
"flex flex-row items-center mr-8",
|
|
39
39
|
// "transition-all ease-in-out delay-100 duration-300",
|
|
40
40
|
// drawerOpen ? "w-full" : "w-18",
|
|
41
41
|
drawerOpen ? "pl-4 h-12" : "pl-4 h-11",
|
|
42
|
-
"font-
|
|
43
|
-
isActive ? "bg-
|
|
42
|
+
"font-semibold text-xs",
|
|
43
|
+
isActive ? "bg-surface-accent-200 bg-opacity-60 dark:bg-surface-800 dark:bg-opacity-50" : ""
|
|
44
44
|
)}
|
|
45
45
|
to={url}
|
|
46
46
|
>
|
|
@@ -95,16 +95,16 @@ export interface EntityEditViewProps<M extends Record<string, any>> {
|
|
|
95
95
|
* You probably don't want to use this view directly since it is bound to the
|
|
96
96
|
* side panel.
|
|
97
97
|
*/
|
|
98
|
-
export function EntityEditView<M extends Record<string, any>,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
export function EntityEditView<M extends Record<string, any>, USER extends User>({
|
|
99
|
+
entityId,
|
|
100
|
+
...props
|
|
101
|
+
}: EntityEditViewProps<M>) {
|
|
102
102
|
const {
|
|
103
103
|
entity,
|
|
104
104
|
dataLoading,
|
|
105
105
|
// eslint-disable-next-line no-unused-vars
|
|
106
106
|
dataLoadingError
|
|
107
|
-
} = useEntityFetch<M,
|
|
107
|
+
} = useEntityFetch<M, USER>({
|
|
108
108
|
path: props.path,
|
|
109
109
|
entityId: entityId,
|
|
110
110
|
collection: props.collection,
|
|
@@ -185,7 +185,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
185
185
|
collection: inputCollection,
|
|
186
186
|
path,
|
|
187
187
|
values: entity?.values,
|
|
188
|
-
|
|
188
|
+
propertyConfigs: customizationController.propertyConfigs
|
|
189
189
|
}), [entity?.values, path, customizationController.propertyConfigs]);
|
|
190
190
|
|
|
191
191
|
const initialStatus = copy ? "copy" : (entityIdProp ? "existing" : "new");
|
|
@@ -431,10 +431,10 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
431
431
|
return {};
|
|
432
432
|
})
|
|
433
433
|
.catch((e: any) => {
|
|
434
|
-
const errors: Record<string, string> = {};
|
|
435
|
-
e.inner.forEach((error: any) => {
|
|
436
|
-
|
|
437
|
-
});
|
|
434
|
+
// const errors: Record<string, string> = {};
|
|
435
|
+
// e.inner.forEach((error: any) => {
|
|
436
|
+
// errors[error.path] = error.message;
|
|
437
|
+
// });
|
|
438
438
|
return yupToFormErrors(e);
|
|
439
439
|
});
|
|
440
440
|
}
|
|
@@ -446,7 +446,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
446
446
|
entityId,
|
|
447
447
|
values: formex.values,
|
|
448
448
|
previousValues: formex.initialValues,
|
|
449
|
-
|
|
449
|
+
propertyConfigs: customizationController.propertyConfigs
|
|
450
450
|
});
|
|
451
451
|
|
|
452
452
|
const lastSavedValues = useRef<EntityValues<M> | undefined>(entity?.values);
|
|
@@ -778,12 +778,14 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
778
778
|
|
|
779
779
|
const child = Builder
|
|
780
780
|
? <Builder entity={entity} context={context}/>
|
|
781
|
-
: <>
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
781
|
+
: <>
|
|
782
|
+
{additionalField.value?.({
|
|
783
|
+
entity,
|
|
784
|
+
context
|
|
785
|
+
})?.toString()}
|
|
786
|
+
</>;
|
|
785
787
|
return (
|
|
786
|
-
<div>
|
|
788
|
+
<div key={`additional_${key}`}>
|
|
787
789
|
<LabelWithIconAndTooltip
|
|
788
790
|
propertyKey={key}
|
|
789
791
|
icon={<NotesIcon size={"small"}/>}
|
|
@@ -806,8 +808,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
806
808
|
})
|
|
807
809
|
.filter(Boolean)}
|
|
808
810
|
|
|
809
|
-
</>
|
|
810
|
-
);
|
|
811
|
+
</>);
|
|
811
812
|
|
|
812
813
|
const disabled = formex.isSubmitting || (!modified && status === "existing");
|
|
813
814
|
const formRef = React.useRef<HTMLDivElement>(null);
|
|
@@ -888,49 +889,46 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
888
889
|
let form = <>
|
|
889
890
|
|
|
890
891
|
{pluginActions.length > 0 && <div
|
|
891
|
-
className={cls("w-full flex justify-end items-center sticky top-0 right-0 left-0 z-10 bg-opacity-60 bg-
|
|
892
|
+
className={cls("w-full flex justify-end items-center sticky top-0 right-0 left-0 z-10 bg-opacity-60 bg-surface-accent-200 dark:bg-opacity-60 dark:bg-surface-accent-800 backdrop-blur-md")}>
|
|
892
893
|
{pluginActions}
|
|
893
894
|
</div>}
|
|
894
895
|
|
|
895
|
-
<div className="
|
|
896
|
+
<div className="pt-12 pb-16 pl-4 sm:px-8 md:px-10">
|
|
897
|
+
<div
|
|
898
|
+
className={`w-full py-2 flex flex-col items-start mt-${4 + (pluginActions ? 8 : 0)} lg:mt-${8 + (pluginActions ? 8 : 0)} mb-8`}>
|
|
896
899
|
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
<Alert color={"base"} className={"w-full"} size={"small"}>
|
|
906
|
-
<code className={"text-xs select-all"}>{path}/{entityId}</code>
|
|
907
|
-
</Alert>
|
|
908
|
-
</div>
|
|
900
|
+
<Typography
|
|
901
|
+
className={"mt-4 flex-grow line-clamp-1 " + inputCollection.hideIdFromForm ? "mb-2" : "mb-0"}
|
|
902
|
+
variant={"h4"}>{title ?? inputCollection.singularName ?? inputCollection.name}
|
|
903
|
+
</Typography>
|
|
904
|
+
<Alert color={"base"} className={"w-full"} size={"small"}>
|
|
905
|
+
<code className={"text-xs select-all"}>{path}/{entityId}</code>
|
|
906
|
+
</Alert>
|
|
907
|
+
</div>
|
|
909
908
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
909
|
+
{!collection.hideIdFromForm &&
|
|
910
|
+
<CustomIdField customId={inputCollection.customId}
|
|
911
|
+
entityId={entityId}
|
|
912
|
+
status={status}
|
|
913
|
+
onChange={setEntityId}
|
|
914
|
+
error={entityIdError}
|
|
915
|
+
loading={customIdLoading}
|
|
916
|
+
entity={entity}/>}
|
|
918
917
|
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
918
|
+
{entityId && formContext && <>
|
|
919
|
+
<div className="mt-12 flex flex-col gap-8"
|
|
920
|
+
ref={formRef}>
|
|
922
921
|
|
|
923
|
-
|
|
922
|
+
{formFields}
|
|
924
923
|
|
|
925
|
-
|
|
924
|
+
<ErrorFocus containerRef={formRef}/>
|
|
926
925
|
|
|
927
|
-
|
|
926
|
+
</div>
|
|
928
927
|
|
|
929
|
-
|
|
928
|
+
<div className="h-14"/>
|
|
930
929
|
|
|
931
|
-
|
|
930
|
+
</>}
|
|
932
931
|
|
|
933
|
-
</div>
|
|
934
932
|
</div>
|
|
935
933
|
</>;
|
|
936
934
|
|
|
@@ -1004,10 +1002,10 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
1004
1002
|
return (
|
|
1005
1003
|
<Formex value={formex}>
|
|
1006
1004
|
|
|
1007
|
-
<div className="flex flex-col h-full w-full
|
|
1005
|
+
<div className="flex flex-col h-full w-full">
|
|
1008
1006
|
|
|
1009
1007
|
<div
|
|
1010
|
-
className={cls(defaultBorderMixin, "no-scrollbar border-b pl-2 pr-2 pt-1 flex items-end overflow-scroll bg-
|
|
1008
|
+
className={cls(defaultBorderMixin, "no-scrollbar h-16 border-b pl-2 pr-2 pt-1 flex items-end overflow-scroll bg-surface-50 dark:bg-surface-950")}>
|
|
1011
1009
|
|
|
1012
1010
|
<div
|
|
1013
1011
|
className="pb-1 self-center">
|
|
@@ -1032,7 +1030,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
1032
1030
|
onValueChange={(value) => {
|
|
1033
1031
|
onSideTabClick(value);
|
|
1034
1032
|
}}
|
|
1035
|
-
|
|
1033
|
+
innerClassName="pl-4 pr-4 pt-0">
|
|
1036
1034
|
|
|
1037
1035
|
<Tab
|
|
1038
1036
|
disabled={!hasAdditionalViews}
|
package/src/core/FireCMS.tsx
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
|
+
import React, { useMemo } from "react";
|
|
4
|
+
import { CenteredView, Typography } from "@firecms/ui";
|
|
3
5
|
import { CustomizationController, EntityCollection, FireCMSContext, FireCMSPlugin, FireCMSProps, User } from "../types";
|
|
4
6
|
import { AuthControllerContext } from "../contexts";
|
|
5
7
|
import { useBuildSideEntityController } from "../internal/useBuildSideEntityController";
|
|
@@ -12,7 +14,6 @@ import { DataSourceContext } from "../contexts/DataSourceContext";
|
|
|
12
14
|
import { SideEntityControllerContext } from "../contexts/SideEntityControllerContext";
|
|
13
15
|
import { NavigationContext } from "../contexts/NavigationContext";
|
|
14
16
|
import { SideDialogsControllerContext } from "../contexts/SideDialogsControllerContext";
|
|
15
|
-
import { CenteredView, Typography, useLocaleConfig } from "@firecms/ui";
|
|
16
17
|
import { DialogsProvider } from "../contexts/DialogsProvider";
|
|
17
18
|
import { useBuildDataSource } from "../internal/useBuildDataSource";
|
|
18
19
|
import { CustomizationControllerContext } from "../contexts/CustomizationControllerContext";
|
|
@@ -31,7 +32,7 @@ import { useProjectLog } from "../hooks/useProjectLog";
|
|
|
31
32
|
|
|
32
33
|
* @group Core
|
|
33
34
|
*/
|
|
34
|
-
export function FireCMS<
|
|
35
|
+
export function FireCMS<USER extends User, EC extends EntityCollection>(props: FireCMSProps<USER, EC>) {
|
|
35
36
|
|
|
36
37
|
const {
|
|
37
38
|
children,
|
|
@@ -51,8 +52,6 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
|
|
|
51
52
|
apiKey
|
|
52
53
|
} = props;
|
|
53
54
|
|
|
54
|
-
useLocaleConfig(locale);
|
|
55
|
-
|
|
56
55
|
/**
|
|
57
56
|
* Controller in charge of fetching and persisting data
|
|
58
57
|
*/
|
|
@@ -89,6 +88,7 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
|
|
|
89
88
|
dataSourceDelegate,
|
|
90
89
|
plugins
|
|
91
90
|
});
|
|
91
|
+
|
|
92
92
|
if (accessResponse?.message) {
|
|
93
93
|
console.warn(accessResponse.message);
|
|
94
94
|
}
|
package/src/core/SideDialogs.tsx
CHANGED
|
@@ -130,7 +130,7 @@ function SideDialogView({
|
|
|
130
130
|
>
|
|
131
131
|
{panel &&
|
|
132
132
|
<div
|
|
133
|
-
className={"transform max-w-[100vw] lg:max-w-[95vw] flex flex-col h-full transition-all duration-250 ease-in-out bg-white dark:bg-
|
|
133
|
+
className={"transform max-w-[100vw] lg:max-w-[95vw] flex flex-col h-full transition-all duration-250 ease-in-out bg-white dark:bg-surface-900 "}
|
|
134
134
|
style={{
|
|
135
135
|
width: panel.width,
|
|
136
136
|
transform: `translateX(-${offsetPosition * 200}px)`
|
|
@@ -23,7 +23,6 @@ import {
|
|
|
23
23
|
AddLinkIcon,
|
|
24
24
|
BallotIcon,
|
|
25
25
|
DriveFolderUploadIcon,
|
|
26
|
-
EmailIcon,
|
|
27
26
|
FlagIcon,
|
|
28
27
|
FormatListNumberedIcon,
|
|
29
28
|
FormatQuoteIcon,
|
|
@@ -31,6 +30,7 @@ import {
|
|
|
31
30
|
LinkIcon,
|
|
32
31
|
ListAltIcon,
|
|
33
32
|
ListIcon,
|
|
33
|
+
MailIcon,
|
|
34
34
|
NumbersIcon,
|
|
35
35
|
RepeatIcon,
|
|
36
36
|
ScheduleIcon,
|
|
@@ -96,7 +96,7 @@ export const DEFAULT_FIELD_CONFIGS: Record<string, PropertyConfig<any>> = {
|
|
|
96
96
|
key: "email",
|
|
97
97
|
name: "Email",
|
|
98
98
|
description: "Text with email validation",
|
|
99
|
-
Icon:
|
|
99
|
+
Icon: MailIcon,
|
|
100
100
|
color: "#154fb3",
|
|
101
101
|
property: {
|
|
102
102
|
dataType: "string",
|
|
@@ -129,7 +129,7 @@ export const DEFAULT_FIELD_CONFIGS: Record<string, PropertyConfig<any>> = {
|
|
|
129
129
|
},
|
|
130
130
|
multi_select: {
|
|
131
131
|
key: "multi_select",
|
|
132
|
-
name: "Multi select",
|
|
132
|
+
name: "Multi select (enum)",
|
|
133
133
|
description: "Select multiple text values from within an enumeration",
|
|
134
134
|
Icon: ListAltIcon,
|
|
135
135
|
color: "#4223c9",
|
|
@@ -300,7 +300,7 @@ export const DEFAULT_FIELD_CONFIGS: Record<string, PropertyConfig<any>> = {
|
|
|
300
300
|
block: {
|
|
301
301
|
key: "block",
|
|
302
302
|
name: "Block",
|
|
303
|
-
description: "A complex field that allows the user to compose different fields together, with a key
|
|
303
|
+
description: "A complex field that allows the user to compose different fields together, with a key/value format",
|
|
304
304
|
Icon: ViewStreamIcon,
|
|
305
305
|
color: "#ff9408",
|
|
306
306
|
property: {
|
|
@@ -81,12 +81,13 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
|
|
|
81
81
|
context,
|
|
82
82
|
includeDescription,
|
|
83
83
|
underlyingValueHasChanged,
|
|
84
|
-
disabled,
|
|
84
|
+
disabled: disabledProp,
|
|
85
85
|
partOfArray,
|
|
86
86
|
minimalistView,
|
|
87
87
|
autoFocus,
|
|
88
88
|
index,
|
|
89
|
-
size
|
|
89
|
+
size,
|
|
90
|
+
onPropertyChange
|
|
90
91
|
}: PropertyFieldBindingProps<T, M>): ReactElement<PropertyFieldBindingProps<T, M>> {
|
|
91
92
|
|
|
92
93
|
const customizationController = useCustomizationController();
|
|
@@ -105,10 +106,12 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
|
|
|
105
106
|
values: fieldProps.form.values,
|
|
106
107
|
path: context.path,
|
|
107
108
|
entityId: context.entityId,
|
|
108
|
-
|
|
109
|
+
propertyConfigs: customizationController.propertyConfigs,
|
|
109
110
|
index
|
|
110
111
|
});
|
|
111
112
|
|
|
113
|
+
const disabled = disabledProp || isReadOnly(resolvedProperty) || Boolean(resolvedProperty?.disabled);
|
|
114
|
+
|
|
112
115
|
if (resolvedProperty === null || isHidden(resolvedProperty)) {
|
|
113
116
|
return <></>;
|
|
114
117
|
} else if (isReadOnly(resolvedProperty)) {
|
|
@@ -122,6 +125,7 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
|
|
|
122
125
|
if (!propertyConfig) {
|
|
123
126
|
console.log("INTERNAL: Could not find field config for property", {
|
|
124
127
|
propertyKey,
|
|
128
|
+
property,
|
|
125
129
|
resolvedProperty,
|
|
126
130
|
fields: customizationController.propertyConfigs,
|
|
127
131
|
propertyConfig
|
|
@@ -134,7 +138,7 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
|
|
|
134
138
|
values: fieldProps.form.values,
|
|
135
139
|
path: context.path,
|
|
136
140
|
entityId: context.entityId,
|
|
137
|
-
|
|
141
|
+
propertyConfigs: customizationController.propertyConfigs,
|
|
138
142
|
index
|
|
139
143
|
});
|
|
140
144
|
Component = configProperty.Field as ComponentType<FieldProps<T>>;
|
|
@@ -157,13 +161,14 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
|
|
|
157
161
|
partOfArray,
|
|
158
162
|
minimalistView,
|
|
159
163
|
autoFocus,
|
|
160
|
-
size
|
|
164
|
+
size,
|
|
165
|
+
onPropertyChange
|
|
161
166
|
};
|
|
162
167
|
|
|
163
168
|
return <FieldInternal
|
|
164
169
|
Component={Component as ComponentType<FieldProps>}
|
|
165
170
|
componentProps={componentProps}
|
|
166
|
-
|
|
171
|
+
formexFieldProps={fieldProps}/>;
|
|
167
172
|
}}
|
|
168
173
|
</Field>
|
|
169
174
|
);
|
|
@@ -189,26 +194,27 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
|
|
|
189
194
|
autoFocus,
|
|
190
195
|
context,
|
|
191
196
|
disabled,
|
|
192
|
-
size
|
|
197
|
+
size,
|
|
198
|
+
onPropertyChange
|
|
193
199
|
},
|
|
194
|
-
|
|
200
|
+
formexFieldProps
|
|
195
201
|
}:
|
|
196
202
|
{
|
|
197
203
|
Component: ComponentType<FieldProps<T, any, M>>,
|
|
198
204
|
componentProps: ResolvedPropertyFieldBindingProps<T, M>,
|
|
199
|
-
|
|
205
|
+
formexFieldProps: FormexFieldProps<T, any>
|
|
200
206
|
}) {
|
|
201
207
|
|
|
202
208
|
const { plugins } = useCustomizationController();
|
|
203
209
|
|
|
204
210
|
const customFieldProps: any = property.customProps;
|
|
205
|
-
const value =
|
|
206
|
-
// const initialValue =
|
|
207
|
-
const error = getIn(
|
|
208
|
-
const touched = getIn(
|
|
211
|
+
const value = formexFieldProps.field.value;
|
|
212
|
+
// const initialValue = formexFieldProps.meta.initialValue;
|
|
213
|
+
const error = getIn(formexFieldProps.form.errors, propertyKey);
|
|
214
|
+
const touched = getIn(formexFieldProps.form.touched, propertyKey);
|
|
209
215
|
|
|
210
216
|
const showError: boolean = error &&
|
|
211
|
-
(
|
|
217
|
+
(formexFieldProps.form.submitCount > 0 || property.validation?.unique) &&
|
|
212
218
|
(!Array.isArray(error) || !!error.filter((e: any) => !!e).length);
|
|
213
219
|
|
|
214
220
|
const WrappedComponent: ComponentType<FieldProps<T, any, M>> | null = useWrappedComponent({
|
|
@@ -221,16 +227,16 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
|
|
|
221
227
|
});
|
|
222
228
|
const UsedComponent: ComponentType<FieldProps<T>> = WrappedComponent ?? Component;
|
|
223
229
|
|
|
224
|
-
const isSubmitting =
|
|
230
|
+
const isSubmitting = formexFieldProps.form.isSubmitting;
|
|
225
231
|
|
|
226
232
|
const setValue = useCallback((value: T | null, shouldValidate?: boolean) => {
|
|
227
|
-
|
|
228
|
-
|
|
233
|
+
formexFieldProps.form.setFieldTouched(propertyKey, true, false);
|
|
234
|
+
formexFieldProps.form.setFieldValue(propertyKey, value, shouldValidate);
|
|
229
235
|
}, []);
|
|
230
236
|
|
|
231
237
|
const setFieldValue = useCallback((otherPropertyKey: string, value: CMSType | null, shouldValidate?: boolean) => {
|
|
232
|
-
|
|
233
|
-
|
|
238
|
+
formexFieldProps.form.setFieldTouched(propertyKey, true, false);
|
|
239
|
+
formexFieldProps.form.setFieldValue(otherPropertyKey, value, shouldValidate);
|
|
234
240
|
}, []);
|
|
235
241
|
|
|
236
242
|
const cmsFieldProps: FieldProps<T, CustomProps, M> = {
|
|
@@ -251,7 +257,8 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
|
|
|
251
257
|
autoFocus: autoFocus ?? false,
|
|
252
258
|
customProps: customFieldProps,
|
|
253
259
|
context,
|
|
254
|
-
size
|
|
260
|
+
size,
|
|
261
|
+
onPropertyChange
|
|
255
262
|
};
|
|
256
263
|
|
|
257
264
|
return (
|
|
@@ -100,7 +100,9 @@ export function CustomIdField<M extends Record<string, any>>({
|
|
|
100
100
|
|
|
101
101
|
{enumValues &&
|
|
102
102
|
<Select
|
|
103
|
+
size={"large"}
|
|
103
104
|
error={error}
|
|
105
|
+
fullWidth={true}
|
|
104
106
|
onValueChange={(v) => onChange(v as string)}
|
|
105
107
|
{...fieldProps}
|
|
106
108
|
renderValue={(option) => {
|
|
@@ -31,12 +31,12 @@ export function StorageItemPreview({
|
|
|
31
31
|
return (
|
|
32
32
|
<div className={cls(paperMixin,
|
|
33
33
|
"relative m-4 border-box flex items-center justify-center",
|
|
34
|
-
size === "
|
|
34
|
+
size === "large" ? "min-w-[220px] min-h-[220px] max-w-[220px]" : "min-w-[118px] min-h-[118px] max-w-[118px]",
|
|
35
35
|
className)}>
|
|
36
36
|
|
|
37
37
|
{!placeholder && !disabled &&
|
|
38
38
|
<div
|
|
39
|
-
className="absolute rounded-full -top-2 -right-2 z-10 bg-white dark:bg-
|
|
39
|
+
className="absolute rounded-full -top-2 -right-2 z-10 bg-white dark:bg-surface-900">
|
|
40
40
|
|
|
41
41
|
<Tooltip
|
|
42
42
|
asChild={true}
|
|
@@ -67,7 +67,7 @@ export function StorageItemPreview({
|
|
|
67
67
|
<div
|
|
68
68
|
onClick={(e) => e.stopPropagation()}
|
|
69
69
|
className="flex flex-col items-center justify-center w-full h-full">
|
|
70
|
-
<DescriptionIcon className="text-
|
|
70
|
+
<DescriptionIcon className="text-surface-700 dark:text-surface-300"/>
|
|
71
71
|
</div>
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -3,7 +3,7 @@ import { FieldProps } from "../../types";
|
|
|
3
3
|
import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
|
|
4
4
|
import { PropertyFieldBinding } from "../PropertyFieldBinding";
|
|
5
5
|
import { ExpandablePanel, Typography } from "@firecms/ui";
|
|
6
|
-
import { getArrayResolvedProperties, getIconForProperty } from "../../util";
|
|
6
|
+
import { getArrayResolvedProperties, getIconForProperty, isReadOnly } from "../../util";
|
|
7
7
|
import { useClearRestoreValue } from "../useClearRestoreValue";
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -57,9 +57,10 @@ export function ArrayCustomShapedFieldBinding<T extends Array<any>>({
|
|
|
57
57
|
</>);
|
|
58
58
|
|
|
59
59
|
const body = resolvedProperties.map((childProperty, index) => {
|
|
60
|
+
const thisDisabled = isReadOnly(childProperty) || Boolean(childProperty.disabled);
|
|
60
61
|
const fieldProps = {
|
|
61
62
|
propertyKey: `${propertyKey}[${index}]`,
|
|
62
|
-
disabled,
|
|
63
|
+
disabled: disabled || thisDisabled,
|
|
63
64
|
property: childProperty,
|
|
64
65
|
includeDescription,
|
|
65
66
|
underlyingValueHasChanged,
|