@firecms/core 3.0.0-canary.204 → 3.0.0-canary.205
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/form/EntityForm.d.ts +0 -10
- package/dist/index.es.js +155 -387
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +155 -387
- package/dist/index.umd.js.map +1 -1
- package/dist/internal/useBuildSideEntityController.d.ts +2 -2
- package/dist/util/resolutions.d.ts +6 -1
- package/package.json +5 -5
- package/src/core/EntityEditView.tsx +14 -50
- package/src/core/EntitySidePanel.tsx +2 -2
- package/src/form/EntityForm.tsx +56 -98
- package/src/internal/useBuildSideEntityController.tsx +28 -14
- package/src/util/resolutions.ts +26 -5
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EntityCollection, EntitySidePanelProps, NavigationController, SideDialogsController, SideEntityController } from "../types";
|
|
2
|
-
export declare function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean): string;
|
|
1
|
+
import { CustomizationController, EntityCollection, EntitySidePanelProps, NavigationController, SideDialogsController, SideEntityController } from "../types";
|
|
2
|
+
export declare function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean, customizationController: CustomizationController): string;
|
|
3
3
|
export declare const useBuildSideEntityController: (navigation: NavigationController, sideDialogsController: SideDialogsController) => SideEntityController;
|
|
4
4
|
export declare function buildSidePanelsFromUrl(path: string, collections: EntityCollection[], newFlag: boolean): EntitySidePanelProps<any>[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ArrayProperty, CMSType, EntityCollection, EntityCustomView, EntityValues, EnumValueConfig, EnumValues, NumberProperty, PropertiesOrBuilders, PropertyConfig, PropertyOrBuilder, ResolvedArrayProperty, ResolvedEntityCollection, ResolvedNumberProperty, ResolvedProperties, ResolvedProperty, ResolvedStringProperty, StringProperty, UserConfigurationPersistence } from "../types";
|
|
1
|
+
import { ArrayProperty, CMSType, CustomizationController, EntityCollection, EntityCustomView, EntityValues, EnumValueConfig, EnumValues, NumberProperty, PropertiesOrBuilders, PropertyConfig, PropertyOrBuilder, ResolvedArrayProperty, ResolvedEntityCollection, ResolvedNumberProperty, ResolvedProperties, ResolvedProperty, ResolvedStringProperty, StringProperty, UserConfigurationPersistence } from "../types";
|
|
2
2
|
export declare const resolveCollection: <M extends Record<string, any>>({ collection, path, entityId, values, previousValues, userConfigPersistence, propertyConfigs, ignoreMissingFields }: {
|
|
3
3
|
collection: EntityCollection<M> | ResolvedEntityCollection<M>;
|
|
4
4
|
path: string;
|
|
@@ -76,3 +76,8 @@ export declare function resolveProperties<M extends Record<string, any>>({ prope
|
|
|
76
76
|
export declare function resolvePropertyEnum(property: StringProperty | NumberProperty, fromBuilder?: boolean): ResolvedStringProperty | ResolvedNumberProperty;
|
|
77
77
|
export declare function resolveEnumValues(input: EnumValues): EnumValueConfig[] | undefined;
|
|
78
78
|
export declare function resolveEntityView(entityView: string | EntityCustomView<any>, contextEntityViews?: EntityCustomView<any>[]): EntityCustomView<any> | undefined;
|
|
79
|
+
export declare function resolvedSelectedEntityView<M extends Record<string, any>>(customViews: (string | EntityCustomView<M>)[] | undefined, customizationController: CustomizationController, selectedTab?: string): {
|
|
80
|
+
resolvedEntityViews: EntityCustomView[];
|
|
81
|
+
selectedEntityView: EntityCustomView | undefined;
|
|
82
|
+
selectedSecondaryForm: EntityCustomView | undefined;
|
|
83
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firecms/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0.0-canary.
|
|
4
|
+
"version": "3.0.0-canary.205",
|
|
5
5
|
"description": "Awesome Firebase/Firestore-based headless open-source CMS",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/firecmsco"
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"./package.json": "./package.json"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@firecms/editor": "^3.0.0-canary.
|
|
54
|
-
"@firecms/formex": "^3.0.0-canary.
|
|
55
|
-
"@firecms/ui": "^3.0.0-canary.
|
|
53
|
+
"@firecms/editor": "^3.0.0-canary.205",
|
|
54
|
+
"@firecms/formex": "^3.0.0-canary.205",
|
|
55
|
+
"@firecms/ui": "^3.0.0-canary.205",
|
|
56
56
|
"@hello-pangea/dnd": "^17.0.0",
|
|
57
57
|
"@radix-ui/react-portal": "^1.1.3",
|
|
58
58
|
"clsx": "^2.1.1",
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
"dist",
|
|
105
105
|
"src"
|
|
106
106
|
],
|
|
107
|
-
"gitHead": "
|
|
107
|
+
"gitHead": "b3a2a795ce5eb7edc68efea5caa69b8d477901be",
|
|
108
108
|
"publishConfig": {
|
|
109
109
|
"access": "public"
|
|
110
110
|
},
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import React, { useEffect, useMemo, useState } from "react";
|
|
2
|
-
import { Entity, EntityCollection,
|
|
2
|
+
import { Entity, EntityCollection, EntityStatus, FireCMSPlugin, FormContext, User } from "../types";
|
|
3
3
|
|
|
4
4
|
import { CircularProgressCenter, EntityCollectionView, EntityView, ErrorBoundary } from "../components";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
canEditEntity,
|
|
7
|
+
removeInitialAndTrailingSlashes,
|
|
8
|
+
resolveDefaultSelectedView,
|
|
9
|
+
resolvedSelectedEntityView
|
|
10
|
+
} from "../util";
|
|
6
11
|
|
|
7
12
|
import {
|
|
8
13
|
useAuthController,
|
|
@@ -13,7 +18,7 @@ import {
|
|
|
13
18
|
} from "../hooks";
|
|
14
19
|
import { CircularProgress, cls, defaultBorderMixin, Tab, Tabs, Typography } from "@firecms/ui";
|
|
15
20
|
import { getEntityFromCache } from "../util/entity_cache";
|
|
16
|
-
import { EntityForm, EntityFormProps
|
|
21
|
+
import { EntityForm, EntityFormProps } from "../form";
|
|
17
22
|
import { EntityEditViewFormActions } from "./EntityEditViewFormActions";
|
|
18
23
|
|
|
19
24
|
const MAIN_TAB_VALUE = "main_##Q$SC^#S6";
|
|
@@ -120,43 +125,6 @@ export function EntityEditView<M extends Record<string, any>, USER extends User>
|
|
|
120
125
|
/>;
|
|
121
126
|
}
|
|
122
127
|
|
|
123
|
-
function SecondaryForm<M extends object>({
|
|
124
|
-
collection,
|
|
125
|
-
className,
|
|
126
|
-
customView,
|
|
127
|
-
entity,
|
|
128
|
-
formContext,
|
|
129
|
-
forceActionsAtTheBottom,
|
|
130
|
-
}: {
|
|
131
|
-
className?: string,
|
|
132
|
-
customView: EntityCustomView,
|
|
133
|
-
formContext: FormContext<M>,
|
|
134
|
-
collection: EntityCollection<M>,
|
|
135
|
-
forceActionsAtTheBottom?: boolean,
|
|
136
|
-
entity: Entity<M> | undefined,
|
|
137
|
-
}) {
|
|
138
|
-
|
|
139
|
-
if (!customView.Builder) {
|
|
140
|
-
console.error("customView.Builder is not defined");
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return <FormLayoutInner
|
|
145
|
-
className={className}
|
|
146
|
-
forceActionsAtTheBottom={forceActionsAtTheBottom}
|
|
147
|
-
formContext={formContext}
|
|
148
|
-
EntityFormActionsComponent={EntityEditViewFormActions}>
|
|
149
|
-
<ErrorBoundary>
|
|
150
|
-
{formContext && <customView.Builder
|
|
151
|
-
collection={collection}
|
|
152
|
-
entity={entity}
|
|
153
|
-
modifiedValues={formContext.formex.values ?? entity?.values}
|
|
154
|
-
formContext={formContext}
|
|
155
|
-
/>}
|
|
156
|
-
</ErrorBoundary>
|
|
157
|
-
</FormLayoutInner>;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
128
|
export function EntityEditViewInner<M extends Record<string, any>>({
|
|
161
129
|
path,
|
|
162
130
|
entityId,
|
|
@@ -220,15 +188,11 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
220
188
|
const customViewsCount = customViews?.length ?? 0;
|
|
221
189
|
const hasAdditionalViews = customViewsCount > 0 || subcollectionsCount > 0;
|
|
222
190
|
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
const selectedEntityView = resolvedEntityViews.find(e => e.key === selectedTab);
|
|
229
|
-
const selectedSecondaryForm = formContext
|
|
230
|
-
&& customViews
|
|
231
|
-
&& resolvedEntityViews.filter(e => e.includeActions).find(e => e.key === selectedTab);
|
|
191
|
+
const {
|
|
192
|
+
resolvedEntityViews,
|
|
193
|
+
selectedEntityView,
|
|
194
|
+
selectedSecondaryForm
|
|
195
|
+
} = resolvedSelectedEntityView(customViews, customizationController, selectedTab);
|
|
232
196
|
|
|
233
197
|
const actionsAtTheBottom = !largeLayout || layout === "side_panel" || selectedEntityView?.includeActions === "bottom";
|
|
234
198
|
|
|
@@ -305,7 +269,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
305
269
|
path,
|
|
306
270
|
entityId,
|
|
307
271
|
selectedTab: value === MAIN_TAB_VALUE ? undefined : value,
|
|
308
|
-
collection
|
|
272
|
+
collection,
|
|
309
273
|
});
|
|
310
274
|
}
|
|
311
275
|
};
|
|
@@ -141,14 +141,14 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
|
|
|
141
141
|
path,
|
|
142
142
|
entityId,
|
|
143
143
|
selectedTab,
|
|
144
|
-
collection
|
|
144
|
+
collection,
|
|
145
145
|
}) => {
|
|
146
146
|
sideEntityController.replace({
|
|
147
147
|
path,
|
|
148
148
|
entityId,
|
|
149
149
|
selectedTab,
|
|
150
150
|
updateUrl: true,
|
|
151
|
-
collection
|
|
151
|
+
collection,
|
|
152
152
|
});
|
|
153
153
|
}}
|
|
154
154
|
formProps={props.formProps}
|
package/src/form/EntityForm.tsx
CHANGED
|
@@ -589,7 +589,7 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
589
589
|
|
|
590
590
|
const formView = <ErrorBoundary>
|
|
591
591
|
<>
|
|
592
|
-
<div className={"w-full py-2 flex flex-col items-start my-4 lg:my-6"}>
|
|
592
|
+
{!Builder && <div className={"w-full py-2 flex flex-col items-start my-4 lg:my-6"}>
|
|
593
593
|
<Typography
|
|
594
594
|
className={"py-4 flex-grow line-clamp-1 " + (collection.hideIdFromForm ? "mb-2" : "mb-0")}
|
|
595
595
|
variant={"h4"}>
|
|
@@ -601,11 +601,11 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
601
601
|
{entity?.path ?? path}/{entityId}
|
|
602
602
|
</code>
|
|
603
603
|
</Alert>}
|
|
604
|
-
</div>
|
|
604
|
+
</div>}
|
|
605
605
|
|
|
606
606
|
{children}
|
|
607
607
|
|
|
608
|
-
{!collection.hideIdFromForm &&
|
|
608
|
+
{!Builder && !collection.hideIdFromForm &&
|
|
609
609
|
<CustomIdField customId={collection.customId}
|
|
610
610
|
entityId={entityId}
|
|
611
611
|
status={status}
|
|
@@ -631,104 +631,14 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
631
631
|
onIdChange(entityId);
|
|
632
632
|
}, [entityId, onIdChange]);
|
|
633
633
|
|
|
634
|
-
return (
|
|
635
|
-
<FormLayoutInner
|
|
636
|
-
className={className}
|
|
637
|
-
id={`form_${path}`}
|
|
638
|
-
pluginActions={pluginActions}
|
|
639
|
-
forceActionsAtTheBottom={forceActionsAtTheBottom}
|
|
640
|
-
EntityFormActionsComponent={EntityFormActionsComponent}
|
|
641
|
-
formContext={formContext}
|
|
642
|
-
showDefaultActions={showDefaultActions}>
|
|
643
|
-
{formView}
|
|
644
|
-
</FormLayoutInner>
|
|
645
|
-
);
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
function getInitialEntityValues<M extends object>(
|
|
649
|
-
collection: EntityCollection,
|
|
650
|
-
path: string,
|
|
651
|
-
status: "new" | "existing" | "copy",
|
|
652
|
-
entity: Entity<M> | undefined,
|
|
653
|
-
propertyConfigs?: Record<string, PropertyConfig>
|
|
654
|
-
): Partial<EntityValues<M>> {
|
|
655
|
-
const resolvedCollection = resolveCollection({
|
|
656
|
-
collection,
|
|
657
|
-
path,
|
|
658
|
-
values: entity?.values,
|
|
659
|
-
propertyConfigs
|
|
660
|
-
});
|
|
661
|
-
const properties = resolvedCollection.properties;
|
|
662
|
-
if ((status === "existing" || status === "copy") && entity) {
|
|
663
|
-
if (!collection.alwaysApplyDefaultValues) {
|
|
664
|
-
return entity.values ?? getDefaultValuesFor(properties);
|
|
665
|
-
} else {
|
|
666
|
-
const defaultValues = getDefaultValuesFor(properties);
|
|
667
|
-
return mergeDeep(defaultValues, entity.values ?? {});
|
|
668
|
-
}
|
|
669
|
-
} else if (status === "new") {
|
|
670
|
-
return getDefaultValuesFor(properties);
|
|
671
|
-
} else {
|
|
672
|
-
console.error({
|
|
673
|
-
status,
|
|
674
|
-
entity
|
|
675
|
-
});
|
|
676
|
-
throw new Error("Form has not been initialised with the correct parameters");
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
export function yupToFormErrors(yupError: ValidationError): Record<string, any> {
|
|
681
|
-
let errors: Record<string, any> = {};
|
|
682
|
-
if (yupError.inner) {
|
|
683
|
-
if (yupError.inner.length === 0) {
|
|
684
|
-
return setIn(errors, yupError.path!, yupError.message);
|
|
685
|
-
}
|
|
686
|
-
for (const err of yupError.inner) {
|
|
687
|
-
if (!getIn(errors, err.path!)) {
|
|
688
|
-
errors = setIn(errors, err.path!, err.message);
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
return errors;
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
export function FormLayoutInner({
|
|
696
|
-
id,
|
|
697
|
-
formContext,
|
|
698
|
-
children,
|
|
699
|
-
className,
|
|
700
|
-
forceActionsAtTheBottom,
|
|
701
|
-
pluginActions,
|
|
702
|
-
EntityFormActionsComponent,
|
|
703
|
-
showDefaultActions,
|
|
704
|
-
}: {
|
|
705
|
-
id?: string,
|
|
706
|
-
formContext: FormContext,
|
|
707
|
-
children: React.ReactNode,
|
|
708
|
-
className?: string,
|
|
709
|
-
forceActionsAtTheBottom?: boolean,
|
|
710
|
-
pluginActions?: React.ReactNode[],
|
|
711
|
-
EntityFormActionsComponent: React.FC<EntityFormActionsProps>;
|
|
712
|
-
showDefaultActions?: boolean;
|
|
713
|
-
}) {
|
|
714
|
-
|
|
715
|
-
const formex = formContext.formex;
|
|
716
|
-
const collection = formContext.collection;
|
|
717
|
-
const path = formContext.path;
|
|
718
|
-
const entity = formContext.entity;
|
|
719
|
-
const savingError = formContext.savingError;
|
|
720
|
-
const status = formContext.status;
|
|
721
|
-
const openEntityMode = formContext.openEntityMode;
|
|
722
634
|
const disabled = formex.isSubmitting || (!formex.dirty && status === "existing");
|
|
723
635
|
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
if (!collection || !path) {
|
|
636
|
+
if (!resolvedCollection || !path) {
|
|
727
637
|
throw Error("INTERNAL: Collection and path must be defined in form context");
|
|
728
638
|
}
|
|
729
639
|
|
|
730
640
|
const dialogActions = <EntityFormActionsComponent
|
|
731
|
-
collection={
|
|
641
|
+
collection={resolvedCollection}
|
|
732
642
|
path={path}
|
|
733
643
|
entity={entity}
|
|
734
644
|
layout={forceActionsAtTheBottom ? "bottom" : "side"}
|
|
@@ -746,12 +656,12 @@ export function FormLayoutInner({
|
|
|
746
656
|
<form
|
|
747
657
|
onSubmit={formContext.formex.handleSubmit}
|
|
748
658
|
onReset={() => formex.resetForm({
|
|
749
|
-
values: getInitialEntityValues(collection, path, status, entity, customizationController.propertyConfigs),
|
|
659
|
+
values: getInitialEntityValues(collection, path, status, entity, customizationController.propertyConfigs) as M,
|
|
750
660
|
})}
|
|
751
661
|
noValidate
|
|
752
662
|
className={cls("flex-1 flex flex-row w-full overflow-y-auto justify-center", className)}>
|
|
753
663
|
<div
|
|
754
|
-
id={
|
|
664
|
+
id={`form_${path}`}
|
|
755
665
|
className={cls("relative flex flex-row max-w-4xl lg:max-w-3xl xl:max-w-4xl 2xl:max-w-6xl w-full h-fit")}>
|
|
756
666
|
|
|
757
667
|
<div className={cls("flex flex-col w-full pt-12 pb-16 px-4 sm:px-8 md:px-10")}>
|
|
@@ -769,7 +679,8 @@ export function FormLayoutInner({
|
|
|
769
679
|
<CheckIcon size={"smallest"}/>
|
|
770
680
|
</Chip>
|
|
771
681
|
</Tooltip>}
|
|
772
|
-
|
|
682
|
+
|
|
683
|
+
{formView}
|
|
773
684
|
|
|
774
685
|
</div>
|
|
775
686
|
|
|
@@ -781,6 +692,53 @@ export function FormLayoutInner({
|
|
|
781
692
|
);
|
|
782
693
|
}
|
|
783
694
|
|
|
695
|
+
function getInitialEntityValues<M extends object>(
|
|
696
|
+
collection: EntityCollection,
|
|
697
|
+
path: string,
|
|
698
|
+
status: "new" | "existing" | "copy",
|
|
699
|
+
entity: Entity<M> | undefined,
|
|
700
|
+
propertyConfigs?: Record<string, PropertyConfig>
|
|
701
|
+
): Partial<EntityValues<M>> {
|
|
702
|
+
const resolvedCollection = resolveCollection({
|
|
703
|
+
collection,
|
|
704
|
+
path,
|
|
705
|
+
values: entity?.values,
|
|
706
|
+
propertyConfigs
|
|
707
|
+
});
|
|
708
|
+
const properties = resolvedCollection.properties;
|
|
709
|
+
if ((status === "existing" || status === "copy") && entity) {
|
|
710
|
+
if (!collection.alwaysApplyDefaultValues) {
|
|
711
|
+
return entity.values ?? getDefaultValuesFor(properties);
|
|
712
|
+
} else {
|
|
713
|
+
const defaultValues = getDefaultValuesFor(properties);
|
|
714
|
+
return mergeDeep(defaultValues, entity.values ?? {});
|
|
715
|
+
}
|
|
716
|
+
} else if (status === "new") {
|
|
717
|
+
return getDefaultValuesFor(properties);
|
|
718
|
+
} else {
|
|
719
|
+
console.error({
|
|
720
|
+
status,
|
|
721
|
+
entity
|
|
722
|
+
});
|
|
723
|
+
throw new Error("Form has not been initialised with the correct parameters");
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
export function yupToFormErrors(yupError: ValidationError): Record<string, any> {
|
|
728
|
+
let errors: Record<string, any> = {};
|
|
729
|
+
if (yupError.inner) {
|
|
730
|
+
if (yupError.inner.length === 0) {
|
|
731
|
+
return setIn(errors, yupError.path!, yupError.message);
|
|
732
|
+
}
|
|
733
|
+
for (const err of yupError.inner) {
|
|
734
|
+
if (!getIn(errors, err.path!)) {
|
|
735
|
+
errors = setIn(errors, err.path!, err.message);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
return errors;
|
|
740
|
+
}
|
|
741
|
+
|
|
784
742
|
function useOnAutoSave(autoSave: undefined | boolean, formex: FormexController<any>, lastSavedValues: any, save: (values: EntityValues<any>) => Promise<void>) {
|
|
785
743
|
if (!autoSave) return;
|
|
786
744
|
useEffect(() => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef } from "react";
|
|
2
2
|
import {
|
|
3
|
+
CustomizationController,
|
|
3
4
|
EntityCollection,
|
|
4
5
|
EntitySidePanelProps,
|
|
5
6
|
NavigationController,
|
|
@@ -10,17 +11,28 @@ import {
|
|
|
10
11
|
} from "../types";
|
|
11
12
|
import { getNavigationEntriesFromPath, NavigationViewInternal } from "../util/navigation_from_path";
|
|
12
13
|
import { useLocation } from "react-router-dom";
|
|
13
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
removeInitialAndTrailingSlashes,
|
|
16
|
+
resolveCollection,
|
|
17
|
+
resolveDefaultSelectedView,
|
|
18
|
+
resolvedSelectedEntityView
|
|
19
|
+
} from "../util";
|
|
14
20
|
import { ADDITIONAL_TAB_WIDTH, CONTAINER_FULL_WIDTH, FORM_CONTAINER_WIDTH } from "./common";
|
|
15
|
-
import { useLargeLayout } from "../hooks";
|
|
21
|
+
import { useCustomizationController, useLargeLayout } from "../hooks";
|
|
16
22
|
import { EntitySidePanel } from "../core/EntitySidePanel";
|
|
17
23
|
|
|
18
24
|
const NEW_URL_HASH = "new_side";
|
|
19
25
|
const SIDE_URL_HASH = "side";
|
|
20
26
|
|
|
21
|
-
export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean): string {
|
|
27
|
+
export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean, customizationController: CustomizationController): string {
|
|
22
28
|
if (small) return CONTAINER_FULL_WIDTH;
|
|
23
|
-
|
|
29
|
+
|
|
30
|
+
const {
|
|
31
|
+
selectedSecondaryForm
|
|
32
|
+
} = resolvedSelectedEntityView(props.collection?.entityViews, customizationController, props.selectedTab);
|
|
33
|
+
|
|
34
|
+
const shouldUseSmallLayout = !props.selectedTab || Boolean(selectedSecondaryForm);
|
|
35
|
+
|
|
24
36
|
let resolvedWidth: string | undefined;
|
|
25
37
|
if (props.width) {
|
|
26
38
|
resolvedWidth = typeof props.width === "number" ? `${props.width}px` : props.width;
|
|
@@ -28,7 +40,7 @@ export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: bool
|
|
|
28
40
|
resolvedWidth = typeof props.collection.sideDialogWidth === "number" ? `${props.collection.sideDialogWidth}px` : props.collection.sideDialogWidth;
|
|
29
41
|
}
|
|
30
42
|
|
|
31
|
-
if (!
|
|
43
|
+
if (!shouldUseSmallLayout) {
|
|
32
44
|
return `calc(${ADDITIONAL_TAB_WIDTH} + ${resolvedWidth ?? FORM_CONTAINER_WIDTH})`
|
|
33
45
|
} else {
|
|
34
46
|
if (resolvedWidth) {
|
|
@@ -89,6 +101,7 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
89
101
|
|
|
90
102
|
const location = useLocation();
|
|
91
103
|
const initialised = useRef<boolean>(false);
|
|
104
|
+
const customizationController = useCustomizationController();
|
|
92
105
|
|
|
93
106
|
const smallLayout = !useLargeLayout();
|
|
94
107
|
|
|
@@ -105,9 +118,9 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
105
118
|
for (let i = 0; i < panelsFromUrl.length; i++) {
|
|
106
119
|
const props = panelsFromUrl[i];
|
|
107
120
|
if (i === 0)
|
|
108
|
-
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout));
|
|
121
|
+
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController));
|
|
109
122
|
else
|
|
110
|
-
sideDialogsController.open(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout))
|
|
123
|
+
sideDialogsController.open(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController))
|
|
111
124
|
}
|
|
112
125
|
}
|
|
113
126
|
initialised.current = true;
|
|
@@ -127,7 +140,7 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
127
140
|
return;
|
|
128
141
|
}
|
|
129
142
|
const lastPanel = panelsFromUrl[panelsFromUrl.length - 1];
|
|
130
|
-
const panelProps = propsToSidePanel(lastPanel, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout);
|
|
143
|
+
const panelProps = propsToSidePanel(lastPanel, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController);
|
|
131
144
|
const lastCurrentPanel = currentPanelKeys.length > 0 ? currentPanelKeys[currentPanelKeys.length - 1] : undefined;
|
|
132
145
|
if (!lastCurrentPanel || lastCurrentPanel !== panelProps.key) {
|
|
133
146
|
sideDialogsController.replace(panelProps);
|
|
@@ -140,7 +153,7 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
140
153
|
useEffect(() => {
|
|
141
154
|
const updatedSidePanels = sideDialogsController.sidePanels.map(sidePanelProps => {
|
|
142
155
|
if (sidePanelProps.additional) {
|
|
143
|
-
return propsToSidePanel(sidePanelProps.additional, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout);
|
|
156
|
+
return propsToSidePanel(sidePanelProps.additional, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController);
|
|
144
157
|
}
|
|
145
158
|
return sidePanelProps;
|
|
146
159
|
});
|
|
@@ -172,7 +185,8 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
172
185
|
},
|
|
173
186
|
navigation.buildUrlCollectionPath,
|
|
174
187
|
navigation.resolveIdsFrom,
|
|
175
|
-
smallLayout
|
|
188
|
+
smallLayout,
|
|
189
|
+
customizationController
|
|
176
190
|
));
|
|
177
191
|
|
|
178
192
|
}, [sideDialogsController, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout]);
|
|
@@ -183,7 +197,7 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
183
197
|
throw Error("If you want to copy an entity you need to provide an entityId");
|
|
184
198
|
}
|
|
185
199
|
|
|
186
|
-
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout));
|
|
200
|
+
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController));
|
|
187
201
|
|
|
188
202
|
}, [navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, sideDialogsController, smallLayout]);
|
|
189
203
|
|
|
@@ -242,11 +256,11 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
|
|
|
242
256
|
return sidePanel ? [sidePanel] : [];
|
|
243
257
|
}
|
|
244
258
|
|
|
245
|
-
|
|
246
259
|
const propsToSidePanel = (props: EntitySidePanelProps,
|
|
247
260
|
buildUrlCollectionPath: (path: string) => string,
|
|
248
261
|
resolveIdsFrom: (pathWithAliases: string) => string,
|
|
249
|
-
smallLayout: boolean
|
|
262
|
+
smallLayout: boolean,
|
|
263
|
+
customizationController: CustomizationController): SideDialogPanelProps => {
|
|
250
264
|
|
|
251
265
|
const collectionPath = removeInitialAndTrailingSlashes(props.path);
|
|
252
266
|
|
|
@@ -261,7 +275,7 @@ const propsToSidePanel = (props: EntitySidePanelProps,
|
|
|
261
275
|
formProps: props.formProps
|
|
262
276
|
};
|
|
263
277
|
|
|
264
|
-
const entityViewWidth = getEntityViewWidth(props, smallLayout);
|
|
278
|
+
const entityViewWidth = getEntityViewWidth(props, smallLayout, customizationController);
|
|
265
279
|
|
|
266
280
|
return {
|
|
267
281
|
key: `${props.path}/${props.entityId}`,
|
package/src/util/resolutions.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ArrayProperty,
|
|
3
3
|
CMSType,
|
|
4
|
+
CustomizationController,
|
|
4
5
|
EntityCollection,
|
|
5
6
|
EntityCustomView,
|
|
6
7
|
EntityValues,
|
|
@@ -218,11 +219,11 @@ export function resolveProperty<T extends CMSType = CMSType, M extends Record<st
|
|
|
218
219
|
}
|
|
219
220
|
|
|
220
221
|
export function getArrayResolvedProperties<M>({
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
222
|
+
propertyKey,
|
|
223
|
+
propertyValue,
|
|
224
|
+
property,
|
|
225
|
+
...props
|
|
226
|
+
}: {
|
|
226
227
|
propertyValue: any,
|
|
227
228
|
propertyKey?: string,
|
|
228
229
|
property: ArrayProperty<any> | ResolvedArrayProperty<any>,
|
|
@@ -430,3 +431,23 @@ export function resolveEntityView(entityView: string | EntityCustomView<any>, co
|
|
|
430
431
|
return entityView;
|
|
431
432
|
}
|
|
432
433
|
}
|
|
434
|
+
|
|
435
|
+
export function resolvedSelectedEntityView<M extends Record<string, any>>(
|
|
436
|
+
customViews: (string | EntityCustomView<M>)[] | undefined,
|
|
437
|
+
customizationController: CustomizationController,
|
|
438
|
+
selectedTab?: string
|
|
439
|
+
) {
|
|
440
|
+
const resolvedEntityViews = customViews ? customViews
|
|
441
|
+
.map(e => resolveEntityView(e, customizationController.entityViews))
|
|
442
|
+
.filter(Boolean) as EntityCustomView[]
|
|
443
|
+
: [];
|
|
444
|
+
|
|
445
|
+
const selectedEntityView = resolvedEntityViews.find(e => e.key === selectedTab);
|
|
446
|
+
const selectedSecondaryForm = customViews
|
|
447
|
+
&& resolvedEntityViews.filter(e => e.includeActions).find(e => e.key === selectedTab);
|
|
448
|
+
return {
|
|
449
|
+
resolvedEntityViews,
|
|
450
|
+
selectedEntityView,
|
|
451
|
+
selectedSecondaryForm
|
|
452
|
+
};
|
|
453
|
+
}
|