@firecms/core 3.0.0-canary.197 → 3.0.0-canary.198
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/core/EntityEditView.d.ts +3 -1
- package/dist/core/EntityEditViewFormActions.d.ts +1 -1
- package/dist/form/EntityForm.d.ts +13 -5
- package/dist/form/EntityFormActions.d.ts +1 -0
- package/dist/index.es.js +88 -69
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +88 -69
- package/dist/index.umd.js.map +1 -1
- package/dist/types/side_entity_controller.d.ts +5 -0
- package/package.json +5 -5
- package/src/core/EntityEditView.tsx +26 -10
- package/src/core/EntityEditViewFormActions.tsx +6 -5
- package/src/core/EntitySidePanel.tsx +1 -2
- package/src/form/EntityForm.tsx +27 -14
- package/src/form/EntityFormActions.tsx +1 -0
- package/src/internal/useBuildSideEntityController.tsx +1 -0
- package/src/types/side_dialogs_controller.tsx +2 -0
- package/src/types/side_entity_controller.tsx +5 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EntityCollection } from "./collections";
|
|
2
2
|
import { ResolvedEntityCollection } from "./resolved_entities";
|
|
3
3
|
import { Entity } from "./entities";
|
|
4
|
+
import { EntityFormProps } from "../form";
|
|
4
5
|
/**
|
|
5
6
|
* Props used to open a side dialog
|
|
6
7
|
* @group Hooks and utilities
|
|
@@ -55,6 +56,10 @@ export interface EntitySidePanelProps<M extends Record<string, any> = any> {
|
|
|
55
56
|
* Should this panel close when saving
|
|
56
57
|
*/
|
|
57
58
|
closeOnSave?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Override some form properties
|
|
61
|
+
*/
|
|
62
|
+
formProps?: Partial<EntityFormProps<M>>;
|
|
58
63
|
}
|
|
59
64
|
/**
|
|
60
65
|
* Controller to open the side dialog displaying entity forms
|
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.198",
|
|
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.198",
|
|
54
|
+
"@firecms/formex": "^3.0.0-canary.198",
|
|
55
|
+
"@firecms/ui": "^3.0.0-canary.198",
|
|
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": "c246dc2774f7ef1a91df3da792a217decbda700b",
|
|
108
108
|
"publishConfig": {
|
|
109
109
|
"access": "public"
|
|
110
110
|
},
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from "../hooks";
|
|
14
14
|
import { CircularProgress, cls, defaultBorderMixin, Tab, Tabs, Typography } from "@firecms/ui";
|
|
15
15
|
import { getEntityFromCache } from "../util/entity_cache";
|
|
16
|
-
import { EntityForm, FormLayoutInner } from "../form";
|
|
16
|
+
import { EntityForm, EntityFormProps, FormLayoutInner } from "../form";
|
|
17
17
|
import { EntityEditViewFormActions } from "./EntityEditViewFormActions";
|
|
18
18
|
|
|
19
19
|
const MAIN_TAB_VALUE = "main_##Q$SC^#S6";
|
|
@@ -47,6 +47,7 @@ export interface EntityEditViewProps<M extends Record<string, any>> {
|
|
|
47
47
|
onTabChange?: (props: OnTabChangeParams<M>) => void;
|
|
48
48
|
layout?: "side_panel" | "full_screen";
|
|
49
49
|
barActions?: React.ReactNode;
|
|
50
|
+
formProps?: Partial<EntityFormProps<M>>
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
/**
|
|
@@ -172,6 +173,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
172
173
|
barActions,
|
|
173
174
|
status,
|
|
174
175
|
setStatus,
|
|
176
|
+
formProps,
|
|
175
177
|
}: EntityEditViewProps<M> & {
|
|
176
178
|
entity?: Entity<M>,
|
|
177
179
|
cachedDirtyValues?: Partial<M>, // dirty cached entity in memory
|
|
@@ -331,20 +333,34 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
331
333
|
path={path}
|
|
332
334
|
entityId={entityId ?? usedEntity?.id}
|
|
333
335
|
onValuesModified={onValuesModified}
|
|
334
|
-
onSaved={onSaved ? (params) => onSaved({
|
|
335
|
-
...params,
|
|
336
|
-
selectedTab: MAIN_TAB_VALUE === selectedTab ? undefined : selectedTab,
|
|
337
|
-
}) : undefined}
|
|
338
336
|
entity={entity}
|
|
339
|
-
|
|
337
|
+
initialDirtyValues={cachedDirtyValues}
|
|
340
338
|
openEntityMode={layout}
|
|
341
|
-
onFormContextReady={setFormContext}
|
|
342
339
|
forceActionsAtTheBottom={actionsAtTheBottom}
|
|
343
340
|
initialStatus={status}
|
|
344
|
-
|
|
345
|
-
className={!mainViewVisible ? "hidden" : ""}
|
|
341
|
+
className={cls(!mainViewVisible ? "hidden" : "", formProps?.className)}
|
|
346
342
|
EntityFormActionsComponent={EntityEditViewFormActions}
|
|
347
|
-
|
|
343
|
+
{...formProps}
|
|
344
|
+
onEntityChange={(entity) => {
|
|
345
|
+
setUsedEntity(entity);
|
|
346
|
+
formProps?.onEntityChange?.(entity);
|
|
347
|
+
}}
|
|
348
|
+
onStatusChange={(status) => {
|
|
349
|
+
setStatus(status);
|
|
350
|
+
formProps?.onStatusChange?.(status);
|
|
351
|
+
}}
|
|
352
|
+
onFormContextReady={(formContext) => {
|
|
353
|
+
setFormContext(formContext);
|
|
354
|
+
formProps?.onFormContextReady?.(formContext);
|
|
355
|
+
}}
|
|
356
|
+
onSaved={(params) => {
|
|
357
|
+
const res = {
|
|
358
|
+
...params,
|
|
359
|
+
selectedTab: MAIN_TAB_VALUE === selectedTab ? undefined : selectedTab,
|
|
360
|
+
};
|
|
361
|
+
onSaved?.(res);
|
|
362
|
+
formProps?.onSaved?.(res);
|
|
363
|
+
}}
|
|
348
364
|
/>;
|
|
349
365
|
|
|
350
366
|
const subcollectionTabs = subcollections && subcollections.map((subcollection) =>
|
|
@@ -18,7 +18,8 @@ export function EntityEditViewFormActions({
|
|
|
18
18
|
disabled,
|
|
19
19
|
status,
|
|
20
20
|
pluginActions,
|
|
21
|
-
openEntityMode
|
|
21
|
+
openEntityMode,
|
|
22
|
+
showDefaultActions = true
|
|
22
23
|
}: EntityFormActionsProps) {
|
|
23
24
|
|
|
24
25
|
const authController = useAuthController();
|
|
@@ -40,7 +41,7 @@ export function EntityEditViewFormActions({
|
|
|
40
41
|
return actions;
|
|
41
42
|
}, [authController, collection, path]);
|
|
42
43
|
|
|
43
|
-
const formActions = entityActions.filter(a => a.includeInForm === undefined || a.includeInForm);
|
|
44
|
+
const formActions = showDefaultActions ? entityActions.filter(a => a.includeInForm === undefined || a.includeInForm) : [];
|
|
44
45
|
|
|
45
46
|
return layout === "bottom"
|
|
46
47
|
? buildBottomActions({
|
|
@@ -55,7 +56,7 @@ export function EntityEditViewFormActions({
|
|
|
55
56
|
status,
|
|
56
57
|
sideDialogContext,
|
|
57
58
|
pluginActions,
|
|
58
|
-
openEntityMode
|
|
59
|
+
openEntityMode,
|
|
59
60
|
})
|
|
60
61
|
: buildSideActions({
|
|
61
62
|
savingError,
|
|
@@ -69,7 +70,7 @@ export function EntityEditViewFormActions({
|
|
|
69
70
|
disabled,
|
|
70
71
|
status,
|
|
71
72
|
pluginActions,
|
|
72
|
-
openEntityMode
|
|
73
|
+
openEntityMode,
|
|
73
74
|
});
|
|
74
75
|
}
|
|
75
76
|
|
|
@@ -100,7 +101,7 @@ function buildBottomActions<M extends object>({
|
|
|
100
101
|
status,
|
|
101
102
|
sideDialogContext,
|
|
102
103
|
pluginActions,
|
|
103
|
-
openEntityMode
|
|
104
|
+
openEntityMode,
|
|
104
105
|
}: ActionsViewProps<M>) {
|
|
105
106
|
|
|
106
107
|
const canClose = openEntityMode === "side_panel";
|
|
@@ -33,8 +33,6 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
|
|
|
33
33
|
const navigationController = useNavigationController();
|
|
34
34
|
const sideDialogsController = useSideDialogContext();
|
|
35
35
|
|
|
36
|
-
console.log("sideDialogsController", sideDialogsController);
|
|
37
|
-
|
|
38
36
|
const onClose = () => {
|
|
39
37
|
if (props.onClose) {
|
|
40
38
|
props.onClose();
|
|
@@ -153,6 +151,7 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
|
|
|
153
151
|
collection
|
|
154
152
|
});
|
|
155
153
|
}}
|
|
154
|
+
formProps={props.formProps}
|
|
156
155
|
/>
|
|
157
156
|
</ErrorBoundary>
|
|
158
157
|
|
package/src/form/EntityForm.tsx
CHANGED
|
@@ -25,11 +25,9 @@ import {
|
|
|
25
25
|
|
|
26
26
|
import {
|
|
27
27
|
saveEntityWithCallbacks,
|
|
28
|
-
useAuthController,
|
|
29
28
|
useCustomizationController,
|
|
30
29
|
useDataSource,
|
|
31
|
-
useFireCMSContext,
|
|
32
|
-
useSideEntityController,
|
|
30
|
+
useFireCMSContext,
|
|
33
31
|
useSnackbarController
|
|
34
32
|
} from "../hooks";
|
|
35
33
|
import { Alert, CheckIcon, Chip, cls, EditIcon, NotesIcon, paperMixin, Tooltip, Typography } from "@firecms/ui";
|
|
@@ -42,7 +40,6 @@ import { CustomIdField } from "../form/components/CustomIdField";
|
|
|
42
40
|
import { ErrorFocus } from "../form/components/ErrorFocus";
|
|
43
41
|
import { CustomFieldValidator, getYupEntitySchema } from "../form/validation";
|
|
44
42
|
import { EntityFormActions, EntityFormActionsProps } from "./EntityFormActions";
|
|
45
|
-
import { useSideDialogContext } from "../core";
|
|
46
43
|
|
|
47
44
|
export type OnUpdateParams = {
|
|
48
45
|
entity: Entity<any>,
|
|
@@ -53,7 +50,7 @@ export type OnUpdateParams = {
|
|
|
53
50
|
collection: EntityCollection<any>
|
|
54
51
|
};
|
|
55
52
|
|
|
56
|
-
type EntityFormProps<M extends Record<string, any>> = {
|
|
53
|
+
export type EntityFormProps<M extends Record<string, any>> = {
|
|
57
54
|
path: string;
|
|
58
55
|
collection: EntityCollection<M>;
|
|
59
56
|
entityId?: string;
|
|
@@ -62,7 +59,7 @@ type EntityFormProps<M extends Record<string, any>> = {
|
|
|
62
59
|
onIdChange?: (id: string) => void;
|
|
63
60
|
onValuesModified?: (modified: boolean) => void;
|
|
64
61
|
onSaved?: (params: OnUpdateParams) => void;
|
|
65
|
-
|
|
62
|
+
initialDirtyValues?: Partial<M>; // dirty cached entity in memory
|
|
66
63
|
onFormContextReady?: (formContext: FormContext) => void;
|
|
67
64
|
forceActionsAtTheBottom?: boolean;
|
|
68
65
|
className?: string;
|
|
@@ -71,6 +68,16 @@ type EntityFormProps<M extends Record<string, any>> = {
|
|
|
71
68
|
onEntityChange?: (entity: Entity<M>) => void;
|
|
72
69
|
formex?: FormexController<M>;
|
|
73
70
|
openEntityMode?: "side_panel" | "full_screen";
|
|
71
|
+
/**
|
|
72
|
+
* Include the copy and delete actions in the form
|
|
73
|
+
*/
|
|
74
|
+
showDefaultActions?: boolean;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Display the entity path in the form
|
|
78
|
+
*/
|
|
79
|
+
showEntityPath?: boolean;
|
|
80
|
+
|
|
74
81
|
EntityFormActionsComponent?: React.FC<EntityFormActionsProps>;
|
|
75
82
|
};
|
|
76
83
|
|
|
@@ -82,7 +89,7 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
82
89
|
onIdChange,
|
|
83
90
|
onSaved,
|
|
84
91
|
entity,
|
|
85
|
-
|
|
92
|
+
initialDirtyValues,
|
|
86
93
|
onFormContextReady,
|
|
87
94
|
forceActionsAtTheBottom,
|
|
88
95
|
initialStatus,
|
|
@@ -91,7 +98,9 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
91
98
|
onEntityChange,
|
|
92
99
|
openEntityMode = "full_screen",
|
|
93
100
|
formex: formexProp,
|
|
94
|
-
EntityFormActionsComponent = EntityFormActions
|
|
101
|
+
EntityFormActionsComponent = EntityFormActions,
|
|
102
|
+
showDefaultActions = true,
|
|
103
|
+
showEntityPath = true
|
|
95
104
|
}: EntityFormProps<M>) {
|
|
96
105
|
|
|
97
106
|
if (collection.customId && collection.formAutoSave) {
|
|
@@ -186,8 +195,8 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
186
195
|
};
|
|
187
196
|
|
|
188
197
|
const formex: FormexController<M> = formexProp ?? useCreateFormex<M>({
|
|
189
|
-
initialValues: (
|
|
190
|
-
initialDirty: Boolean(
|
|
198
|
+
initialValues: (initialDirtyValues ?? getInitialEntityValues(collection, path, status, entity)) as M,
|
|
199
|
+
initialDirty: Boolean(initialDirtyValues),
|
|
191
200
|
onSubmit,
|
|
192
201
|
onReset: () => {
|
|
193
202
|
clearDirtyCache();
|
|
@@ -567,12 +576,12 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
567
576
|
variant={"h4"}>
|
|
568
577
|
{title ?? collection.singularName ?? collection.name}
|
|
569
578
|
</Typography>
|
|
570
|
-
<Alert color={"base"} className={"w-full"} size={"small"}>
|
|
579
|
+
{showEntityPath && <Alert color={"base"} className={"w-full"} size={"small"}>
|
|
571
580
|
<code
|
|
572
581
|
className={"text-xs select-all text-text-secondary dark:text-text-secondary-dark"}>
|
|
573
582
|
{entity?.path ?? path}/{entityId}
|
|
574
583
|
</code>
|
|
575
|
-
</Alert>
|
|
584
|
+
</Alert>}
|
|
576
585
|
</div>
|
|
577
586
|
|
|
578
587
|
{!collection.hideIdFromForm &&
|
|
@@ -608,7 +617,8 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
608
617
|
pluginActions={pluginActions}
|
|
609
618
|
forceActionsAtTheBottom={forceActionsAtTheBottom}
|
|
610
619
|
EntityFormActionsComponent={EntityFormActionsComponent}
|
|
611
|
-
formContext={formContext}
|
|
620
|
+
formContext={formContext}
|
|
621
|
+
showDefaultActions={showDefaultActions}>
|
|
612
622
|
{formView}
|
|
613
623
|
</FormLayoutInner>
|
|
614
624
|
);
|
|
@@ -661,7 +671,8 @@ export function FormLayoutInner({
|
|
|
661
671
|
className,
|
|
662
672
|
forceActionsAtTheBottom,
|
|
663
673
|
pluginActions,
|
|
664
|
-
EntityFormActionsComponent
|
|
674
|
+
EntityFormActionsComponent,
|
|
675
|
+
showDefaultActions
|
|
665
676
|
}: {
|
|
666
677
|
id?: string,
|
|
667
678
|
formContext: FormContext,
|
|
@@ -670,6 +681,7 @@ export function FormLayoutInner({
|
|
|
670
681
|
forceActionsAtTheBottom?: boolean,
|
|
671
682
|
pluginActions?: React.ReactNode[],
|
|
672
683
|
EntityFormActionsComponent: React.FC<EntityFormActionsProps>;
|
|
684
|
+
showDefaultActions?: boolean;
|
|
673
685
|
}) {
|
|
674
686
|
|
|
675
687
|
const formex = formContext.formex;
|
|
@@ -696,6 +708,7 @@ export function FormLayoutInner({
|
|
|
696
708
|
status={status}
|
|
697
709
|
pluginActions={pluginActions ?? []}
|
|
698
710
|
openEntityMode={openEntityMode}
|
|
711
|
+
showDefaultActions={showDefaultActions}
|
|
699
712
|
/>;
|
|
700
713
|
|
|
701
714
|
return (
|
|
@@ -260,6 +260,7 @@ const propsToSidePanel = (props: EntitySidePanelProps,
|
|
|
260
260
|
const resolvedPanelProps: EntitySidePanelProps<any> = {
|
|
261
261
|
...props,
|
|
262
262
|
path: resolvedPath,
|
|
263
|
+
formProps: props.formProps
|
|
263
264
|
};
|
|
264
265
|
|
|
265
266
|
const entityViewWidth = getEntityViewWidth(props, smallLayout);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { EntityFormProps } from "../form";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Controller to open the side dialog
|
|
@@ -78,4 +79,5 @@ export interface SideDialogPanelProps {
|
|
|
78
79
|
* Use this prop to store additional data in the panel
|
|
79
80
|
*/
|
|
80
81
|
additional?: any;
|
|
82
|
+
|
|
81
83
|
}
|
|
@@ -2,6 +2,7 @@ import { EntityCollection } from "./collections";
|
|
|
2
2
|
import { ResolvedEntityCollection } from "./resolved_entities";
|
|
3
3
|
import { Entity } from "./entities";
|
|
4
4
|
import { EntityOverrides } from "./entity_overrides";
|
|
5
|
+
import { EntityFormProps } from "../form";
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Props used to open a side dialog
|
|
@@ -66,6 +67,10 @@ export interface EntitySidePanelProps<M extends Record<string, any> = any> {
|
|
|
66
67
|
*/
|
|
67
68
|
closeOnSave?: boolean;
|
|
68
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Override some form properties
|
|
72
|
+
*/
|
|
73
|
+
formProps?: Partial<EntityFormProps<M>>;
|
|
69
74
|
}
|
|
70
75
|
|
|
71
76
|
/**
|