@firecms/core 3.0.0-canary.186 → 3.0.0-canary.187
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 +4 -15
- package/dist/core/EntityForm.d.ts +43 -0
- 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/MapFieldBinding.d.ts +1 -1
- package/dist/index.es.js +11960 -11691
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +11938 -11669
- package/dist/index.umd.js.map +1 -1
- package/dist/types/fields.d.ts +11 -0
- package/dist/types/navigation.d.ts +1 -0
- package/dist/types/plugins.d.ts +1 -1
- package/dist/types/properties.d.ts +1 -1
- package/package.json +5 -5
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +4 -2
- package/src/core/EntityEditView.tsx +210 -1049
- package/src/core/EntityForm.tsx +952 -0
- package/src/core/NavigationRoutes.tsx +16 -12
- package/src/form/components/FormEntry.tsx +22 -0
- package/src/form/components/FormLayout.tsx +16 -0
- package/src/form/components/index.tsx +2 -0
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +0 -2
- package/src/form/field_bindings/MapFieldBinding.tsx +0 -2
- package/src/routes/FireCMSRoute.tsx +7 -2
- package/src/types/fields.tsx +16 -0
- package/src/types/navigation.ts +1 -0
- package/src/types/plugins.tsx +1 -1
- package/src/types/properties.ts +1 -1
- package/src/util/entity_cache.ts +10 -1
|
@@ -68,24 +68,28 @@ export const NavigationRoutes = React.memo<NavigationRoutesProps>(
|
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
const
|
|
72
|
-
const collectionRoute =
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
71
|
+
const collectionUrlPath = navigation.buildUrlCollectionPath("");
|
|
72
|
+
const collectionRoute = (
|
|
73
|
+
<Route path={collectionUrlPath + "/*"}
|
|
74
|
+
key={`navigation_entity`}
|
|
75
|
+
element={
|
|
76
|
+
<ErrorBoundary>
|
|
77
|
+
<FireCMSRoute/>
|
|
78
|
+
</ErrorBoundary>
|
|
79
|
+
}/>
|
|
80
|
+
);
|
|
79
81
|
|
|
80
82
|
const homeRoute = (
|
|
81
83
|
<Route path={"/"}
|
|
82
84
|
element={<HomePageRoute>{homePage}</HomePageRoute>}/>
|
|
83
85
|
);
|
|
84
86
|
|
|
85
|
-
const notFoundRoute =
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
const notFoundRoute = (
|
|
88
|
+
<Route path={"*"}
|
|
89
|
+
element={
|
|
90
|
+
<NotFoundPage/>
|
|
91
|
+
}/>
|
|
92
|
+
);
|
|
89
93
|
|
|
90
94
|
return (
|
|
91
95
|
<Routes location={baseLocation}>
|
|
@@ -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
|
+
}
|
|
@@ -23,7 +23,6 @@ export function ArrayCustomShapedFieldBinding<T extends Array<any>>({
|
|
|
23
23
|
minimalistView: minimalistViewProp,
|
|
24
24
|
property,
|
|
25
25
|
includeDescription,
|
|
26
|
-
underlyingValueHasChanged,
|
|
27
26
|
context,
|
|
28
27
|
disabled
|
|
29
28
|
}: FieldProps<T, any, any>) {
|
|
@@ -65,7 +64,6 @@ export function ArrayCustomShapedFieldBinding<T extends Array<any>>({
|
|
|
65
64
|
disabled: disabled || thisDisabled,
|
|
66
65
|
property: childProperty,
|
|
67
66
|
includeDescription,
|
|
68
|
-
underlyingValueHasChanged,
|
|
69
67
|
context,
|
|
70
68
|
partOfArray: true,
|
|
71
69
|
minimalistView: false,
|
|
@@ -23,7 +23,6 @@ export function MapFieldBinding({
|
|
|
23
23
|
property,
|
|
24
24
|
minimalistView: minimalistViewProp,
|
|
25
25
|
includeDescription,
|
|
26
|
-
underlyingValueHasChanged,
|
|
27
26
|
autoFocus,
|
|
28
27
|
context,
|
|
29
28
|
onPropertyChange
|
|
@@ -62,7 +61,6 @@ export function MapFieldBinding({
|
|
|
62
61
|
disabled: disabled || thisDisabled,
|
|
63
62
|
property: childProperty,
|
|
64
63
|
includeDescription,
|
|
65
|
-
underlyingValueHasChanged,
|
|
66
64
|
context,
|
|
67
65
|
partOfArray: false,
|
|
68
66
|
minimalistView: false,
|
|
@@ -190,10 +190,15 @@ function EntityFullScreenRoute({
|
|
|
190
190
|
onValuesModified={(modified) => blocked.current = modified}
|
|
191
191
|
onSaved={(params) => {
|
|
192
192
|
console.log("Entity saved", params);
|
|
193
|
-
|
|
193
|
+
const newSelectedTab = params.selectedTab;
|
|
194
|
+
const newEntityId = params.entityId;
|
|
195
|
+
if (newSelectedTab) {
|
|
196
|
+
navigate(`${basePath}/${newEntityId}/${newSelectedTab}`, { replace: true });
|
|
197
|
+
} else {
|
|
198
|
+
navigate(`${basePath}/${newEntityId}`, { replace: true });
|
|
199
|
+
}
|
|
194
200
|
}}
|
|
195
201
|
onTabChange={(params) => {
|
|
196
|
-
// updateUrl(params.entityId, params.selectedTab, !isNew, params.path, isNew);
|
|
197
202
|
setSelectedTab(params.selectedTab);
|
|
198
203
|
if (isNew) {
|
|
199
204
|
return;
|
package/src/types/fields.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CMSType, Property, PropertyOrBuilder } from "./properties";
|
|
2
2
|
import { ResolvedEntityCollection, ResolvedProperty } from "./resolved_entities";
|
|
3
3
|
import { FormexController } from "@firecms/formex";
|
|
4
|
+
import { Entity } from "./entities";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* When building a custom field you need to create a React component that takes
|
|
@@ -161,6 +162,21 @@ export interface FormContext<M extends Record<string, any> = any> {
|
|
|
161
162
|
*/
|
|
162
163
|
path?: string;
|
|
163
164
|
|
|
165
|
+
status: "new" | "existing" | "copy";
|
|
166
|
+
|
|
167
|
+
entity?: Entity<M>;
|
|
168
|
+
|
|
169
|
+
savingError?: Error;
|
|
170
|
+
|
|
171
|
+
openEntityMode: "side_panel" | "full_screen";
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* If pending close is set to true, the form will close when the user
|
|
175
|
+
* saves the entity
|
|
176
|
+
* @param pendingClose
|
|
177
|
+
*/
|
|
178
|
+
setPendingClose?: (pendingClose: boolean) => void;
|
|
179
|
+
|
|
164
180
|
/**
|
|
165
181
|
* This is the underlying formex controller that powers the form
|
|
166
182
|
*/
|
package/src/types/navigation.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { EntityReference } from "./entities";
|
|
|
5
5
|
/**
|
|
6
6
|
* Controller that includes the resolved navigation and utility methods and
|
|
7
7
|
* attributes.
|
|
8
|
+
* This controller holds the state of the navigation including the collections.
|
|
8
9
|
* @group Models
|
|
9
10
|
*/
|
|
10
11
|
export type NavigationController<EC extends EntityCollection = EntityCollection<any>> = {
|
package/src/types/plugins.tsx
CHANGED
|
@@ -195,7 +195,7 @@ export interface PluginFormActionProps<USER extends User = User, EC extends Enti
|
|
|
195
195
|
formContext?: FormContext<any>;
|
|
196
196
|
context: FireCMSContext<USER>;
|
|
197
197
|
currentEntityId?: string;
|
|
198
|
-
|
|
198
|
+
openEntityMode: "side_panel" | "full_screen";
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
export type PluginFieldBuilderParams<T extends CMSType = CMSType, M extends Record<string, any> = any, EC extends EntityCollection<M> = EntityCollection<M>> = {
|
package/src/types/properties.ts
CHANGED
|
@@ -377,7 +377,7 @@ export interface StringProperty extends BaseProperty<string> {
|
|
|
377
377
|
|
|
378
378
|
/**
|
|
379
379
|
* You can specify a `Storage` configuration. It is used to
|
|
380
|
-
* indicate that this string refers to a path in
|
|
380
|
+
* indicate that this string refers to a path in your storage provider.
|
|
381
381
|
*/
|
|
382
382
|
storage?: StorageConfig;
|
|
383
383
|
|
package/src/util/entity_cache.ts
CHANGED
|
@@ -10,23 +10,31 @@ const entityCache: Map<string, object> = new Map();
|
|
|
10
10
|
const isLocalStorageAvailable = typeof localStorage !== "undefined";
|
|
11
11
|
|
|
12
12
|
// Define custom replacer for JSON.stringify
|
|
13
|
-
function customReplacer(key: string
|
|
13
|
+
function customReplacer(key: string): any {
|
|
14
|
+
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
const value = this[key];
|
|
17
|
+
|
|
14
18
|
// Handle Date objects
|
|
19
|
+
// @ts-ignore
|
|
15
20
|
if (value instanceof Date) {
|
|
16
21
|
return { __type: "Date", value: value.toISOString() };
|
|
17
22
|
}
|
|
18
23
|
|
|
19
24
|
// Handle EntityReference
|
|
25
|
+
// @ts-ignore
|
|
20
26
|
if (value instanceof EntityReference) {
|
|
21
27
|
return { __type: "EntityReference", id: value.id, path: value.path };
|
|
22
28
|
}
|
|
23
29
|
|
|
24
30
|
// Handle GeoPoint
|
|
31
|
+
// @ts-ignore
|
|
25
32
|
if (value instanceof GeoPoint) {
|
|
26
33
|
return { __type: "GeoPoint", latitude: value.latitude, longitude: value.longitude };
|
|
27
34
|
}
|
|
28
35
|
|
|
29
36
|
// Handle Vector
|
|
37
|
+
// @ts-ignore
|
|
30
38
|
if (value instanceof Vector) {
|
|
31
39
|
return { __type: "Vector", value: value.value };
|
|
32
40
|
}
|
|
@@ -93,6 +101,7 @@ export function saveEntityToCache(path: string, data: object): void {
|
|
|
93
101
|
if (isLocalStorageAvailable) {
|
|
94
102
|
try {
|
|
95
103
|
const key = LOCAL_STORAGE_PREFIX + path;
|
|
104
|
+
console.log("Saving entity to cache", key, data);
|
|
96
105
|
const entityString = JSON.stringify(data, customReplacer);
|
|
97
106
|
localStorage.setItem(key, entityString);
|
|
98
107
|
} catch (error) {
|