@react-typed-forms/schemas 1.0.0-dev.17 → 1.0.0-dev.19
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/.rush/temp/operation/build/state.json +1 -1
- package/.rush/temp/shrinkwrap-deps.json +5 -1
- package/lib/controlRender.d.ts +112 -100
- package/lib/hooks.d.ts +11 -9
- package/lib/index.d.ts +7 -5
- package/lib/index.js +1132 -139
- package/lib/index.js.map +1 -1
- package/lib/renderers.d.ts +153 -0
- package/lib/schemaBuilder.d.ts +87 -87
- package/lib/tailwind.d.ts +2 -0
- package/lib/types.d.ts +265 -234
- package/lib/util.d.ts +22 -3
- package/package.json +8 -4
- package/src/controlRender.tsx +172 -275
- package/src/hooks.tsx +441 -0
- package/src/index.ts +2 -0
- package/src/renderers.tsx +855 -0
- package/src/tailwind.tsx +21 -0
- package/src/types.ts +56 -17
- package/src/util.ts +204 -1
- package/src/hooks.ts +0 -173
package/src/tailwind.tsx
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { DefaultRendererOptions } from "./renderers";
|
|
3
|
+
|
|
4
|
+
export const defaultTailwindTheme: DefaultRendererOptions = {
|
|
5
|
+
label: {
|
|
6
|
+
className: "flex flex-col",
|
|
7
|
+
groupLabelClass: "font-bold",
|
|
8
|
+
requiredElement: <span className="text-red-500"> *</span>,
|
|
9
|
+
},
|
|
10
|
+
array: {
|
|
11
|
+
removableClass: "grid grid-cols-[1fr_auto] items-center gap-x-2",
|
|
12
|
+
childClass: "grow",
|
|
13
|
+
},
|
|
14
|
+
group: {
|
|
15
|
+
standardClassName: "space-y-4",
|
|
16
|
+
gridClassName: "gap-x-2 gap-y-4",
|
|
17
|
+
},
|
|
18
|
+
action: {
|
|
19
|
+
className: "bg-primary rounded-lg p-3 text-white",
|
|
20
|
+
},
|
|
21
|
+
};
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { DataControlProperties } from "./controlRender";
|
|
2
|
-
|
|
3
1
|
export interface SchemaField {
|
|
4
2
|
type: string;
|
|
5
3
|
field: string;
|
|
@@ -13,10 +11,7 @@ export interface SchemaField {
|
|
|
13
11
|
isTypeField?: boolean | null;
|
|
14
12
|
searchable?: boolean | null;
|
|
15
13
|
options?: FieldOption[] | null;
|
|
16
|
-
|
|
17
|
-
* @deprecated Use options directly
|
|
18
|
-
*/
|
|
19
|
-
restrictions?: SchemaRestrictions | undefined | null;
|
|
14
|
+
validators?: SchemaValidator[] | null;
|
|
20
15
|
}
|
|
21
16
|
|
|
22
17
|
export enum FieldType {
|
|
@@ -39,10 +34,6 @@ export interface EntityRefField extends SchemaField {
|
|
|
39
34
|
parentField: string;
|
|
40
35
|
}
|
|
41
36
|
|
|
42
|
-
export interface SchemaRestrictions {
|
|
43
|
-
options?: FieldOption[] | null;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
37
|
export interface FieldOption {
|
|
47
38
|
name: string;
|
|
48
39
|
value: any;
|
|
@@ -114,9 +105,17 @@ export interface ControlAdornment {
|
|
|
114
105
|
type: string;
|
|
115
106
|
}
|
|
116
107
|
|
|
108
|
+
export enum AdornmentPlacement {
|
|
109
|
+
ControlStart = "ControlStart",
|
|
110
|
+
ControlEnd = "ControlEnd",
|
|
111
|
+
LabelStart = "LabelStart",
|
|
112
|
+
LabelEnd = "LabelEnd",
|
|
113
|
+
}
|
|
114
|
+
|
|
117
115
|
export enum ControlAdornmentType {
|
|
118
116
|
Tooltip = "Tooltip",
|
|
119
117
|
Accordion = "Accordion",
|
|
118
|
+
HelpText = "HelpText",
|
|
120
119
|
}
|
|
121
120
|
|
|
122
121
|
export interface TooltipAdornment extends ControlAdornment {
|
|
@@ -130,6 +129,12 @@ export interface AccordionAdornment extends ControlAdornment {
|
|
|
130
129
|
defaultExpanded: boolean;
|
|
131
130
|
}
|
|
132
131
|
|
|
132
|
+
export interface HelpTextAdornment extends ControlAdornment {
|
|
133
|
+
type: ControlAdornmentType.HelpText;
|
|
134
|
+
helpText: string;
|
|
135
|
+
placement: AdornmentPlacement;
|
|
136
|
+
}
|
|
137
|
+
|
|
133
138
|
export interface DataControlDefinition extends ControlDefinition {
|
|
134
139
|
type: ControlDefinitionType.Data;
|
|
135
140
|
field: string;
|
|
@@ -137,6 +142,7 @@ export interface DataControlDefinition extends ControlDefinition {
|
|
|
137
142
|
renderOptions?: RenderOptions | null;
|
|
138
143
|
defaultValue?: any;
|
|
139
144
|
readonly?: boolean | null;
|
|
145
|
+
validators?: SchemaValidator[] | null;
|
|
140
146
|
}
|
|
141
147
|
|
|
142
148
|
export interface RenderOptions {
|
|
@@ -153,6 +159,8 @@ export enum DataRenderType {
|
|
|
153
159
|
Synchronised = "Synchronised",
|
|
154
160
|
IconSelector = "IconSelector",
|
|
155
161
|
DateTime = "DateTime",
|
|
162
|
+
Checkbox = "Checkbox",
|
|
163
|
+
Dropdown = "Dropdown",
|
|
156
164
|
}
|
|
157
165
|
|
|
158
166
|
export interface RadioButtonRenderOptions extends RenderOptions {
|
|
@@ -270,26 +278,51 @@ export interface ActionControlDefinition extends ControlDefinition {
|
|
|
270
278
|
actionId: string;
|
|
271
279
|
}
|
|
272
280
|
|
|
281
|
+
export enum ValidatorType {
|
|
282
|
+
Jsonata = "Jsonata",
|
|
283
|
+
Date = "Date",
|
|
284
|
+
}
|
|
285
|
+
export interface SchemaValidator {
|
|
286
|
+
type: string;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export interface JsonataValidator extends SchemaValidator {
|
|
290
|
+
type: ValidatorType.Jsonata;
|
|
291
|
+
expression: string;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export enum DateComparison {
|
|
295
|
+
NotBefore = "NotBefore",
|
|
296
|
+
NotAfter = "NotAfter",
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export interface DateValidator extends SchemaValidator {
|
|
300
|
+
type: ValidatorType.Date;
|
|
301
|
+
comparison: DateComparison;
|
|
302
|
+
fixedDate?: string | null;
|
|
303
|
+
daysFromCurrent?: number | null;
|
|
304
|
+
}
|
|
305
|
+
|
|
273
306
|
export function isDataControlDefinition(
|
|
274
|
-
x: ControlDefinition
|
|
307
|
+
x: ControlDefinition,
|
|
275
308
|
): x is DataControlDefinition {
|
|
276
309
|
return x.type === ControlDefinitionType.Data;
|
|
277
310
|
}
|
|
278
311
|
|
|
279
312
|
export function isGroupControlsDefinition(
|
|
280
|
-
x: ControlDefinition
|
|
313
|
+
x: ControlDefinition,
|
|
281
314
|
): x is GroupedControlsDefinition {
|
|
282
315
|
return x.type === ControlDefinitionType.Group;
|
|
283
316
|
}
|
|
284
317
|
|
|
285
318
|
export function isDisplayControlsDefinition(
|
|
286
|
-
x: ControlDefinition
|
|
319
|
+
x: ControlDefinition,
|
|
287
320
|
): x is DisplayControlDefinition {
|
|
288
321
|
return x.type === ControlDefinitionType.Display;
|
|
289
322
|
}
|
|
290
323
|
|
|
291
324
|
export function isActionControlsDefinition(
|
|
292
|
-
x: ControlDefinition
|
|
325
|
+
x: ControlDefinition,
|
|
293
326
|
): x is ActionControlDefinition {
|
|
294
327
|
return x.type === ControlDefinitionType.Action;
|
|
295
328
|
}
|
|
@@ -304,7 +337,7 @@ export interface ControlVisitor<A> {
|
|
|
304
337
|
export function visitControlDefinition<A>(
|
|
305
338
|
x: ControlDefinition,
|
|
306
339
|
visitor: ControlVisitor<A>,
|
|
307
|
-
defaultValue: (c: ControlDefinition) => A
|
|
340
|
+
defaultValue: (c: ControlDefinition) => A,
|
|
308
341
|
): A {
|
|
309
342
|
switch (x.type) {
|
|
310
343
|
case ControlDefinitionType.Action:
|
|
@@ -322,14 +355,14 @@ export function visitControlDefinition<A>(
|
|
|
322
355
|
|
|
323
356
|
export function dataControl(
|
|
324
357
|
field: string,
|
|
325
|
-
options?: Partial<DataControlDefinition
|
|
358
|
+
options?: Partial<DataControlDefinition>,
|
|
326
359
|
): DataControlDefinition {
|
|
327
360
|
return { type: ControlDefinitionType.Data, field, ...options };
|
|
328
361
|
}
|
|
329
362
|
|
|
330
363
|
export function fieldValueExpr(
|
|
331
364
|
field: string,
|
|
332
|
-
value: any
|
|
365
|
+
value: any,
|
|
333
366
|
): FieldValueExpression {
|
|
334
367
|
return { type: ExpressionType.FieldValue, field, value };
|
|
335
368
|
}
|
|
@@ -337,3 +370,9 @@ export function fieldValueExpr(
|
|
|
337
370
|
export function visibility(expr: EntityExpression): DynamicProperty {
|
|
338
371
|
return { type: DynamicPropertyType.Visible, expr };
|
|
339
372
|
}
|
|
373
|
+
|
|
374
|
+
export function isGridRenderer(
|
|
375
|
+
options: GroupRenderOptions,
|
|
376
|
+
): options is GridRenderer {
|
|
377
|
+
return options.type === GroupRenderType.Grid;
|
|
378
|
+
}
|
package/src/util.ts
CHANGED
|
@@ -1,4 +1,119 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
CompoundField,
|
|
3
|
+
ControlDefinition,
|
|
4
|
+
ControlDefinitionType,
|
|
5
|
+
DataControlDefinition,
|
|
6
|
+
DataRenderType,
|
|
7
|
+
FieldOption,
|
|
8
|
+
FieldType,
|
|
9
|
+
GridRenderer,
|
|
10
|
+
GroupedControlsDefinition,
|
|
11
|
+
GroupRenderType,
|
|
12
|
+
SchemaField,
|
|
13
|
+
} from "./types";
|
|
14
|
+
|
|
15
|
+
export function applyDefaultValues(
|
|
16
|
+
v: { [k: string]: any } | undefined,
|
|
17
|
+
fields: SchemaField[],
|
|
18
|
+
): any {
|
|
19
|
+
if (!v) return defaultValueForFields(fields);
|
|
20
|
+
const applyValue = fields.filter(
|
|
21
|
+
(x) => isCompoundField(x) || !(x.field in v),
|
|
22
|
+
);
|
|
23
|
+
if (!applyValue.length) return v;
|
|
24
|
+
const out = { ...v };
|
|
25
|
+
applyValue.forEach((x) => {
|
|
26
|
+
out[x.field] =
|
|
27
|
+
x.field in v
|
|
28
|
+
? applyDefaultForField(v[x.field], x, fields)
|
|
29
|
+
: defaultValueForField(x);
|
|
30
|
+
});
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function applyDefaultForField(
|
|
35
|
+
v: any,
|
|
36
|
+
field: SchemaField,
|
|
37
|
+
parent: SchemaField[],
|
|
38
|
+
notElement?: boolean,
|
|
39
|
+
): any {
|
|
40
|
+
if (field.collection && !notElement) {
|
|
41
|
+
return ((v as any[]) ?? []).map((x) =>
|
|
42
|
+
applyDefaultForField(x, field, parent, true),
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
if (isCompoundField(field)) {
|
|
46
|
+
if (!v && !field.required) return v;
|
|
47
|
+
return applyDefaultValues(v, field.treeChildren ? parent : field.children);
|
|
48
|
+
}
|
|
49
|
+
return defaultValueForField(field);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function defaultValueForFields(fields: SchemaField[]): any {
|
|
53
|
+
return Object.fromEntries(
|
|
54
|
+
fields.map((x) => [x.field, defaultValueForField(x)]),
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function defaultValueForField(sf: SchemaField): any {
|
|
59
|
+
if (isCompoundField(sf)) {
|
|
60
|
+
return sf.required
|
|
61
|
+
? sf.collection
|
|
62
|
+
? []
|
|
63
|
+
: defaultValueForFields(sf.children)
|
|
64
|
+
: undefined;
|
|
65
|
+
}
|
|
66
|
+
if (sf.collection) return [];
|
|
67
|
+
return sf.defaultValue;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function elementValueForField(sf: SchemaField): any {
|
|
71
|
+
if (isCompoundField(sf)) {
|
|
72
|
+
return defaultValueForFields(sf.children);
|
|
73
|
+
}
|
|
74
|
+
return sf.defaultValue;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function findScalarField(
|
|
78
|
+
fields: SchemaField[],
|
|
79
|
+
field: string,
|
|
80
|
+
): SchemaField | undefined {
|
|
81
|
+
return findField(fields, field);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function findCompoundField(
|
|
85
|
+
fields: SchemaField[],
|
|
86
|
+
field: string,
|
|
87
|
+
): CompoundField | undefined {
|
|
88
|
+
return findField(fields, field) as CompoundField | undefined;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function findField(
|
|
92
|
+
fields: SchemaField[],
|
|
93
|
+
field: string,
|
|
94
|
+
): SchemaField | undefined {
|
|
95
|
+
return fields.find((x) => x.field === field);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function isScalarField(sf: SchemaField): sf is SchemaField {
|
|
99
|
+
return !isCompoundField(sf);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function isCompoundField(sf: SchemaField): sf is CompoundField {
|
|
103
|
+
return sf.type === FieldType.Compound;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function isDataControl(
|
|
107
|
+
c: ControlDefinition,
|
|
108
|
+
): c is DataControlDefinition {
|
|
109
|
+
return c.type === ControlDefinitionType.Data;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function isGroupControl(
|
|
113
|
+
c: ControlDefinition,
|
|
114
|
+
): c is GroupedControlsDefinition {
|
|
115
|
+
return c.type === ControlDefinitionType.Group;
|
|
116
|
+
}
|
|
2
117
|
|
|
3
118
|
export function fieldHasTag(field: SchemaField, tag: string) {
|
|
4
119
|
return Boolean(field.tags?.includes(tag));
|
|
@@ -7,3 +122,91 @@ export function fieldHasTag(field: SchemaField, tag: string) {
|
|
|
7
122
|
export function fieldDisplayName(field: SchemaField) {
|
|
8
123
|
return field.displayName ?? field.field;
|
|
9
124
|
}
|
|
125
|
+
|
|
126
|
+
export function hasOptions(o: { options: FieldOption[] | undefined | null }) {
|
|
127
|
+
return (o.options?.length ?? 0) > 0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function defaultControlForField(
|
|
131
|
+
sf: SchemaField,
|
|
132
|
+
): DataControlDefinition | GroupedControlsDefinition {
|
|
133
|
+
if (isCompoundField(sf)) {
|
|
134
|
+
return {
|
|
135
|
+
type: ControlDefinitionType.Group,
|
|
136
|
+
title: sf.displayName,
|
|
137
|
+
compoundField: sf.field,
|
|
138
|
+
groupOptions: {
|
|
139
|
+
type: GroupRenderType.Grid,
|
|
140
|
+
hideTitle: false,
|
|
141
|
+
} as GridRenderer,
|
|
142
|
+
children: sf.children.map(defaultControlForField),
|
|
143
|
+
} satisfies GroupedControlsDefinition;
|
|
144
|
+
} else if (isScalarField(sf)) {
|
|
145
|
+
const htmlEditor = sf.tags?.includes("_HtmlEditor");
|
|
146
|
+
return {
|
|
147
|
+
type: ControlDefinitionType.Data,
|
|
148
|
+
title: sf.displayName,
|
|
149
|
+
field: sf.field,
|
|
150
|
+
required: sf.required,
|
|
151
|
+
renderOptions: {
|
|
152
|
+
type: htmlEditor ? DataRenderType.HtmlEditor : DataRenderType.Standard,
|
|
153
|
+
},
|
|
154
|
+
} satisfies DataControlDefinition;
|
|
155
|
+
}
|
|
156
|
+
throw "Unknown schema field";
|
|
157
|
+
}
|
|
158
|
+
function findReferencedControl(
|
|
159
|
+
field: string,
|
|
160
|
+
control: ControlDefinition,
|
|
161
|
+
): ControlDefinition | undefined {
|
|
162
|
+
if (isDataControl(control) && field === control.field) return control;
|
|
163
|
+
if (isGroupControl(control)) {
|
|
164
|
+
if (control.compoundField)
|
|
165
|
+
return field === control.compoundField ? control : undefined;
|
|
166
|
+
return findReferencedControlInArray(field, control.children);
|
|
167
|
+
}
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function findReferencedControlInArray(
|
|
172
|
+
field: string,
|
|
173
|
+
controls: ControlDefinition[],
|
|
174
|
+
): ControlDefinition | undefined {
|
|
175
|
+
for (const c of controls) {
|
|
176
|
+
const ref = findReferencedControl(field, c);
|
|
177
|
+
if (ref) return ref;
|
|
178
|
+
}
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function addMissingControls(
|
|
183
|
+
fields: SchemaField[],
|
|
184
|
+
controls: ControlDefinition[],
|
|
185
|
+
): ControlDefinition[] {
|
|
186
|
+
const changes: {
|
|
187
|
+
field: SchemaField;
|
|
188
|
+
existing: ControlDefinition | undefined;
|
|
189
|
+
}[] = fields.flatMap((x) => {
|
|
190
|
+
if (fieldHasTag(x, "_NoControl")) return [];
|
|
191
|
+
const existing = findReferencedControlInArray(x.field, controls);
|
|
192
|
+
if (!existing || isCompoundField(x)) return { field: x, existing };
|
|
193
|
+
return [];
|
|
194
|
+
});
|
|
195
|
+
const changedCompounds = controls.map((x) => {
|
|
196
|
+
const ex = changes.find((c) => c.existing === x);
|
|
197
|
+
if (!ex) return x;
|
|
198
|
+
const cf = x as GroupedControlsDefinition;
|
|
199
|
+
return {
|
|
200
|
+
...cf,
|
|
201
|
+
children: addMissingControls(
|
|
202
|
+
(ex.field as CompoundField).children,
|
|
203
|
+
cf.children,
|
|
204
|
+
),
|
|
205
|
+
};
|
|
206
|
+
});
|
|
207
|
+
return changedCompounds.concat(
|
|
208
|
+
changes
|
|
209
|
+
.filter((x) => !x.existing)
|
|
210
|
+
.map((x) => defaultControlForField(x.field)),
|
|
211
|
+
);
|
|
212
|
+
}
|
package/src/hooks.ts
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ActionControlDefinition,
|
|
3
|
-
ControlDefinition,
|
|
4
|
-
DataControlDefinition,
|
|
5
|
-
DynamicPropertyType,
|
|
6
|
-
EntityExpression,
|
|
7
|
-
ExpressionType,
|
|
8
|
-
FieldOption,
|
|
9
|
-
FieldValueExpression,
|
|
10
|
-
SchemaField,
|
|
11
|
-
} from "./types";
|
|
12
|
-
import {
|
|
13
|
-
ActionControlProperties,
|
|
14
|
-
controlForField,
|
|
15
|
-
DataControlProperties,
|
|
16
|
-
ExpressionHook,
|
|
17
|
-
fieldForControl,
|
|
18
|
-
findField,
|
|
19
|
-
FormEditHooks,
|
|
20
|
-
FormEditState,
|
|
21
|
-
isGroupControl,
|
|
22
|
-
isScalarField,
|
|
23
|
-
} from "./controlRender";
|
|
24
|
-
import { useEffect, useMemo } from "react";
|
|
25
|
-
import { Control, newControl } from "@react-typed-forms/core";
|
|
26
|
-
|
|
27
|
-
export function useDefaultValue(
|
|
28
|
-
definition: DataControlDefinition,
|
|
29
|
-
field: SchemaField,
|
|
30
|
-
formState: FormEditState,
|
|
31
|
-
useExpression: ExpressionHook
|
|
32
|
-
) {
|
|
33
|
-
const valueExpression = definition.dynamic?.find(
|
|
34
|
-
(x) => x.type === DynamicPropertyType.DefaultValue
|
|
35
|
-
);
|
|
36
|
-
if (valueExpression) {
|
|
37
|
-
return useExpression(valueExpression.expr, formState);
|
|
38
|
-
}
|
|
39
|
-
return field.defaultValue;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function useIsControlVisible(
|
|
43
|
-
definition: ControlDefinition,
|
|
44
|
-
formState: FormEditState,
|
|
45
|
-
useExpression: ExpressionHook
|
|
46
|
-
) {
|
|
47
|
-
const visibleExpression = definition.dynamic?.find(
|
|
48
|
-
(x) => x.type === DynamicPropertyType.Visible
|
|
49
|
-
);
|
|
50
|
-
if (visibleExpression && visibleExpression.expr) {
|
|
51
|
-
return Boolean(useExpression(visibleExpression.expr, formState));
|
|
52
|
-
}
|
|
53
|
-
const schemaFields = formState.fields;
|
|
54
|
-
|
|
55
|
-
const { typeControl, compoundField } = useMemo(() => {
|
|
56
|
-
const typeField = schemaFields.find(
|
|
57
|
-
(x) => isScalarField(x) && x.isTypeField
|
|
58
|
-
) as SchemaField | undefined;
|
|
59
|
-
|
|
60
|
-
const typeControl = ((typeField &&
|
|
61
|
-
formState.data.fields?.[typeField.field]) ??
|
|
62
|
-
newControl(undefined)) as Control<string | undefined>;
|
|
63
|
-
const compoundField =
|
|
64
|
-
isGroupControl(definition) && definition.compoundField
|
|
65
|
-
? formState.data.fields[definition.compoundField]
|
|
66
|
-
: undefined;
|
|
67
|
-
return { typeControl, compoundField };
|
|
68
|
-
}, [schemaFields, formState.data]);
|
|
69
|
-
|
|
70
|
-
const fieldName = fieldForControl(definition);
|
|
71
|
-
const onlyForTypes = (
|
|
72
|
-
fieldName ? findField(schemaFields, fieldName) : undefined
|
|
73
|
-
)?.onlyForTypes;
|
|
74
|
-
|
|
75
|
-
return (
|
|
76
|
-
(!compoundField || compoundField.value != null) &&
|
|
77
|
-
(!onlyForTypes ||
|
|
78
|
-
onlyForTypes.length === 0 ||
|
|
79
|
-
Boolean(typeControl.value && onlyForTypes.includes(typeControl.value)))
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
export function getDefaultScalarControlProperties(
|
|
83
|
-
definition: DataControlDefinition,
|
|
84
|
-
field: SchemaField,
|
|
85
|
-
visible: boolean,
|
|
86
|
-
defaultValue: any,
|
|
87
|
-
control: Control<any>,
|
|
88
|
-
readonly?: boolean
|
|
89
|
-
): DataControlProperties {
|
|
90
|
-
return {
|
|
91
|
-
defaultValue,
|
|
92
|
-
options: getOptionsForScalarField(field),
|
|
93
|
-
required: definition.required ?? false,
|
|
94
|
-
visible,
|
|
95
|
-
readonly: readonly ?? definition.readonly ?? false,
|
|
96
|
-
control,
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function getOptionsForScalarField(
|
|
101
|
-
field: SchemaField
|
|
102
|
-
): FieldOption[] | undefined | null {
|
|
103
|
-
const opts = field.options ?? field.restrictions?.options;
|
|
104
|
-
if (opts?.length ?? 0 > 0) {
|
|
105
|
-
return opts;
|
|
106
|
-
}
|
|
107
|
-
return undefined;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export const defaultExpressionHook: ExpressionHook = (
|
|
111
|
-
expr: EntityExpression,
|
|
112
|
-
formState: FormEditState
|
|
113
|
-
) => {
|
|
114
|
-
switch (expr.type) {
|
|
115
|
-
case ExpressionType.FieldValue:
|
|
116
|
-
const fvExpr = expr as FieldValueExpression;
|
|
117
|
-
return controlForField(fvExpr.field, formState).value === fvExpr.value;
|
|
118
|
-
default:
|
|
119
|
-
return undefined;
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
export function createFormEditHooks(
|
|
124
|
-
useExpression: ExpressionHook
|
|
125
|
-
): FormEditHooks {
|
|
126
|
-
return {
|
|
127
|
-
useExpression,
|
|
128
|
-
useDataProperties(
|
|
129
|
-
formState: FormEditState,
|
|
130
|
-
definition: DataControlDefinition,
|
|
131
|
-
field: SchemaField
|
|
132
|
-
): DataControlProperties {
|
|
133
|
-
const visible = useIsControlVisible(definition, formState, useExpression);
|
|
134
|
-
const defaultValue = useDefaultValue(
|
|
135
|
-
definition,
|
|
136
|
-
field,
|
|
137
|
-
formState,
|
|
138
|
-
useExpression
|
|
139
|
-
);
|
|
140
|
-
const scalarControl = formState.data.fields[field.field];
|
|
141
|
-
|
|
142
|
-
useEffect(() => {
|
|
143
|
-
if (!visible) scalarControl.value = null;
|
|
144
|
-
else if (scalarControl.current.value == null) {
|
|
145
|
-
scalarControl.value = defaultValue;
|
|
146
|
-
}
|
|
147
|
-
}, [visible, defaultValue]);
|
|
148
|
-
return getDefaultScalarControlProperties(
|
|
149
|
-
definition,
|
|
150
|
-
field,
|
|
151
|
-
visible,
|
|
152
|
-
defaultValue,
|
|
153
|
-
scalarControl,
|
|
154
|
-
formState.readonly
|
|
155
|
-
);
|
|
156
|
-
},
|
|
157
|
-
useDisplayProperties: (fs, definition) => {
|
|
158
|
-
const visible = useIsControlVisible(definition, fs, useExpression);
|
|
159
|
-
return { visible };
|
|
160
|
-
},
|
|
161
|
-
useGroupProperties: (fs, definition, hooks) => {
|
|
162
|
-
const visible = useIsControlVisible(definition, fs, useExpression);
|
|
163
|
-
return { visible, hooks };
|
|
164
|
-
},
|
|
165
|
-
useActionProperties(
|
|
166
|
-
formState: FormEditState,
|
|
167
|
-
definition: ActionControlDefinition
|
|
168
|
-
): ActionControlProperties {
|
|
169
|
-
const visible = useIsControlVisible(definition, formState, useExpression);
|
|
170
|
-
return { visible, onClick: () => {} };
|
|
171
|
-
},
|
|
172
|
-
};
|
|
173
|
-
}
|