@webiny/app-admin 6.2.0 → 6.3.0-beta.0
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/base/Admin.js +2 -0
- package/base/Admin.js.map +1 -1
- package/base/Base/DefaultFieldRenderers.js +20 -4
- package/base/Base/DefaultFieldRenderers.js.map +1 -1
- package/base/Base/DefaultLayoutRenderers.d.ts +2 -0
- package/base/Base/DefaultLayoutRenderers.js +11 -0
- package/base/Base/DefaultLayoutRenderers.js.map +1 -0
- package/base/Base/FieldRenderers/InputRenderer.d.ts +15 -0
- package/base/Base/FieldRenderers/{TextRenderer.js → InputRenderer.js} +5 -3
- package/base/Base/FieldRenderers/InputRenderer.js.map +1 -0
- package/base/Base/FieldRenderers/ObjectRenderer/ObjectFieldComponents.d.ts +25 -0
- package/base/Base/FieldRenderers/ObjectRenderer/ObjectFieldComponents.js +89 -0
- package/base/Base/FieldRenderers/ObjectRenderer/ObjectFieldComponents.js.map +1 -0
- package/base/Base/FieldRenderers/ObjectRenderer/ObjectListFlatRenderer.d.ts +21 -0
- package/base/Base/FieldRenderers/ObjectRenderer/ObjectListFlatRenderer.js +28 -0
- package/base/Base/FieldRenderers/ObjectRenderer/ObjectListFlatRenderer.js.map +1 -0
- package/base/Base/FieldRenderers/ObjectRenderer/ObjectRenderer.d.ts +17 -0
- package/base/Base/FieldRenderers/ObjectRenderer/ObjectRenderer.js +63 -0
- package/base/Base/FieldRenderers/ObjectRenderer/ObjectRenderer.js.map +1 -0
- package/base/Base/FieldRenderers/ObjectRenderer/resolveItemTitle.d.ts +4 -0
- package/base/Base/FieldRenderers/ObjectRenderer/resolveItemTitle.js +22 -0
- package/base/Base/FieldRenderers/ObjectRenderer/resolveItemTitle.js.map +1 -0
- package/base/Base/FieldRenderers/PassthroughRenderer.d.ts +15 -0
- package/base/Base/FieldRenderers/PassthroughRenderer.js +29 -0
- package/base/Base/FieldRenderers/PassthroughRenderer.js.map +1 -0
- package/base/Base/FieldRenderers/SelectRenderer.d.ts +12 -2
- package/base/Base/FieldRenderers/SelectRenderer.js +4 -2
- package/base/Base/FieldRenderers/SelectRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/TextareaRenderer.d.ts +17 -0
- package/base/Base/FieldRenderers/TextareaRenderer.js +25 -0
- package/base/Base/FieldRenderers/TextareaRenderer.js.map +1 -0
- package/base/Base/FieldRenderers/VerticalTabsRenderer.d.ts +5 -0
- package/base/Base/FieldRenderers/VerticalTabsRenderer.js +41 -0
- package/base/Base/FieldRenderers/VerticalTabsRenderer.js.map +1 -0
- package/base/Base.js +2 -1
- package/base/Base.js.map +1 -1
- package/base/createRootContainer.js +4 -0
- package/base/createRootContainer.js.map +1 -1
- package/base/providers/UiProviders.js +0 -1
- package/base/providers/UiProviders.js.map +1 -1
- package/components/Filters/Filters.js.map +1 -1
- package/components/IconPicker/components/IconPickerCell.d.ts +1 -1
- package/components/IconPicker/components/IconPickerTrigger.d.ts +1 -1
- package/components/IconPicker/components/IconPickerTrigger.js.map +1 -1
- package/components/LexicalEditor/LexicalEditor.js +7 -1
- package/components/LexicalEditor/LexicalEditor.js.map +1 -1
- package/components/LexicalEditor/lexicalValueFromHtml.d.ts +7 -0
- package/components/LexicalEditor/lexicalValueFromHtml.js +35 -0
- package/components/LexicalEditor/lexicalValueFromHtml.js.map +1 -0
- package/components/OverlayLayout/components/OverlayHeader.d.ts +1 -1
- package/components/OverlayLayout/components/OverlayHeader.js.map +1 -1
- package/components/SimpleForm/SimpleForm.d.ts +2 -2
- package/components/SimpleForm/SimpleForm.js.map +1 -1
- package/config/AdminConfig/Form.d.ts +1 -0
- package/config/AdminConfig/Form.js +3 -1
- package/config/AdminConfig/Form.js.map +1 -1
- package/config/AdminConfig/LayoutRenderer.d.ts +10 -0
- package/config/AdminConfig/LayoutRenderer.js +21 -0
- package/config/AdminConfig/LayoutRenderer.js.map +1 -0
- package/config/AdminConfig/Menu/MenuLink.d.ts +2 -2
- package/config/AdminConfig.d.ts +4 -0
- package/config/AdminConfig.js +2 -1
- package/config/AdminConfig.js.map +1 -1
- package/exports/admin.d.ts +2 -0
- package/exports/admin.js +2 -0
- package/exports/admin.js.map +1 -1
- package/features/formModel/Field.js +4 -0
- package/features/formModel/Field.js.map +1 -1
- package/features/formModel/FieldBuilder.d.ts +18 -2
- package/features/formModel/FieldBuilder.js +57 -3
- package/features/formModel/FieldBuilder.js.map +1 -1
- package/features/formModel/FormModel.d.ts +3 -3
- package/features/formModel/FormModel.js +48 -13
- package/features/formModel/FormModel.js.map +1 -1
- package/features/formModel/FormModel.test.js +383 -0
- package/features/formModel/FormModel.test.js.map +1 -1
- package/features/formModel/FormModelFactory.d.ts +2 -2
- package/features/formModel/FormModelFactory.js.map +1 -1
- package/features/formModel/FormView.d.ts +24 -4
- package/features/formModel/FormView.js +57 -27
- package/features/formModel/FormView.js.map +1 -1
- package/features/formModel/ObjectField.d.ts +46 -0
- package/features/formModel/ObjectField.js +346 -0
- package/features/formModel/ObjectField.js.map +1 -0
- package/features/formModel/abstractions.d.ts +88 -19
- package/features/formModel/abstractions.js +8 -0
- package/features/formModel/abstractions.js.map +1 -1
- package/features/formModel/index.d.ts +7 -4
- package/features/formModel/index.js +9 -2
- package/features/formModel/index.js.map +1 -1
- package/features/formModel/renderers.d.ts +6 -0
- package/features/formModel/renderers.js +10 -0
- package/features/formModel/renderers.js.map +1 -0
- package/features/formModel/useLayoutRenderers.d.ts +2 -0
- package/features/formModel/useLayoutRenderers.js +19 -0
- package/features/formModel/useLayoutRenderers.js.map +1 -0
- package/features/tools/ToolPipelineRunner.d.ts +10 -0
- package/features/tools/ToolPipelineRunner.js +33 -0
- package/features/tools/ToolPipelineRunner.js.map +1 -0
- package/features/tools/ToolRegistry.d.ts +12 -0
- package/features/tools/ToolRegistry.js +29 -0
- package/features/tools/ToolRegistry.js.map +1 -0
- package/features/tools/abstractions.d.ts +28 -0
- package/features/tools/abstractions.js +6 -0
- package/features/tools/abstractions.js.map +1 -0
- package/features/tools/feature.d.ts +4 -0
- package/features/tools/feature.js +19 -0
- package/features/tools/feature.js.map +1 -0
- package/features/tools/index.d.ts +2 -0
- package/features/tools/index.js +4 -0
- package/features/tools/index.js.map +1 -0
- package/features/wcp/ReactLicense.d.ts +3 -0
- package/features/wcp/ReactLicense.js +9 -0
- package/features/wcp/ReactLicense.js.map +1 -1
- package/features/wcp/WcpGateway.js +4 -0
- package/features/wcp/WcpGateway.js.map +1 -1
- package/features/webinySdk/WebinySdk.d.ts +11 -0
- package/features/webinySdk/WebinySdk.js +27 -0
- package/features/webinySdk/WebinySdk.js.map +1 -0
- package/features/webinySdk/abstractions.d.ts +6 -0
- package/features/webinySdk/abstractions.js +8 -0
- package/features/webinySdk/abstractions.js.map +1 -0
- package/features/webinySdk/feature.d.ts +3 -0
- package/features/webinySdk/feature.js +16 -0
- package/features/webinySdk/feature.js.map +1 -0
- package/features/webinySdk/index.d.ts +2 -0
- package/features/webinySdk/index.js +4 -0
- package/features/webinySdk/index.js.map +1 -0
- package/index.d.ts +8 -3
- package/index.js +5 -2
- package/index.js.map +1 -1
- package/package.json +24 -23
- package/presentation/textToLexicalTool/TextToLexicalTool.d.ts +27 -0
- package/presentation/textToLexicalTool/TextToLexicalTool.js +25 -0
- package/presentation/textToLexicalTool/TextToLexicalTool.js.map +1 -0
- package/presentation/textToLexicalTool/feature.d.ts +1 -0
- package/presentation/textToLexicalTool/feature.js +10 -0
- package/presentation/textToLexicalTool/feature.js.map +1 -0
- package/presentation/textToLexicalTool/textToLexicalState.d.ts +5 -0
- package/presentation/textToLexicalTool/textToLexicalState.js +19 -0
- package/presentation/textToLexicalTool/textToLexicalState.js.map +1 -0
- package/base/Base/FieldRenderers/TextRenderer.d.ts +0 -5
- package/base/Base/FieldRenderers/TextRenderer.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { FormModel } from "./FormModel.js";
|
|
2
1
|
import { type IFormModelFactory, type IFormModelConfig } from "./abstractions.js";
|
|
2
|
+
import type { IFormModel } from "./abstractions.js";
|
|
3
3
|
declare class FormModelFactoryImpl implements IFormModelFactory {
|
|
4
|
-
create(config: IFormModelConfig):
|
|
4
|
+
create<T = Record<string, any>>(config: IFormModelConfig): IFormModel<T>;
|
|
5
5
|
}
|
|
6
6
|
export declare const FormModelFactory: typeof FormModelFactoryImpl & {
|
|
7
7
|
__abstraction: import("@webiny/di").Abstraction<IFormModelFactory>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["FormModel","FormModelFactory","Abstraction","FormModelFactoryImpl","create","config","createImplementation","implementation","dependencies"],"sources":["FormModelFactory.ts"],"sourcesContent":["import { FormModel } from \"./FormModel.js\";\nimport {\n FormModelFactory as Abstraction,\n type IFormModelFactory,\n type IFormModelConfig\n} from \"./abstractions.js\";\n\nclass FormModelFactoryImpl implements IFormModelFactory {\n create(config: IFormModelConfig):
|
|
1
|
+
{"version":3,"names":["FormModel","FormModelFactory","Abstraction","FormModelFactoryImpl","create","config","createImplementation","implementation","dependencies"],"sources":["FormModelFactory.ts"],"sourcesContent":["import { FormModel } from \"./FormModel.js\";\nimport {\n FormModelFactory as Abstraction,\n type IFormModelFactory,\n type IFormModelConfig\n} from \"./abstractions.js\";\nimport type { IFormModel } from \"./abstractions.js\";\n\nclass FormModelFactoryImpl implements IFormModelFactory {\n create<T = Record<string, any>>(config: IFormModelConfig): IFormModel<T> {\n return new FormModel(config) as IFormModel<T>;\n }\n}\n\nexport const FormModelFactory = Abstraction.createImplementation({\n implementation: FormModelFactoryImpl,\n dependencies: []\n});\n"],"mappings":"AAAA,SAASA,SAAS;AAClB,SACIC,gBAAgB,IAAIC,WAAW;AAMnC,MAAMC,oBAAoB,CAA8B;EACpDC,MAAMA,CAA0BC,MAAwB,EAAiB;IACrE,OAAO,IAAIL,SAAS,CAACK,MAAM,CAAC;EAChC;AACJ;AAEA,OAAO,MAAMJ,gBAAgB,GAAGC,WAAW,CAACI,oBAAoB,CAAC;EAC7DC,cAAc,EAAEJ,oBAAoB;EACpCK,YAAY,EAAE;AAClB,CAAC,CAAC","ignoreList":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import type { IFormVM, IFieldVM } from "./abstractions.js";
|
|
2
|
+
import type { IFormVM, LayoutNodeVM, IFieldVM, ITabsNodeVM } from "./abstractions.js";
|
|
3
3
|
/**
|
|
4
4
|
* A field renderer component receives a FieldVM and renders the appropriate UI.
|
|
5
5
|
*/
|
|
@@ -7,17 +7,37 @@ export type FieldRendererComponent = React.ComponentType<{
|
|
|
7
7
|
field: IFieldVM;
|
|
8
8
|
}>;
|
|
9
9
|
/**
|
|
10
|
-
* Map of renderer keys to React components.
|
|
10
|
+
* Map of renderer keys to React components for fields.
|
|
11
11
|
* Lookup order: `{type}:{renderer}` → `{type}`.
|
|
12
12
|
*/
|
|
13
13
|
export type FieldRenderers = Record<string, FieldRendererComponent>;
|
|
14
|
+
/**
|
|
15
|
+
* Map of renderer keys to React components for layout nodes.
|
|
16
|
+
*/
|
|
17
|
+
export type LayoutRenderers = Record<string, React.ComponentType<any>>;
|
|
18
|
+
interface FormViewRenderers {
|
|
19
|
+
fieldRenderers: FieldRenderers;
|
|
20
|
+
layoutRenderers: LayoutRenderers;
|
|
21
|
+
}
|
|
22
|
+
declare const useFormViewRenderers: () => FormViewRenderers;
|
|
23
|
+
export { useFormViewRenderers };
|
|
14
24
|
interface FormViewProps {
|
|
15
25
|
form: IFormVM;
|
|
16
26
|
renderers?: FieldRenderers;
|
|
27
|
+
layoutRenderers?: LayoutRenderers;
|
|
17
28
|
}
|
|
18
29
|
/**
|
|
19
30
|
* Generic form view that walks layout nodes and renders fields.
|
|
20
31
|
* This component is stateless — it reads from the FormVM and delegates to renderers.
|
|
21
32
|
*/
|
|
22
|
-
export declare const FormView: React.
|
|
23
|
-
|
|
33
|
+
export declare const FormView: (({ form, renderers, layoutRenderers }: FormViewProps) => React.JSX.Element) & {
|
|
34
|
+
displayName: string;
|
|
35
|
+
};
|
|
36
|
+
export declare const LayoutNodeRenderer: (({ node }: {
|
|
37
|
+
node: LayoutNodeVM;
|
|
38
|
+
}) => React.JSX.Element | null) & {
|
|
39
|
+
displayName: string;
|
|
40
|
+
};
|
|
41
|
+
export interface TabsNodeRendererProps {
|
|
42
|
+
node: ITabsNodeVM;
|
|
43
|
+
}
|
|
@@ -1,63 +1,82 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { createContext, useContext, useMemo } from "react";
|
|
2
2
|
import { observer } from "mobx-react-lite";
|
|
3
3
|
import { useFieldRenderers } from "./useFieldRenderers.js";
|
|
4
|
+
import { useLayoutRenderers } from "./useLayoutRenderers.js";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* A field renderer component receives a FieldVM and renders the appropriate UI.
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
|
-
* Map of renderer keys to React components.
|
|
11
|
+
* Map of renderer keys to React components for fields.
|
|
11
12
|
* Lookup order: `{type}:{renderer}` → `{type}`.
|
|
12
13
|
*/
|
|
13
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Map of renderer keys to React components for layout nodes.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const FormViewRenderersContext = /*#__PURE__*/createContext(null);
|
|
20
|
+
const useFormViewRenderers = () => {
|
|
21
|
+
const ctx = useContext(FormViewRenderersContext);
|
|
22
|
+
if (!ctx) {
|
|
23
|
+
throw new Error("useFormViewRenderers must be used within a FormView.");
|
|
24
|
+
}
|
|
25
|
+
return ctx;
|
|
26
|
+
};
|
|
27
|
+
export { useFormViewRenderers };
|
|
14
28
|
/**
|
|
15
29
|
* Generic form view that walks layout nodes and renders fields.
|
|
16
30
|
* This component is stateless — it reads from the FormVM and delegates to renderers.
|
|
17
31
|
*/
|
|
18
32
|
export const FormView = observer(function FormView({
|
|
19
33
|
form,
|
|
20
|
-
renderers
|
|
34
|
+
renderers,
|
|
35
|
+
layoutRenderers
|
|
21
36
|
}) {
|
|
22
|
-
const
|
|
23
|
-
|
|
37
|
+
const defaultFieldRenderers = useFieldRenderers();
|
|
38
|
+
const defaultLayoutRenderers = useLayoutRenderers();
|
|
39
|
+
const value = useMemo(() => ({
|
|
40
|
+
fieldRenderers: renderers ?? defaultFieldRenderers,
|
|
41
|
+
layoutRenderers: layoutRenderers ?? defaultLayoutRenderers
|
|
42
|
+
}), [renderers, defaultFieldRenderers, layoutRenderers, defaultLayoutRenderers]);
|
|
43
|
+
return /*#__PURE__*/React.createElement(FormViewRenderersContext.Provider, {
|
|
44
|
+
value: value
|
|
45
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
24
46
|
className: "w-full flex flex-col gap-4"
|
|
25
47
|
}, form.layout.map((node, index) => /*#__PURE__*/React.createElement(LayoutNodeRenderer, {
|
|
26
48
|
key: index,
|
|
27
|
-
node: node
|
|
28
|
-
|
|
29
|
-
})));
|
|
49
|
+
node: node
|
|
50
|
+
}))));
|
|
30
51
|
});
|
|
31
|
-
const LayoutNodeRenderer = observer(function LayoutNodeRenderer({
|
|
32
|
-
node
|
|
33
|
-
renderers
|
|
52
|
+
export const LayoutNodeRenderer = observer(function LayoutNodeRenderer({
|
|
53
|
+
node
|
|
34
54
|
}) {
|
|
35
55
|
switch (node.type) {
|
|
36
56
|
case "row":
|
|
37
57
|
return /*#__PURE__*/React.createElement(RowNodeRenderer, {
|
|
38
|
-
node: node
|
|
39
|
-
renderers: renderers
|
|
58
|
+
node: node
|
|
40
59
|
});
|
|
41
60
|
case "separator":
|
|
42
61
|
return /*#__PURE__*/React.createElement(SeparatorNodeRenderer, null);
|
|
43
62
|
case "tabs":
|
|
44
63
|
return /*#__PURE__*/React.createElement(TabsNodeRenderer, {
|
|
45
|
-
node: node
|
|
46
|
-
renderers: renderers
|
|
64
|
+
node: node
|
|
47
65
|
});
|
|
48
66
|
case "element":
|
|
49
67
|
return /*#__PURE__*/React.createElement(ElementNodeRenderer, {
|
|
50
|
-
node: node
|
|
51
|
-
renderers: renderers
|
|
68
|
+
node: node
|
|
52
69
|
});
|
|
53
70
|
default:
|
|
54
71
|
return null;
|
|
55
72
|
}
|
|
56
73
|
});
|
|
57
74
|
const RowNodeRenderer = observer(function RowNodeRenderer({
|
|
58
|
-
node
|
|
59
|
-
renderers
|
|
75
|
+
node
|
|
60
76
|
}) {
|
|
77
|
+
const {
|
|
78
|
+
fieldRenderers
|
|
79
|
+
} = useFormViewRenderers();
|
|
61
80
|
return /*#__PURE__*/React.createElement("div", {
|
|
62
81
|
className: "grid grid-cols-12 gap-4"
|
|
63
82
|
}, node.fields.map(field => {
|
|
@@ -67,7 +86,7 @@ const RowNodeRenderer = observer(function RowNodeRenderer({
|
|
|
67
86
|
className: `col-span-${span}`
|
|
68
87
|
}, /*#__PURE__*/React.createElement(FieldRenderer, {
|
|
69
88
|
field: field,
|
|
70
|
-
renderers:
|
|
89
|
+
renderers: fieldRenderers
|
|
71
90
|
}));
|
|
72
91
|
}));
|
|
73
92
|
});
|
|
@@ -92,9 +111,19 @@ const SeparatorNodeRenderer = observer(function SeparatorNodeRenderer() {
|
|
|
92
111
|
});
|
|
93
112
|
});
|
|
94
113
|
const TabsNodeRenderer = observer(function TabsNodeRenderer({
|
|
95
|
-
node
|
|
96
|
-
renderers
|
|
114
|
+
node
|
|
97
115
|
}) {
|
|
116
|
+
const {
|
|
117
|
+
layoutRenderers
|
|
118
|
+
} = useFormViewRenderers();
|
|
119
|
+
if (node.renderer) {
|
|
120
|
+
const CustomRenderer = layoutRenderers[node.renderer];
|
|
121
|
+
if (CustomRenderer) {
|
|
122
|
+
return /*#__PURE__*/React.createElement(CustomRenderer, {
|
|
123
|
+
node: node
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
98
127
|
const activeTab = node.tabs.find(t => t.id === node.activeTabId);
|
|
99
128
|
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
|
|
100
129
|
className: "flex border-b border-neutral-dimmed"
|
|
@@ -113,15 +142,16 @@ const TabsNodeRenderer = observer(function TabsNodeRenderer({
|
|
|
113
142
|
className: "flex flex-col gap-4"
|
|
114
143
|
}, activeTab.layout.map((childNode, index) => /*#__PURE__*/React.createElement(LayoutNodeRenderer, {
|
|
115
144
|
key: index,
|
|
116
|
-
node: childNode
|
|
117
|
-
renderers: renderers
|
|
145
|
+
node: childNode
|
|
118
146
|
})))));
|
|
119
147
|
});
|
|
120
148
|
const ElementNodeRenderer = observer(function ElementNodeRenderer({
|
|
121
|
-
node
|
|
122
|
-
renderers
|
|
149
|
+
node
|
|
123
150
|
}) {
|
|
124
|
-
const
|
|
151
|
+
const {
|
|
152
|
+
fieldRenderers
|
|
153
|
+
} = useFormViewRenderers();
|
|
154
|
+
const Renderer = fieldRenderers[`element:${node.renderer}`];
|
|
125
155
|
if (!Renderer) {
|
|
126
156
|
if (process.env.NODE_ENV === "development") {
|
|
127
157
|
console.warn(`[FormView] No renderer found for element "${node.renderer}".`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","observer","useFieldRenderers","FormView","form","renderers","fieldRenderers","createElement","className","layout","map","node","index","LayoutNodeRenderer","key","type","RowNodeRenderer","SeparatorNodeRenderer","TabsNodeRenderer","ElementNodeRenderer","fields","field","span","Math","floor","length","name","FieldRenderer","Renderer","renderer","undefined","process","env","NODE_ENV","console","warn","activeTab","tabs","find","t","id","activeTabId","tab","onClick","setActiveTab","label","hasErrors","description","childNode","props"],"sources":["FormView.tsx"],"sourcesContent":["import React from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport type {\n IFormVM,\n LayoutNodeVM,\n IRowNodeVM,\n IFieldVM,\n ITabsNodeVM,\n IElementNodeVM\n} from \"./abstractions.js\";\nimport { useFieldRenderers } from \"~/features/formModel/useFieldRenderers.js\";\n\n/**\n * A field renderer component receives a FieldVM and renders the appropriate UI.\n */\nexport type FieldRendererComponent = React.ComponentType<{ field: IFieldVM }>;\n\n/**\n * Map of renderer keys to React components.\n * Lookup order: `{type}:{renderer}` → `{type}`.\n */\nexport type FieldRenderers = Record<string, FieldRendererComponent>;\n\ninterface FormViewProps {\n form: IFormVM;\n renderers?: FieldRenderers;\n}\n\n/**\n * Generic form view that walks layout nodes and renders fields.\n * This component is stateless — it reads from the FormVM and delegates to renderers.\n */\nexport const FormView = observer(function FormView({ form, renderers }: FormViewProps) {\n const fieldRenderers = useFieldRenderers();\n\n return (\n <div className=\"w-full flex flex-col gap-4\">\n {form.layout.map((node, index) => (\n <LayoutNodeRenderer\n key={index}\n node={node}\n renderers={renderers ?? fieldRenderers}\n />\n ))}\n </div>\n );\n});\n\ninterface LayoutNodeRendererProps {\n node: LayoutNodeVM;\n renderers: FieldRenderers;\n}\n\nconst LayoutNodeRenderer = observer(function LayoutNodeRenderer({\n node,\n renderers\n}: LayoutNodeRendererProps) {\n switch (node.type) {\n case \"row\":\n return <RowNodeRenderer node={node} renderers={renderers} />;\n case \"separator\":\n return <SeparatorNodeRenderer />;\n case \"tabs\":\n return <TabsNodeRenderer node={node} renderers={renderers} />;\n case \"element\":\n return <ElementNodeRenderer node={node} renderers={renderers} />;\n default:\n return null;\n }\n});\n\ninterface RowNodeRendererProps {\n node: IRowNodeVM;\n renderers: FieldRenderers;\n}\n\nconst RowNodeRenderer = observer(function RowNodeRenderer({\n node,\n renderers\n}: RowNodeRendererProps) {\n return (\n <div className=\"grid grid-cols-12 gap-4\">\n {node.fields.map(field => {\n const span = Math.floor(12 / node.fields.length);\n return (\n <div key={field.name} className={`col-span-${span}`}>\n <FieldRenderer field={field} renderers={renderers} />\n </div>\n );\n })}\n </div>\n );\n});\n\ninterface FieldRendererProps {\n field: IFieldVM;\n renderers: FieldRenderers;\n}\n\nconst FieldRenderer = observer(function FieldRenderer({ field, renderers }: FieldRendererProps) {\n const Renderer = field.renderer ? renderers[field.renderer] : undefined;\n\n if (!Renderer) {\n if (process.env.NODE_ENV === \"development\") {\n console.warn(\n `[FormView] No renderer found for field \"${field.name}\" (renderer: \"${field.renderer || \"none\"}\").`\n );\n }\n return null;\n }\n\n return <Renderer field={field} />;\n});\n\nconst SeparatorNodeRenderer = observer(function SeparatorNodeRenderer() {\n return <hr className=\"border-neutral-dimmed my-2\" />;\n});\n\ninterface TabsNodeRendererProps {\n node: ITabsNodeVM;\n renderers: FieldRenderers;\n}\n\nconst TabsNodeRenderer = observer(function TabsNodeRenderer({\n node,\n renderers\n}: TabsNodeRendererProps) {\n const activeTab = node.tabs.find(t => t.id === node.activeTabId);\n\n return (\n <div>\n <div className=\"flex border-b border-neutral-dimmed\">\n {node.tabs.map(tab => (\n <button\n key={tab.id}\n type=\"button\"\n className={`px-4 py-2 text-sm font-medium border-b-2 ${\n tab.id === node.activeTabId\n ? \"border-primary text-primary\"\n : \"border-transparent text-neutral hover:text-neutral-strong\"\n }`}\n onClick={() => node.setActiveTab(tab.id)}\n >\n {tab.label}\n {tab.hasErrors && <span className=\"ml-1 text-destructive text-xs\">*</span>}\n </button>\n ))}\n </div>\n {activeTab && (\n <div className=\"pt-4\">\n {activeTab.description && (\n <p className=\"text-sm text-neutral mb-4\">{activeTab.description}</p>\n )}\n <div className=\"flex flex-col gap-4\">\n {activeTab.layout.map((childNode, index) => (\n <LayoutNodeRenderer\n key={index}\n node={childNode}\n renderers={renderers}\n />\n ))}\n </div>\n </div>\n )}\n </div>\n );\n});\n\ninterface ElementNodeRendererProps {\n node: IElementNodeVM;\n renderers: FieldRenderers;\n}\n\nconst ElementNodeRenderer = observer(function ElementNodeRenderer({\n node,\n renderers\n}: ElementNodeRendererProps) {\n const Renderer = renderers[`element:${node.renderer}`];\n\n if (!Renderer) {\n if (process.env.NODE_ENV === \"development\") {\n console.warn(`[FormView] No renderer found for element \"${node.renderer}\".`);\n }\n return null;\n }\n\n return <Renderer field={{ ...node.props } as any} />;\n});\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["React","createContext","useContext","useMemo","observer","useFieldRenderers","useLayoutRenderers","FormViewRenderersContext","useFormViewRenderers","ctx","Error","FormView","form","renderers","layoutRenderers","defaultFieldRenderers","defaultLayoutRenderers","value","fieldRenderers","createElement","Provider","className","layout","map","node","index","LayoutNodeRenderer","key","type","RowNodeRenderer","SeparatorNodeRenderer","TabsNodeRenderer","ElementNodeRenderer","fields","field","span","Math","floor","length","name","FieldRenderer","Renderer","renderer","undefined","process","env","NODE_ENV","console","warn","CustomRenderer","activeTab","tabs","find","t","id","activeTabId","tab","onClick","setActiveTab","label","hasErrors","description","childNode","props"],"sources":["FormView.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport type {\n IFormVM,\n LayoutNodeVM,\n IRowNodeVM,\n IFieldVM,\n ITabsNodeVM,\n IElementNodeVM\n} from \"./abstractions.js\";\nimport { useFieldRenderers } from \"~/features/formModel/useFieldRenderers.js\";\nimport { useLayoutRenderers } from \"~/features/formModel/useLayoutRenderers.js\";\n\n/**\n * A field renderer component receives a FieldVM and renders the appropriate UI.\n */\nexport type FieldRendererComponent = React.ComponentType<{ field: IFieldVM }>;\n\n/**\n * Map of renderer keys to React components for fields.\n * Lookup order: `{type}:{renderer}` → `{type}`.\n */\nexport type FieldRenderers = Record<string, FieldRendererComponent>;\n\n/**\n * Map of renderer keys to React components for layout nodes.\n */\nexport type LayoutRenderers = Record<string, React.ComponentType<any>>;\n\ninterface FormViewRenderers {\n fieldRenderers: FieldRenderers;\n layoutRenderers: LayoutRenderers;\n}\n\nconst FormViewRenderersContext = createContext<FormViewRenderers | null>(null);\n\nconst useFormViewRenderers = (): FormViewRenderers => {\n const ctx = useContext(FormViewRenderersContext);\n if (!ctx) {\n throw new Error(\"useFormViewRenderers must be used within a FormView.\");\n }\n return ctx;\n};\n\nexport { useFormViewRenderers };\n\ninterface FormViewProps {\n form: IFormVM;\n renderers?: FieldRenderers;\n layoutRenderers?: LayoutRenderers;\n}\n\n/**\n * Generic form view that walks layout nodes and renders fields.\n * This component is stateless — it reads from the FormVM and delegates to renderers.\n */\nexport const FormView = observer(function FormView({\n form,\n renderers,\n layoutRenderers\n}: FormViewProps) {\n const defaultFieldRenderers = useFieldRenderers();\n const defaultLayoutRenderers = useLayoutRenderers();\n\n const value = useMemo(\n () => ({\n fieldRenderers: renderers ?? defaultFieldRenderers,\n layoutRenderers: layoutRenderers ?? defaultLayoutRenderers\n }),\n [renderers, defaultFieldRenderers, layoutRenderers, defaultLayoutRenderers]\n );\n\n return (\n <FormViewRenderersContext.Provider value={value}>\n <div className=\"w-full flex flex-col gap-4\">\n {form.layout.map((node, index) => (\n <LayoutNodeRenderer key={index} node={node} />\n ))}\n </div>\n </FormViewRenderersContext.Provider>\n );\n});\n\nexport const LayoutNodeRenderer = observer(function LayoutNodeRenderer({\n node\n}: {\n node: LayoutNodeVM;\n}) {\n switch (node.type) {\n case \"row\":\n return <RowNodeRenderer node={node} />;\n case \"separator\":\n return <SeparatorNodeRenderer />;\n case \"tabs\":\n return <TabsNodeRenderer node={node} />;\n case \"element\":\n return <ElementNodeRenderer node={node} />;\n default:\n return null;\n }\n});\n\nconst RowNodeRenderer = observer(function RowNodeRenderer({ node }: { node: IRowNodeVM }) {\n const { fieldRenderers } = useFormViewRenderers();\n\n return (\n <div className=\"grid grid-cols-12 gap-4\">\n {node.fields.map(field => {\n const span = Math.floor(12 / node.fields.length);\n return (\n <div key={field.name} className={`col-span-${span}`}>\n <FieldRenderer field={field} renderers={fieldRenderers} />\n </div>\n );\n })}\n </div>\n );\n});\n\ninterface FieldRendererProps {\n field: IFieldVM;\n renderers: FieldRenderers;\n}\n\nconst FieldRenderer = observer(function FieldRenderer({ field, renderers }: FieldRendererProps) {\n const Renderer = field.renderer ? renderers[field.renderer] : undefined;\n\n if (!Renderer) {\n if (process.env.NODE_ENV === \"development\") {\n console.warn(\n `[FormView] No renderer found for field \"${field.name}\" (renderer: \"${field.renderer || \"none\"}\").`\n );\n }\n return null;\n }\n\n return <Renderer field={field} />;\n});\n\nconst SeparatorNodeRenderer = observer(function SeparatorNodeRenderer() {\n return <hr className=\"border-neutral-dimmed my-2\" />;\n});\n\nexport interface TabsNodeRendererProps {\n node: ITabsNodeVM;\n}\n\nconst TabsNodeRenderer = observer(function TabsNodeRenderer({ node }: TabsNodeRendererProps) {\n const { layoutRenderers } = useFormViewRenderers();\n\n if (node.renderer) {\n const CustomRenderer = layoutRenderers[node.renderer];\n if (CustomRenderer) {\n return <CustomRenderer node={node} />;\n }\n }\n\n const activeTab = node.tabs.find(t => t.id === node.activeTabId);\n\n return (\n <div>\n <div className=\"flex border-b border-neutral-dimmed\">\n {node.tabs.map(tab => (\n <button\n key={tab.id}\n type=\"button\"\n className={`px-4 py-2 text-sm font-medium border-b-2 ${\n tab.id === node.activeTabId\n ? \"border-primary text-primary\"\n : \"border-transparent text-neutral hover:text-neutral-strong\"\n }`}\n onClick={() => node.setActiveTab(tab.id)}\n >\n {tab.label}\n {tab.hasErrors && <span className=\"ml-1 text-destructive text-xs\">*</span>}\n </button>\n ))}\n </div>\n {activeTab && (\n <div className=\"pt-4\">\n {activeTab.description && (\n <p className=\"text-sm text-neutral mb-4\">{activeTab.description}</p>\n )}\n <div className=\"flex flex-col gap-4\">\n {activeTab.layout.map((childNode, index) => (\n <LayoutNodeRenderer key={index} node={childNode} />\n ))}\n </div>\n </div>\n )}\n </div>\n );\n});\n\nconst ElementNodeRenderer = observer(function ElementNodeRenderer({\n node\n}: {\n node: IElementNodeVM;\n}) {\n const { fieldRenderers } = useFormViewRenderers();\n const Renderer = fieldRenderers[`element:${node.renderer}`];\n\n if (!Renderer) {\n if (process.env.NODE_ENV === \"development\") {\n console.warn(`[FormView] No renderer found for element \"${node.renderer}\".`);\n }\n return null;\n }\n\n return <Renderer field={{ ...node.props } as any} />;\n});\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { IObjectFieldConfig, IObjectField, IListItemField, IField, IObjectFieldVM, IFieldValidation, IFormModel, FieldTypeMap, BeforeChangeCallback, AfterChangeCallback, AfterSetValueCallback, OnBlurCallback } from "./abstractions.js";
|
|
2
|
+
export declare function isObjectField(field: IField): field is ObjectField;
|
|
3
|
+
/**
|
|
4
|
+
* ObjectField — hierarchical field with children, using composition.
|
|
5
|
+
* Holds a `_base` Field for scalar behavior (callbacks, disabled/hidden, form ref).
|
|
6
|
+
* Adds its own children/items management for object and list modes.
|
|
7
|
+
*/
|
|
8
|
+
export declare class ObjectField implements IObjectField {
|
|
9
|
+
readonly config: IObjectFieldConfig;
|
|
10
|
+
private _base;
|
|
11
|
+
private _form;
|
|
12
|
+
private _children;
|
|
13
|
+
private _items;
|
|
14
|
+
constructor(config: IObjectFieldConfig);
|
|
15
|
+
get name(): string;
|
|
16
|
+
get type(): string;
|
|
17
|
+
get visible(): boolean;
|
|
18
|
+
setDisabled(value: boolean): void;
|
|
19
|
+
setVisible(value: boolean): void;
|
|
20
|
+
setForm(form: IFormModel): void;
|
|
21
|
+
setValidation(validation: IFieldValidation): void;
|
|
22
|
+
addBeforeChange(cb: BeforeChangeCallback): void;
|
|
23
|
+
addAfterChange(cb: AfterChangeCallback): void;
|
|
24
|
+
addAfterSetValue(cb: AfterSetValueCallback): void;
|
|
25
|
+
addOnBlur(cb: OnBlurCallback): void;
|
|
26
|
+
blur(): void;
|
|
27
|
+
remove(): void;
|
|
28
|
+
get isList(): boolean;
|
|
29
|
+
get children(): Map<string, IField>;
|
|
30
|
+
get items(): IListItemField[];
|
|
31
|
+
getChild(name: string): IField | undefined;
|
|
32
|
+
getListItemChild(index: number, name: string): IField | undefined;
|
|
33
|
+
getData(): any;
|
|
34
|
+
getValue<T = unknown>(): T;
|
|
35
|
+
setValue(value: unknown): void;
|
|
36
|
+
setValueSilent(value: unknown): void;
|
|
37
|
+
addItem(data?: Record<string, unknown>): void;
|
|
38
|
+
removeItem(index: number): void;
|
|
39
|
+
moveItem(fromIndex: number, toIndex: number): void;
|
|
40
|
+
private _addItemInternal;
|
|
41
|
+
resetValidation(): void;
|
|
42
|
+
as<T extends keyof FieldTypeMap>(type: T): FieldTypeMap[T];
|
|
43
|
+
get vm(): IObjectFieldVM;
|
|
44
|
+
get hasErrors(): boolean;
|
|
45
|
+
validate(): Promise<boolean>;
|
|
46
|
+
}
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import { makeAutoObservable, runInAction, toJS } from "mobx";
|
|
2
|
+
import { Field } from "./Field.js";
|
|
3
|
+
function createChildFields(childBuilders, form) {
|
|
4
|
+
const children = new Map();
|
|
5
|
+
for (const [name, builder] of Object.entries(childBuilders)) {
|
|
6
|
+
const config = builder.build(name);
|
|
7
|
+
const field = createFieldFromConfig(config, form);
|
|
8
|
+
children.set(name, field);
|
|
9
|
+
}
|
|
10
|
+
return children;
|
|
11
|
+
}
|
|
12
|
+
function createFieldFromConfig(config, form) {
|
|
13
|
+
if (config.childBuilders) {
|
|
14
|
+
const objField = new ObjectField(config);
|
|
15
|
+
if (form) {
|
|
16
|
+
objField.setForm(form);
|
|
17
|
+
}
|
|
18
|
+
return objField;
|
|
19
|
+
}
|
|
20
|
+
const field = new Field(config);
|
|
21
|
+
if (form) {
|
|
22
|
+
field.setForm(form);
|
|
23
|
+
}
|
|
24
|
+
return field;
|
|
25
|
+
}
|
|
26
|
+
function hydrateChildren(children, data) {
|
|
27
|
+
if (!data) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
for (const [name, field] of children) {
|
|
31
|
+
if (name in data) {
|
|
32
|
+
field.setValueSilent(data[name]);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function getChildrenData(children) {
|
|
37
|
+
const data = {};
|
|
38
|
+
for (const [name, field] of children) {
|
|
39
|
+
if (isObjectField(field)) {
|
|
40
|
+
data[name] = toJS(field.getData());
|
|
41
|
+
} else {
|
|
42
|
+
data[name] = toJS(field.getValue());
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return data;
|
|
46
|
+
}
|
|
47
|
+
async function validateChildren(children) {
|
|
48
|
+
let allValid = true;
|
|
49
|
+
for (const [, field] of children) {
|
|
50
|
+
const valid = await field.validate();
|
|
51
|
+
if (!valid) {
|
|
52
|
+
allValid = false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return allValid;
|
|
56
|
+
}
|
|
57
|
+
export function isObjectField(field) {
|
|
58
|
+
return field.type === "object";
|
|
59
|
+
}
|
|
60
|
+
let itemKeyCounter = 0;
|
|
61
|
+
/**
|
|
62
|
+
* ObjectField — hierarchical field with children, using composition.
|
|
63
|
+
* Holds a `_base` Field for scalar behavior (callbacks, disabled/hidden, form ref).
|
|
64
|
+
* Adds its own children/items management for object and list modes.
|
|
65
|
+
*/
|
|
66
|
+
export class ObjectField {
|
|
67
|
+
_form = null;
|
|
68
|
+
_items = [];
|
|
69
|
+
constructor(config) {
|
|
70
|
+
this.config = config;
|
|
71
|
+
this._base = new Field({
|
|
72
|
+
...config,
|
|
73
|
+
type: "object",
|
|
74
|
+
renderer: config.renderer ?? "object"
|
|
75
|
+
});
|
|
76
|
+
this._children = createChildFields(config.childBuilders, null);
|
|
77
|
+
makeAutoObservable(this, {
|
|
78
|
+
config: false
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// --- Forwarded from _base ---
|
|
83
|
+
|
|
84
|
+
get name() {
|
|
85
|
+
return this._base.name;
|
|
86
|
+
}
|
|
87
|
+
get type() {
|
|
88
|
+
return "object";
|
|
89
|
+
}
|
|
90
|
+
get visible() {
|
|
91
|
+
return this._base.visible;
|
|
92
|
+
}
|
|
93
|
+
setDisabled(value) {
|
|
94
|
+
this._base.setDisabled(value);
|
|
95
|
+
}
|
|
96
|
+
setVisible(value) {
|
|
97
|
+
this._base.setVisible(value);
|
|
98
|
+
}
|
|
99
|
+
setForm(form) {
|
|
100
|
+
this._form = form;
|
|
101
|
+
this._base.setForm(form);
|
|
102
|
+
for (const [, field] of this._children) {
|
|
103
|
+
field.setForm(form);
|
|
104
|
+
}
|
|
105
|
+
for (const item of this._items) {
|
|
106
|
+
for (const [, field] of item.children) {
|
|
107
|
+
field.setForm(form);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
setValidation(validation) {
|
|
112
|
+
this._base.setValidation(validation);
|
|
113
|
+
}
|
|
114
|
+
addBeforeChange(cb) {
|
|
115
|
+
this._base.addBeforeChange(cb);
|
|
116
|
+
}
|
|
117
|
+
addAfterChange(cb) {
|
|
118
|
+
this._base.addAfterChange(cb);
|
|
119
|
+
}
|
|
120
|
+
addAfterSetValue(cb) {
|
|
121
|
+
this._base.addAfterSetValue(cb);
|
|
122
|
+
}
|
|
123
|
+
addOnBlur(cb) {
|
|
124
|
+
this._base.addOnBlur(cb);
|
|
125
|
+
}
|
|
126
|
+
blur() {
|
|
127
|
+
this._base.blur();
|
|
128
|
+
}
|
|
129
|
+
remove() {
|
|
130
|
+
this._base.remove();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// --- Object-specific ---
|
|
134
|
+
|
|
135
|
+
get isList() {
|
|
136
|
+
return this.config.isList;
|
|
137
|
+
}
|
|
138
|
+
get children() {
|
|
139
|
+
return this._children;
|
|
140
|
+
}
|
|
141
|
+
get items() {
|
|
142
|
+
return this._items.map(item => ({
|
|
143
|
+
key: item.key,
|
|
144
|
+
children: item.children,
|
|
145
|
+
getData: () => getChildrenData(item.children)
|
|
146
|
+
}));
|
|
147
|
+
}
|
|
148
|
+
getChild(name) {
|
|
149
|
+
return this._children.get(name);
|
|
150
|
+
}
|
|
151
|
+
getListItemChild(index, name) {
|
|
152
|
+
const item = this._items[index];
|
|
153
|
+
return item?.children.get(name);
|
|
154
|
+
}
|
|
155
|
+
getData() {
|
|
156
|
+
if (this.config.isList) {
|
|
157
|
+
return this._items.map(item => getChildrenData(item.children));
|
|
158
|
+
}
|
|
159
|
+
return getChildrenData(this._children);
|
|
160
|
+
}
|
|
161
|
+
getValue() {
|
|
162
|
+
return this.getData();
|
|
163
|
+
}
|
|
164
|
+
setValue(value) {
|
|
165
|
+
this.setValueSilent(value);
|
|
166
|
+
}
|
|
167
|
+
setValueSilent(value) {
|
|
168
|
+
if (this.config.isList) {
|
|
169
|
+
this._items = [];
|
|
170
|
+
if (Array.isArray(value)) {
|
|
171
|
+
for (const itemData of value) {
|
|
172
|
+
this._addItemInternal(itemData);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
hydrateChildren(this._children, value);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
addItem(data) {
|
|
180
|
+
this._addItemInternal(data);
|
|
181
|
+
}
|
|
182
|
+
removeItem(index) {
|
|
183
|
+
this._items.splice(index, 1);
|
|
184
|
+
}
|
|
185
|
+
moveItem(fromIndex, toIndex) {
|
|
186
|
+
if (fromIndex < 0 || fromIndex >= this._items.length || toIndex < 0 || toIndex >= this._items.length || fromIndex === toIndex) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const [item] = this._items.splice(fromIndex, 1);
|
|
190
|
+
this._items.splice(toIndex, 0, item);
|
|
191
|
+
}
|
|
192
|
+
_addItemInternal(data) {
|
|
193
|
+
const children = createChildFields(this.config.childBuilders, this._form);
|
|
194
|
+
if (data) {
|
|
195
|
+
hydrateChildren(children, data);
|
|
196
|
+
}
|
|
197
|
+
const key = `item_${++itemKeyCounter}`;
|
|
198
|
+
this._items.push({
|
|
199
|
+
key,
|
|
200
|
+
children
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
resetValidation() {
|
|
204
|
+
this._base.resetValidation();
|
|
205
|
+
for (const [, field] of this._children) {
|
|
206
|
+
field.resetValidation();
|
|
207
|
+
}
|
|
208
|
+
for (const item of this._items) {
|
|
209
|
+
for (const [, field] of item.children) {
|
|
210
|
+
field.resetValidation();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
as(type) {
|
|
215
|
+
if (type !== "object") {
|
|
216
|
+
throw new Error(`Field "${this.config.name}" is type "object", not "${type}".`);
|
|
217
|
+
}
|
|
218
|
+
return this;
|
|
219
|
+
}
|
|
220
|
+
get vm() {
|
|
221
|
+
const baseVm = this._base.vm;
|
|
222
|
+
return {
|
|
223
|
+
name: baseVm.name,
|
|
224
|
+
type: "object",
|
|
225
|
+
label: baseVm.label,
|
|
226
|
+
help: baseVm.help,
|
|
227
|
+
description: baseVm.description,
|
|
228
|
+
note: baseVm.note,
|
|
229
|
+
placeholder: baseVm.placeholder,
|
|
230
|
+
value: this.getValue(),
|
|
231
|
+
validation: baseVm.validation,
|
|
232
|
+
required: baseVm.required,
|
|
233
|
+
disabled: baseVm.disabled,
|
|
234
|
+
renderer: baseVm.renderer,
|
|
235
|
+
rendererSettings: baseVm.rendererSettings,
|
|
236
|
+
onChange: value => this.setValue(value),
|
|
237
|
+
onBlur: () => this.blur(),
|
|
238
|
+
isList: this.config.isList,
|
|
239
|
+
fields: this.config.isList ? [] : Array.from(this._children.values()).filter(f => f.visible).map(f => f.vm),
|
|
240
|
+
items: this.config.isList ? this._items.map((item, index) => ({
|
|
241
|
+
key: item.key,
|
|
242
|
+
fields: Array.from(item.children.values()).filter(f => f.visible).map(f => f.vm),
|
|
243
|
+
remove: () => this.removeItem(index),
|
|
244
|
+
moveUp: () => this.moveItem(index, index - 1),
|
|
245
|
+
moveDown: () => this.moveItem(index, index + 1)
|
|
246
|
+
})) : [],
|
|
247
|
+
addItem: () => this.addItem(),
|
|
248
|
+
removeItem: index => this.removeItem(index),
|
|
249
|
+
moveItem: (from, to) => this.moveItem(from, to)
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
get hasErrors() {
|
|
253
|
+
const checkChildren = children => {
|
|
254
|
+
for (const [, field] of children) {
|
|
255
|
+
if (field.vm.validation.isValid === false) {
|
|
256
|
+
return true;
|
|
257
|
+
}
|
|
258
|
+
if (isObjectField(field) && field.hasErrors) {
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return false;
|
|
263
|
+
};
|
|
264
|
+
if (this.config.isList) {
|
|
265
|
+
for (const item of this._items) {
|
|
266
|
+
if (checkChildren(item.children)) {
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
} else {
|
|
271
|
+
if (checkChildren(this._children)) {
|
|
272
|
+
return true;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
async validate() {
|
|
278
|
+
if (this.config.required) {
|
|
279
|
+
if (this.config.isList && this._items.length === 0) {
|
|
280
|
+
this.setValidation({
|
|
281
|
+
isValid: false,
|
|
282
|
+
message: this.config.requiredMessage || "This field is required."
|
|
283
|
+
});
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
if (!this.config.isList) {
|
|
287
|
+
const data = this.getData();
|
|
288
|
+
const hasAnyValue = Object.values(data).some(v => v !== null && v !== undefined && v !== "");
|
|
289
|
+
if (!hasAnyValue) {
|
|
290
|
+
this.setValidation({
|
|
291
|
+
isValid: false,
|
|
292
|
+
message: this.config.requiredMessage || "This field is required."
|
|
293
|
+
});
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (this.config.isList && this.config.listSchema) {
|
|
299
|
+
const listData = this.getData();
|
|
300
|
+
const result = await this.config.listSchema.safeParseAsync(listData);
|
|
301
|
+
if (!result.success) {
|
|
302
|
+
const firstIssue = result.error.issues[0];
|
|
303
|
+
runInAction(() => {
|
|
304
|
+
this.setValidation({
|
|
305
|
+
isValid: false,
|
|
306
|
+
message: firstIssue?.message || "Invalid value."
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
return false;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (this.config.schema) {
|
|
313
|
+
const data = this.getData();
|
|
314
|
+
const result = await this.config.schema.safeParseAsync(data);
|
|
315
|
+
if (!result.success) {
|
|
316
|
+
const firstIssue = result.error.issues[0];
|
|
317
|
+
runInAction(() => {
|
|
318
|
+
this.setValidation({
|
|
319
|
+
isValid: false,
|
|
320
|
+
message: firstIssue?.message || "Invalid value."
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
let allValid = true;
|
|
327
|
+
if (this.config.isList) {
|
|
328
|
+
for (const item of this._items) {
|
|
329
|
+
const valid = await validateChildren(item.children);
|
|
330
|
+
if (!valid) {
|
|
331
|
+
allValid = false;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
} else {
|
|
335
|
+
allValid = await validateChildren(this._children);
|
|
336
|
+
}
|
|
337
|
+
runInAction(() => {
|
|
338
|
+
this.setValidation({
|
|
339
|
+
isValid: allValid
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
return allValid;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
//# sourceMappingURL=ObjectField.js.map
|