@firecms/core 3.0.0-canary.140 → 3.0.0-canary.142
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 +13 -3
- package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +6 -3
- 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/index.es.js +9433 -9358
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +9432 -9357
- package/dist/index.umd.js.map +1 -1
- package/dist/types/collections.d.ts +2 -1
- package/dist/types/fields.d.ts +16 -0
- package/dist/util/objects.d.ts +1 -0
- package/dist/util/property_utils.d.ts +2 -2
- package/package.json +14 -14
- package/src/components/ArrayContainer.tsx +36 -13
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +6 -4
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +66 -58
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +2 -3
- package/src/form/PropertyFieldBinding.tsx +22 -17
- package/src/form/components/index.tsx +0 -1
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +16 -10
- package/src/form/field_bindings/BlockFieldBinding.tsx +24 -8
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +4 -1
- package/src/form/field_bindings/MapFieldBinding.tsx +55 -39
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +1 -1
- package/src/form/field_bindings/RepeatFieldBinding.tsx +25 -20
- package/src/hooks/data/save.ts +0 -1
- package/src/types/collections.ts +2 -1
- package/src/types/fields.tsx +18 -0
- package/src/util/objects.ts +20 -0
- package/src/util/property_utils.tsx +9 -2
- package/dist/form/components/FormikArrayContainer.d.ts +0 -19
- package/src/form/components/FormikArrayContainer.tsx +0 -47
package/dist/types/fields.d.ts
CHANGED
|
@@ -90,6 +90,14 @@ export interface FieldProps<T extends CMSType = any, CustomProps = any, M extend
|
|
|
90
90
|
* Size of the field
|
|
91
91
|
*/
|
|
92
92
|
size?: "smallest" | "small" | "medium";
|
|
93
|
+
/**
|
|
94
|
+
* Some properties might change internal state (like expanding a panel).
|
|
95
|
+
* This function should be called when the internal state changes.
|
|
96
|
+
* This is used to preserve state in array containers.
|
|
97
|
+
*
|
|
98
|
+
* @param property
|
|
99
|
+
*/
|
|
100
|
+
onPropertyChange?: (property: Partial<Property<any>>) => void;
|
|
93
101
|
}
|
|
94
102
|
/**
|
|
95
103
|
* Context passed to custom fields
|
|
@@ -183,4 +191,12 @@ export interface PropertyFieldBindingProps<T extends CMSType, M extends Record<s
|
|
|
183
191
|
* The size of the field
|
|
184
192
|
*/
|
|
185
193
|
size?: "smallest" | "small" | "medium";
|
|
194
|
+
/**
|
|
195
|
+
* Some properties might change internal state (like expanding a panel).
|
|
196
|
+
* This function should be called when the internal state changes.
|
|
197
|
+
* This is used to preserve state in array containers.
|
|
198
|
+
*
|
|
199
|
+
* @param property
|
|
200
|
+
*/
|
|
201
|
+
onPropertyChange?: (property: Partial<Property<any>>) => void;
|
|
186
202
|
}
|
package/dist/util/objects.d.ts
CHANGED
|
@@ -6,5 +6,6 @@ export declare function removeInPath(o: object, path: string): object | undefine
|
|
|
6
6
|
export declare function removeFunctions(o: object | undefined): any;
|
|
7
7
|
export declare function getHashValue<T>(v: T): any;
|
|
8
8
|
export declare function removeUndefined(value: any, removeEmptyStrings?: boolean): any;
|
|
9
|
+
export declare function removeNulls(value: any): any;
|
|
9
10
|
export declare function isEmptyObject(obj: object): boolean;
|
|
10
11
|
export declare function removePropsIfExisting(source: any, comparison: any): any;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { EntityCollection, PropertiesOrBuilders, PropertyConfig, PropertyOrBuilder, ResolvedProperty } from "../types";
|
|
2
|
+
import { EntityCollection, PropertiesOrBuilders, PropertyConfig, PropertyOrBuilder, ResolvedProperties, ResolvedProperty } from "../types";
|
|
3
3
|
export declare function isReferenceProperty(propertyOrBuilder: PropertyOrBuilder, fields: Record<string, PropertyConfig>): boolean | null;
|
|
4
4
|
export declare function getIdIcon(size: "small" | "medium" | "large"): React.ReactNode;
|
|
5
5
|
export declare function getIconForWidget(widget: PropertyConfig | undefined, size: "small" | "medium" | "large"): import("react/jsx-runtime").JSX.Element;
|
|
@@ -11,7 +11,7 @@ export declare function getColorForProperty(property: PropertyOrBuilder, fields:
|
|
|
11
11
|
* @param properties
|
|
12
12
|
* @param path
|
|
13
13
|
*/
|
|
14
|
-
export declare function getPropertyInPath<M extends Record<string, any>>(properties: PropertiesOrBuilders<M
|
|
14
|
+
export declare function getPropertyInPath<M extends Record<string, any>>(properties: PropertiesOrBuilders<M> | ResolvedProperties, path: string): PropertyOrBuilder<any, M> | undefined;
|
|
15
15
|
export declare function getResolvedPropertyInPath(properties: Record<string, ResolvedProperty>, path: string): ResolvedProperty | undefined;
|
|
16
16
|
export declare function getBracketNotation(path: string): string;
|
|
17
17
|
/**
|
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.142",
|
|
5
5
|
"description": "Awesome Firebase/Firestore-based headless open-source CMS",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/firecmsco"
|
|
@@ -46,9 +46,9 @@
|
|
|
46
46
|
"./package.json": "./package.json"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@firecms/editor": "^3.0.0-canary.
|
|
50
|
-
"@firecms/formex": "^3.0.0-canary.
|
|
51
|
-
"@firecms/ui": "^3.0.0-canary.
|
|
49
|
+
"@firecms/editor": "^3.0.0-canary.142",
|
|
50
|
+
"@firecms/formex": "^3.0.0-canary.142",
|
|
51
|
+
"@firecms/ui": "^3.0.0-canary.142",
|
|
52
52
|
"@hello-pangea/dnd": "^17.0.0",
|
|
53
53
|
"@radix-ui/react-portal": "^1.1.2",
|
|
54
54
|
"clsx": "^2.1.1",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"markdown-it": "^14.1.0",
|
|
59
59
|
"notistack": "^3.0.1",
|
|
60
60
|
"object-hash": "^3.0.0",
|
|
61
|
-
"react-dropzone": "^14.2.
|
|
61
|
+
"react-dropzone": "^14.2.10",
|
|
62
62
|
"react-fast-compare": "^3.2.2",
|
|
63
63
|
"react-image-file-resizer": "^0.4.8",
|
|
64
64
|
"react-transition-group": "^4.4.5",
|
|
@@ -77,30 +77,30 @@
|
|
|
77
77
|
"@jest/globals": "^29.7.0",
|
|
78
78
|
"@testing-library/react": "^16.0.1",
|
|
79
79
|
"@testing-library/user-event": "^14.5.2",
|
|
80
|
-
"@types/jest": "^29.5.
|
|
80
|
+
"@types/jest": "^29.5.14",
|
|
81
81
|
"@types/node": "^20.16.11",
|
|
82
82
|
"@types/object-hash": "^3.0.6",
|
|
83
|
-
"@types/react": "^18.3.
|
|
84
|
-
"@types/react-dom": "^18.3.
|
|
83
|
+
"@types/react": "^18.3.12",
|
|
84
|
+
"@types/react-dom": "^18.3.1",
|
|
85
85
|
"@types/react-measure": "^2.0.12",
|
|
86
|
-
"@vitejs/plugin-react": "^4.3.
|
|
86
|
+
"@vitejs/plugin-react": "^4.3.3",
|
|
87
87
|
"cross-env": "^7.0.3",
|
|
88
|
-
"firebase": "^10.14.
|
|
88
|
+
"firebase": "^10.14.1",
|
|
89
89
|
"jest": "^29.7.0",
|
|
90
90
|
"npm-run-all": "^4.1.5",
|
|
91
|
-
"react-router": "^6.
|
|
92
|
-
"react-router-dom": "^6.
|
|
91
|
+
"react-router": "^6.27.0",
|
|
92
|
+
"react-router-dom": "^6.27.0",
|
|
93
93
|
"ts-jest": "^29.2.5",
|
|
94
94
|
"ts-node": "^10.9.2",
|
|
95
95
|
"tsd": "^0.31.2",
|
|
96
96
|
"typescript": "^5.6.3",
|
|
97
|
-
"vite": "^5.4.
|
|
97
|
+
"vite": "^5.4.10"
|
|
98
98
|
},
|
|
99
99
|
"files": [
|
|
100
100
|
"dist",
|
|
101
101
|
"src"
|
|
102
102
|
],
|
|
103
|
-
"gitHead": "
|
|
103
|
+
"gitHead": "9adfc426dab9b7e197f1080065e08d49366fdadd",
|
|
104
104
|
"publishConfig": {
|
|
105
105
|
"access": "public"
|
|
106
106
|
},
|
|
@@ -16,11 +16,21 @@ import {
|
|
|
16
16
|
useOutsideAlerter
|
|
17
17
|
} from "@firecms/ui";
|
|
18
18
|
|
|
19
|
+
export type ArrayEntryParams = {
|
|
20
|
+
index: number,
|
|
21
|
+
internalId: number,
|
|
22
|
+
isDragging: boolean,
|
|
23
|
+
storedProps?: object,
|
|
24
|
+
storeProps: (props: object) => void
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type ArrayEntryBuilder = (params: ArrayEntryParams) => React.ReactNode;
|
|
28
|
+
|
|
19
29
|
export interface ArrayContainerProps<T> {
|
|
20
30
|
droppableId: string;
|
|
21
31
|
value: T[];
|
|
22
32
|
addLabel: string;
|
|
23
|
-
buildEntry:
|
|
33
|
+
buildEntry: ArrayEntryBuilder;
|
|
24
34
|
disabled?: boolean;
|
|
25
35
|
size?: "small" | "medium";
|
|
26
36
|
onInternalIdAdded?: (id: number) => void;
|
|
@@ -67,6 +77,12 @@ export function ArrayContainer<T>({
|
|
|
67
77
|
? Object.values(internalIdsRef.current)
|
|
68
78
|
: []);
|
|
69
79
|
|
|
80
|
+
const itemCustomPropsRef = useRef<Record<number, object>>({});
|
|
81
|
+
|
|
82
|
+
const updateItemCustomProps = useCallback((internalId: number, customProps: object) => {
|
|
83
|
+
itemCustomPropsRef.current[internalId] = customProps;
|
|
84
|
+
}, []);
|
|
85
|
+
|
|
70
86
|
useEffect(() => {
|
|
71
87
|
if (hasValue && value && value.length !== internalIds.length) {
|
|
72
88
|
const newInternalIds = value.map((v, index) => {
|
|
@@ -149,6 +165,8 @@ export function ArrayContainer<T>({
|
|
|
149
165
|
remove={remove}
|
|
150
166
|
copy={copy}
|
|
151
167
|
isDragging={snapshot.isDragging}
|
|
168
|
+
storedProps={itemCustomPropsRef.current[internalId]}
|
|
169
|
+
updateItemCustomProps={updateItemCustomProps}
|
|
152
170
|
/>
|
|
153
171
|
);
|
|
154
172
|
}}
|
|
@@ -176,6 +194,8 @@ export function ArrayContainer<T>({
|
|
|
176
194
|
remove={remove}
|
|
177
195
|
copy={copy}
|
|
178
196
|
isDragging={snapshot.isDragging}
|
|
197
|
+
storedProps={itemCustomPropsRef.current[internalId]}
|
|
198
|
+
updateItemCustomProps={updateItemCustomProps}
|
|
179
199
|
/>
|
|
180
200
|
)}
|
|
181
201
|
</Draggable>
|
|
@@ -208,10 +228,12 @@ type ArrayContainerItemProps = {
|
|
|
208
228
|
internalId: number,
|
|
209
229
|
size?: "small" | "medium",
|
|
210
230
|
disabled: boolean,
|
|
211
|
-
buildEntry:
|
|
231
|
+
buildEntry: ArrayEntryBuilder,
|
|
212
232
|
remove: (index: number) => void,
|
|
213
233
|
copy: (index: number) => void,
|
|
214
234
|
isDragging: boolean,
|
|
235
|
+
storedProps?: object,
|
|
236
|
+
updateItemCustomProps: (internalId: number, props: object) => void
|
|
215
237
|
};
|
|
216
238
|
|
|
217
239
|
export function ArrayContainerItem({
|
|
@@ -223,29 +245,30 @@ export function ArrayContainerItem({
|
|
|
223
245
|
buildEntry,
|
|
224
246
|
remove,
|
|
225
247
|
copy,
|
|
226
|
-
isDragging
|
|
248
|
+
isDragging,
|
|
249
|
+
storedProps,
|
|
250
|
+
updateItemCustomProps
|
|
227
251
|
}: ArrayContainerItemProps) {
|
|
228
252
|
|
|
229
|
-
const [onHover, setOnHover] = React.useState(false);
|
|
230
|
-
const setOnHoverTrue = useCallback(() => setOnHover(true), []);
|
|
231
|
-
const setOnHoverFalse = useCallback(() => setOnHover(false), []);
|
|
232
|
-
|
|
233
253
|
return <div
|
|
234
|
-
onMouseEnter={setOnHoverTrue}
|
|
235
|
-
onMouseMove={setOnHoverTrue}
|
|
236
|
-
onMouseLeave={setOnHoverFalse}
|
|
237
254
|
ref={provided.innerRef}
|
|
238
255
|
{...provided.draggableProps}
|
|
239
256
|
style={provided.draggableProps.style}
|
|
240
257
|
className={`${
|
|
241
|
-
|
|
242
|
-
}
|
|
258
|
+
!isDragging ? "hover:bg-slate-50 dark:hover:bg-gray-800 dark:hover:bg-opacity-20" : ""
|
|
259
|
+
} rounded-md opacity-100`}
|
|
243
260
|
>
|
|
244
261
|
<div
|
|
245
262
|
className="flex items-start">
|
|
246
263
|
<div
|
|
247
264
|
className="flex-grow w-[calc(100%-48px)] text-text-primary dark:text-text-primary-dark">
|
|
248
|
-
{buildEntry(
|
|
265
|
+
{buildEntry({
|
|
266
|
+
index,
|
|
267
|
+
internalId,
|
|
268
|
+
isDragging,
|
|
269
|
+
storedProps,
|
|
270
|
+
storeProps: (props: object) => updateItemCustomProps(internalId, props)
|
|
271
|
+
})}
|
|
249
272
|
</div>
|
|
250
273
|
<ArrayItemOptions direction={size === "small" ? "row" : "column"}
|
|
251
274
|
disabled={disabled}
|
|
@@ -89,8 +89,8 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any>>(
|
|
|
89
89
|
} = useSelectableTableController();
|
|
90
90
|
|
|
91
91
|
const selected = selectedCell?.propertyKey === propertyKey &&
|
|
92
|
-
selectedCell?.
|
|
93
|
-
selectedCell?.
|
|
92
|
+
selectedCell?.entityPath === entity.path &&
|
|
93
|
+
selectedCell?.entityId === entity.id;
|
|
94
94
|
|
|
95
95
|
const [internalValue, setInternalValue] = useState<any | null>(value);
|
|
96
96
|
const internalValueRef = useRef(value);
|
|
@@ -193,7 +193,8 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any>>(
|
|
|
193
193
|
select({
|
|
194
194
|
width,
|
|
195
195
|
height,
|
|
196
|
-
entity,
|
|
196
|
+
entityPath: entity.path,
|
|
197
|
+
entityId: entity.id,
|
|
197
198
|
cellRect,
|
|
198
199
|
propertyKey: propertyKey as Extract<keyof M, string>
|
|
199
200
|
});
|
|
@@ -209,7 +210,8 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any>>(
|
|
|
209
210
|
setPopupCell({
|
|
210
211
|
width,
|
|
211
212
|
height,
|
|
212
|
-
entity,
|
|
213
|
+
entityPath: entity.path,
|
|
214
|
+
entityId: entity.id,
|
|
213
215
|
cellRect,
|
|
214
216
|
propertyKey: propertyKey as Extract<keyof M, string>
|
|
215
217
|
});
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useLayoutEffect, useMemo, useState } from "react";
|
|
2
|
-
import equal from "react-fast-compare"
|
|
3
2
|
|
|
4
3
|
import * as Portal from "@radix-ui/react-portal";
|
|
5
4
|
|
|
@@ -19,20 +18,19 @@ import { useDraggable } from "./useDraggable";
|
|
|
19
18
|
import { CustomFieldValidator, getYupEntitySchema } from "../../../../form/validation";
|
|
20
19
|
import { useWindowSize } from "./useWindowSize";
|
|
21
20
|
import { ElementResizeListener } from "./ElementResizeListener";
|
|
22
|
-
import { ErrorView } from "../../../ErrorView";
|
|
23
21
|
import { getPropertyInPath, isReadOnly, resolveCollection } from "../../../../util";
|
|
24
22
|
import { Button, ClearIcon, DialogActions, IconButton, Typography } from "@firecms/ui";
|
|
25
23
|
import { PropertyFieldBinding } from "../../../../form";
|
|
26
|
-
import { useCustomizationController, useFireCMSContext } from "../../../../hooks";
|
|
24
|
+
import { useCustomizationController, useDataSource, useFireCMSContext } from "../../../../hooks";
|
|
27
25
|
import { OnCellValueChangeParams } from "../../../common";
|
|
28
26
|
|
|
29
27
|
interface PopupFormFieldProps<M extends Record<string, any>> {
|
|
30
|
-
entity: Entity<M>;
|
|
31
28
|
customFieldValidator?: CustomFieldValidator;
|
|
32
29
|
path: string;
|
|
30
|
+
entityId: string;
|
|
33
31
|
tableKey: string;
|
|
34
32
|
propertyKey?: Extract<keyof M, string>;
|
|
35
|
-
collection?: EntityCollection<
|
|
33
|
+
collection?: EntityCollection<any>;
|
|
36
34
|
cellRect?: DOMRect;
|
|
37
35
|
open: boolean;
|
|
38
36
|
onClose: () => void;
|
|
@@ -46,13 +44,54 @@ interface PopupFormFieldProps<M extends Record<string, any>> {
|
|
|
46
44
|
|
|
47
45
|
export function PopupFormField<M extends Record<string, any>>(props: PopupFormFieldProps<M>) {
|
|
48
46
|
if (!props.open) return null;
|
|
49
|
-
return <
|
|
47
|
+
return <PopupFormFieldLoading {...props} />;
|
|
50
48
|
|
|
51
49
|
}
|
|
52
50
|
|
|
51
|
+
export function PopupFormFieldLoading<M extends Record<string, any>>({
|
|
52
|
+
tableKey,
|
|
53
|
+
entityId,
|
|
54
|
+
customFieldValidator,
|
|
55
|
+
propertyKey,
|
|
56
|
+
collection: inputCollection,
|
|
57
|
+
path,
|
|
58
|
+
cellRect,
|
|
59
|
+
open,
|
|
60
|
+
onClose,
|
|
61
|
+
onCellValueChange,
|
|
62
|
+
container
|
|
63
|
+
}: PopupFormFieldProps<M>) {
|
|
64
|
+
const dataSource = useDataSource();
|
|
65
|
+
const [entity, setEntity] = useState<Entity<M> | undefined>(undefined);
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
if (entityId && inputCollection) {
|
|
68
|
+
dataSource.fetchEntity({
|
|
69
|
+
path,
|
|
70
|
+
entityId,
|
|
71
|
+
collection: inputCollection
|
|
72
|
+
}).then(setEntity);
|
|
73
|
+
}
|
|
74
|
+
}, [entityId, inputCollection]);
|
|
75
|
+
|
|
76
|
+
if (!entity) return null;
|
|
77
|
+
return <PopupFormFieldInternal {...{
|
|
78
|
+
tableKey,
|
|
79
|
+
entityId,
|
|
80
|
+
customFieldValidator,
|
|
81
|
+
propertyKey,
|
|
82
|
+
collection: inputCollection,
|
|
83
|
+
path,
|
|
84
|
+
cellRect,
|
|
85
|
+
open,
|
|
86
|
+
onClose,
|
|
87
|
+
onCellValueChange,
|
|
88
|
+
container
|
|
89
|
+
}} entity={entity}/>;
|
|
90
|
+
}
|
|
91
|
+
|
|
53
92
|
export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
54
93
|
tableKey,
|
|
55
|
-
|
|
94
|
+
entityId,
|
|
56
95
|
customFieldValidator,
|
|
57
96
|
propertyKey,
|
|
58
97
|
collection: inputCollection,
|
|
@@ -61,10 +100,12 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
61
100
|
open,
|
|
62
101
|
onClose,
|
|
63
102
|
onCellValueChange,
|
|
64
|
-
container
|
|
65
|
-
|
|
103
|
+
container,
|
|
104
|
+
entity
|
|
105
|
+
}: PopupFormFieldProps<M> & {
|
|
106
|
+
entity?: Entity<M>
|
|
107
|
+
}) {
|
|
66
108
|
|
|
67
|
-
// const dataSource = useDataSource();
|
|
68
109
|
const fireCMSContext = useFireCMSContext();
|
|
69
110
|
const customizationController = useCustomizationController();
|
|
70
111
|
|
|
@@ -74,32 +115,11 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
74
115
|
y: number
|
|
75
116
|
}>();
|
|
76
117
|
|
|
77
|
-
const entityId = entityProp.id;
|
|
78
|
-
const [entity, setEntity] = useState<Entity<M> | undefined>(entityProp);
|
|
79
|
-
// useEffect(() => {
|
|
80
|
-
// if (entityId && inputCollection) {
|
|
81
|
-
// return dataSource.listenEntity?.({
|
|
82
|
-
// path,
|
|
83
|
-
// entityId,
|
|
84
|
-
// collection: inputCollection,
|
|
85
|
-
// onUpdate: (e) => {
|
|
86
|
-
// setEntity(e);
|
|
87
|
-
// setInternalValue(e?.values);
|
|
88
|
-
// }
|
|
89
|
-
// });
|
|
90
|
-
// } else {
|
|
91
|
-
// return () => {
|
|
92
|
-
// };
|
|
93
|
-
// }
|
|
94
|
-
// }, [dataSource, entityId, inputCollection, path, open]);
|
|
95
|
-
|
|
96
|
-
const [internalValue, setInternalValue] = useState<EntityValues<M> | undefined>(entity?.values);
|
|
97
|
-
|
|
98
118
|
const collection: ResolvedEntityCollection<M> | undefined = inputCollection
|
|
99
119
|
? resolveCollection<M>({
|
|
100
120
|
collection: inputCollection,
|
|
101
121
|
path,
|
|
102
|
-
values:
|
|
122
|
+
values: entity?.values,
|
|
103
123
|
entityId,
|
|
104
124
|
propertyConfigs: customizationController.propertyConfigs
|
|
105
125
|
})
|
|
@@ -214,10 +234,6 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
214
234
|
return Promise.resolve();
|
|
215
235
|
};
|
|
216
236
|
|
|
217
|
-
if (!entity)
|
|
218
|
-
return <></>;
|
|
219
|
-
|
|
220
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
221
237
|
const formex = useCreateFormex<M>({
|
|
222
238
|
initialValues: (entity?.values ?? {}) as EntityValues<M>,
|
|
223
239
|
validation: (values) => {
|
|
@@ -234,26 +250,22 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
234
250
|
validateOnInitialRender: true,
|
|
235
251
|
onSubmit: (values, actions) => {
|
|
236
252
|
saveValue(values)
|
|
237
|
-
.then(() =>
|
|
253
|
+
.then(() => {
|
|
254
|
+
formex.resetForm({
|
|
255
|
+
values: values
|
|
256
|
+
})
|
|
257
|
+
onClose();
|
|
258
|
+
})
|
|
238
259
|
.finally(() => actions.setSubmitting(false));
|
|
239
260
|
}
|
|
240
261
|
});
|
|
241
262
|
|
|
242
|
-
const {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
}, [values]);
|
|
250
|
-
|
|
251
|
-
if (!entity)
|
|
252
|
-
return <ErrorView
|
|
253
|
-
error={"PopupFormField misconfiguration"}/>;
|
|
254
|
-
|
|
255
|
-
if (!collection)
|
|
256
|
-
return <></>;
|
|
263
|
+
const {
|
|
264
|
+
values,
|
|
265
|
+
isSubmitting,
|
|
266
|
+
setFieldValue,
|
|
267
|
+
handleSubmit
|
|
268
|
+
} = formex;
|
|
257
269
|
|
|
258
270
|
const disabled = isSubmitting;
|
|
259
271
|
|
|
@@ -267,7 +279,7 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
267
279
|
formex
|
|
268
280
|
};
|
|
269
281
|
|
|
270
|
-
const property: ResolvedProperty<any> | undefined = propertyKey && getPropertyInPath(collection
|
|
282
|
+
const property: ResolvedProperty<any> | undefined = propertyKey && getPropertyInPath(collection?.properties ?? {} as ResolvedProperties, propertyKey as string);
|
|
271
283
|
const fieldProps: PropertyFieldBindingProps<any, M> | undefined = propertyKey && property
|
|
272
284
|
? {
|
|
273
285
|
propertyKey: propertyKey as string,
|
|
@@ -285,7 +297,7 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
285
297
|
let internalForm = <>
|
|
286
298
|
<div
|
|
287
299
|
key={`popup_form_${tableKey}_${entityId}_${propertyKey}`}
|
|
288
|
-
className="w-[
|
|
300
|
+
className="w-[700px] max-w-full max-h-[85vh]">
|
|
289
301
|
<form
|
|
290
302
|
onSubmit={handleSubmit}
|
|
291
303
|
noValidate>
|
|
@@ -320,10 +332,6 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
320
332
|
|
|
321
333
|
const plugins = customizationController.plugins;
|
|
322
334
|
if (plugins) {
|
|
323
|
-
// const formController: FormContext<M> = {
|
|
324
|
-
// values,
|
|
325
|
-
// setFieldValue
|
|
326
|
-
// }
|
|
327
335
|
plugins.forEach((plugin: FireCMSPlugin) => {
|
|
328
336
|
if (plugin.form?.provider) {
|
|
329
337
|
internalForm = (
|
|
@@ -665,13 +665,13 @@ export const EntityCollectionView = React.memo(
|
|
|
665
665
|
/>
|
|
666
666
|
|
|
667
667
|
{popupCell && <PopupFormField
|
|
668
|
-
key={`popup_form_${popupCell?.propertyKey}_${popupCell?.
|
|
668
|
+
key={`popup_form_${popupCell?.propertyKey}_${popupCell?.entityId}`}
|
|
669
669
|
open={Boolean(popupCell)}
|
|
670
670
|
onClose={onPopupClose}
|
|
671
671
|
cellRect={popupCell?.cellRect}
|
|
672
672
|
propertyKey={popupCell?.propertyKey}
|
|
673
673
|
collection={collection}
|
|
674
|
-
|
|
674
|
+
entityId={popupCell.entityId}
|
|
675
675
|
tableKey={tableKey.current}
|
|
676
676
|
customFieldValidator={uniqueFieldValidator}
|
|
677
677
|
path={resolvedFullPath}
|
|
@@ -785,7 +785,6 @@ function EntityIdHeaderWidget({
|
|
|
785
785
|
const [recentIds, setRecentIds] = React.useState<string[]>(getRecentIds(collection.id));
|
|
786
786
|
const sideEntityController = useSideEntityController();
|
|
787
787
|
|
|
788
|
-
|
|
789
788
|
return (
|
|
790
789
|
<Tooltip title={!openPopup ? "Find by ID" : undefined} asChild={false}>
|
|
791
790
|
<Popover
|
|
@@ -86,7 +86,8 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
|
|
|
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();
|
|
@@ -124,6 +125,7 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
|
|
|
124
125
|
if (!propertyConfig) {
|
|
125
126
|
console.log("INTERNAL: Could not find field config for property", {
|
|
126
127
|
propertyKey,
|
|
128
|
+
property,
|
|
127
129
|
resolvedProperty,
|
|
128
130
|
fields: customizationController.propertyConfigs,
|
|
129
131
|
propertyConfig
|
|
@@ -159,13 +161,14 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
|
|
|
159
161
|
partOfArray,
|
|
160
162
|
minimalistView,
|
|
161
163
|
autoFocus,
|
|
162
|
-
size
|
|
164
|
+
size,
|
|
165
|
+
onPropertyChange
|
|
163
166
|
};
|
|
164
167
|
|
|
165
168
|
return <FieldInternal
|
|
166
169
|
Component={Component as ComponentType<FieldProps>}
|
|
167
170
|
componentProps={componentProps}
|
|
168
|
-
|
|
171
|
+
formexFieldProps={fieldProps}/>;
|
|
169
172
|
}}
|
|
170
173
|
</Field>
|
|
171
174
|
);
|
|
@@ -191,26 +194,27 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
|
|
|
191
194
|
autoFocus,
|
|
192
195
|
context,
|
|
193
196
|
disabled,
|
|
194
|
-
size
|
|
197
|
+
size,
|
|
198
|
+
onPropertyChange
|
|
195
199
|
},
|
|
196
|
-
|
|
200
|
+
formexFieldProps
|
|
197
201
|
}:
|
|
198
202
|
{
|
|
199
203
|
Component: ComponentType<FieldProps<T, any, M>>,
|
|
200
204
|
componentProps: ResolvedPropertyFieldBindingProps<T, M>,
|
|
201
|
-
|
|
205
|
+
formexFieldProps: FormexFieldProps<T, any>
|
|
202
206
|
}) {
|
|
203
207
|
|
|
204
208
|
const { plugins } = useCustomizationController();
|
|
205
209
|
|
|
206
210
|
const customFieldProps: any = property.customProps;
|
|
207
|
-
const value =
|
|
208
|
-
// const initialValue =
|
|
209
|
-
const error = getIn(
|
|
210
|
-
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);
|
|
211
215
|
|
|
212
216
|
const showError: boolean = error &&
|
|
213
|
-
(
|
|
217
|
+
(formexFieldProps.form.submitCount > 0 || property.validation?.unique) &&
|
|
214
218
|
(!Array.isArray(error) || !!error.filter((e: any) => !!e).length);
|
|
215
219
|
|
|
216
220
|
const WrappedComponent: ComponentType<FieldProps<T, any, M>> | null = useWrappedComponent({
|
|
@@ -223,16 +227,16 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
|
|
|
223
227
|
});
|
|
224
228
|
const UsedComponent: ComponentType<FieldProps<T>> = WrappedComponent ?? Component;
|
|
225
229
|
|
|
226
|
-
const isSubmitting =
|
|
230
|
+
const isSubmitting = formexFieldProps.form.isSubmitting;
|
|
227
231
|
|
|
228
232
|
const setValue = useCallback((value: T | null, shouldValidate?: boolean) => {
|
|
229
|
-
|
|
230
|
-
|
|
233
|
+
formexFieldProps.form.setFieldTouched(propertyKey, true, false);
|
|
234
|
+
formexFieldProps.form.setFieldValue(propertyKey, value, shouldValidate);
|
|
231
235
|
}, []);
|
|
232
236
|
|
|
233
237
|
const setFieldValue = useCallback((otherPropertyKey: string, value: CMSType | null, shouldValidate?: boolean) => {
|
|
234
|
-
|
|
235
|
-
|
|
238
|
+
formexFieldProps.form.setFieldTouched(propertyKey, true, false);
|
|
239
|
+
formexFieldProps.form.setFieldValue(otherPropertyKey, value, shouldValidate);
|
|
236
240
|
}, []);
|
|
237
241
|
|
|
238
242
|
const cmsFieldProps: FieldProps<T, CustomProps, M> = {
|
|
@@ -253,7 +257,8 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
|
|
|
253
257
|
autoFocus: autoFocus ?? false,
|
|
254
258
|
customProps: customFieldProps,
|
|
255
259
|
context,
|
|
256
|
-
size
|
|
260
|
+
size,
|
|
261
|
+
onPropertyChange
|
|
257
262
|
};
|
|
258
263
|
|
|
259
264
|
return (
|