@astroapps/forms-core 1.2.3 → 2.0.1
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/TODO.txt +6 -1
- package/jest.config.js +8 -0
- package/lib/controlBuilder.d.ts +60 -0
- package/lib/controlDefinition.d.ts +32 -8
- package/lib/evalExpression.d.ts +3 -2
- package/lib/formNode.d.ts +0 -7
- package/lib/formStateNode.d.ts +134 -0
- package/lib/index.cjs +1022 -324
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.ts +5 -1
- package/lib/index.js +852 -283
- package/lib/index.js.map +1 -1
- package/lib/overrideProxy.d.ts +7 -0
- package/lib/resolveChildren.d.ts +19 -0
- package/lib/schemaDataNode.d.ts +3 -0
- package/lib/schemaNode.d.ts +8 -1
- package/lib/schemaValidator.d.ts +3 -0
- package/lib/validators.d.ts +4 -5
- package/package.json +5 -5
- package/src/controlBuilder.ts +218 -0
- package/src/controlDefinition.ts +38 -8
- package/src/defaultSchemaInterface.ts +4 -3
- package/src/evalExpression.ts +38 -8
- package/src/formNode.ts +14 -54
- package/src/formStateNode.ts +807 -0
- package/src/index.ts +5 -1
- package/src/overrideProxy.ts +40 -0
- package/src/resolveChildren.ts +141 -0
- package/src/schemaBuilder.ts +3 -0
- package/src/schemaDataNode.ts +12 -0
- package/src/schemaNode.ts +59 -1
- package/src/schemaValidator.ts +19 -0
- package/src/validators.ts +20 -26
- package/tsconfig.test.json +21 -0
- package/lib/formState.d.ts +0 -48
- package/src/formState.ts +0 -529
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Control } from "@astroapps/controls";
|
|
2
|
+
export declare function createOverrideProxy<A extends object, B extends Record<string, any>>(proxyFor: A, handlers: Control<B>): A;
|
|
3
|
+
declare class NoValue {
|
|
4
|
+
}
|
|
5
|
+
export declare const NoOverride: NoValue;
|
|
6
|
+
export type KeysOfUnion<T> = T extends T ? keyof T : never;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ChangeListenerFunc, CleanupScope, Control } from "@astroapps/controls";
|
|
2
|
+
import { ControlDefinition } from "./controlDefinition";
|
|
3
|
+
import { SchemaDataNode } from "./schemaDataNode";
|
|
4
|
+
import { FormNode } from "./formNode";
|
|
5
|
+
import { FormStateNode } from "./formStateNode";
|
|
6
|
+
export type ChildResolverFunc = (c: FormStateNode) => ChildNodeSpec[];
|
|
7
|
+
export interface ChildNodeSpec {
|
|
8
|
+
childKey: string | number;
|
|
9
|
+
create: (scope: CleanupScope, meta: Record<string, any>) => ChildNodeInit;
|
|
10
|
+
}
|
|
11
|
+
export interface ChildNodeInit {
|
|
12
|
+
definition?: ControlDefinition;
|
|
13
|
+
parent?: SchemaDataNode;
|
|
14
|
+
node?: FormNode | null;
|
|
15
|
+
variables?: (changes: ChangeListenerFunc<any>) => Record<string, any>;
|
|
16
|
+
resolveChildren?: ChildResolverFunc;
|
|
17
|
+
}
|
|
18
|
+
export declare function defaultResolveChildNodes(formStateNode: FormStateNode): ChildNodeSpec[];
|
|
19
|
+
export declare function resolveArrayChildren(data: SchemaDataNode, node: FormNode, adjustChild?: (elem: Control<any>, index: number) => Partial<ChildNodeInit>): ChildNodeSpec[];
|
package/lib/schemaDataNode.d.ts
CHANGED
|
@@ -34,3 +34,6 @@ export declare function schemaDataForFieldRef(fieldRef: string | undefined, sche
|
|
|
34
34
|
export declare function schemaDataForFieldPath(fieldPath: string[], dataNode: SchemaDataNode): SchemaDataNode;
|
|
35
35
|
export declare function validDataNode(context: SchemaDataNode): boolean;
|
|
36
36
|
export declare function hideDisplayOnly(context: SchemaDataNode, schemaInterface: SchemaInterface, definition: ControlDefinition): boolean | undefined;
|
|
37
|
+
export declare function getLoadingControl(data: Control<any>): Control<boolean>;
|
|
38
|
+
export declare function getRefreshingControl(data: Control<any>): Control<boolean>;
|
|
39
|
+
export declare function getHasMoreControl(data: Control<any>): Control<boolean>;
|
package/lib/schemaNode.d.ts
CHANGED
|
@@ -15,7 +15,8 @@ export declare class SchemaNode {
|
|
|
15
15
|
field: SchemaField;
|
|
16
16
|
tree: SchemaTree;
|
|
17
17
|
parent?: SchemaNode | undefined;
|
|
18
|
-
|
|
18
|
+
private getChildFields?;
|
|
19
|
+
constructor(id: string, field: SchemaField, tree: SchemaTree, parent?: SchemaNode | undefined, getChildFields?: (() => SchemaField[]) | undefined);
|
|
19
20
|
getSchema(schemaId: string): SchemaNode | undefined;
|
|
20
21
|
getUnresolvedFields(): SchemaField[];
|
|
21
22
|
getResolvedParent(noRecurse?: boolean): SchemaNode | undefined;
|
|
@@ -37,6 +38,8 @@ export declare function traverseData(fieldPath: string[], root: SchemaNode, data
|
|
|
37
38
|
[k: string]: any;
|
|
38
39
|
}): unknown;
|
|
39
40
|
export declare function schemaForFieldPath(fieldPath: string[], schema: SchemaNode): SchemaNode;
|
|
41
|
+
export declare function schemaForDataPath(fieldPath: string[], schema: SchemaNode): DataPathNode;
|
|
42
|
+
export declare function getParentDataPath({ node, element, }: DataPathNode): DataPathNode | undefined;
|
|
40
43
|
export declare function getSchemaNodePath(node: SchemaNode): string[];
|
|
41
44
|
export declare function getSchemaNodePathString(node: SchemaNode): string;
|
|
42
45
|
export declare function isCompoundNode(node: SchemaNode): boolean;
|
|
@@ -52,3 +55,7 @@ export declare function relativePath(parent: SchemaNode, child: SchemaNode): str
|
|
|
52
55
|
* @param childPath
|
|
53
56
|
*/
|
|
54
57
|
export declare function relativeSegmentPath(parentPath: string[], childPath: string[]): string;
|
|
58
|
+
export interface DataPathNode {
|
|
59
|
+
node: SchemaNode;
|
|
60
|
+
element: boolean;
|
|
61
|
+
}
|
package/lib/schemaValidator.d.ts
CHANGED
|
@@ -25,3 +25,6 @@ export interface DateValidator extends SchemaValidator {
|
|
|
25
25
|
fixedDate?: string | null;
|
|
26
26
|
daysFromCurrent?: number | null;
|
|
27
27
|
}
|
|
28
|
+
export declare function jsonataValidator(expr: string): JsonataValidator;
|
|
29
|
+
export declare function dateValidator(comparison: DateComparison, fixedDate?: string | null, daysFromCurrent?: number | null): DateValidator;
|
|
30
|
+
export declare function lengthValidator(min?: number | null, max?: number | null): LengthValidator;
|
package/lib/validators.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { DateValidator, JsonataValidator, LengthValidator, SchemaValidator } from "./schemaValidator";
|
|
2
2
|
import { ControlDefinition } from "./controlDefinition";
|
|
3
3
|
import { SchemaDataNode } from "./schemaDataNode";
|
|
4
|
-
import { Control } from "@astroapps/controls";
|
|
4
|
+
import { CleanupScope, Control } from "@astroapps/controls";
|
|
5
5
|
import { SchemaInterface } from "./schemaInterface";
|
|
6
|
-
import {
|
|
7
|
-
import { FormNode } from "./formNode";
|
|
6
|
+
import { VariablesFunc } from "./formStateNode";
|
|
8
7
|
export interface ValidationEvalContext {
|
|
9
8
|
addSync(validate: (value: unknown) => string | undefined | null): void;
|
|
10
9
|
addCleanup(cleanup: () => void): void;
|
|
@@ -12,7 +11,7 @@ export interface ValidationEvalContext {
|
|
|
12
11
|
parentData: SchemaDataNode;
|
|
13
12
|
data: SchemaDataNode;
|
|
14
13
|
schemaInterface: SchemaInterface;
|
|
15
|
-
|
|
14
|
+
variables?: VariablesFunc;
|
|
16
15
|
runAsync(af: () => void): void;
|
|
17
16
|
}
|
|
18
17
|
export type ValidatorEval<T extends SchemaValidator> = (validation: T, context: ValidationEvalContext) => void;
|
|
@@ -21,4 +20,4 @@ export declare const lengthValidator: ValidatorEval<LengthValidator>;
|
|
|
21
20
|
export declare const dateValidator: ValidatorEval<DateValidator>;
|
|
22
21
|
export declare const defaultValidators: Record<string, ValidatorEval<any>>;
|
|
23
22
|
export declare function createValidators(def: ControlDefinition, context: ValidationEvalContext): void;
|
|
24
|
-
export declare function setupValidation(
|
|
23
|
+
export declare function setupValidation(scope: CleanupScope, variables: VariablesFunc | undefined, definition: ControlDefinition, dataNode: Control<SchemaDataNode | undefined>, schemaInterface: SchemaInterface, parent: SchemaDataNode, visible: Control<boolean | null>, runAsync: (af: () => void) => void): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astroapps/forms-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.cjs",
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
"jsonata": "^2.0.4"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@astroapps/controls": "^1.
|
|
34
|
+
"@astroapps/controls": "^1.4.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@astroapps/controls": "^1.
|
|
37
|
+
"@astroapps/controls": "^1.4.0",
|
|
38
38
|
"jest": "^29.7.0",
|
|
39
39
|
"tsx": "^4.19.1",
|
|
40
|
-
"fast-check": "^3.
|
|
40
|
+
"fast-check": "^3.23.2",
|
|
41
41
|
"ts-jest": "^29.2.5",
|
|
42
42
|
"@jest/globals": "^29.7.0",
|
|
43
43
|
"typedoc": "^0.27.2",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
54
|
"build": "rimraf ./lib/ node_modules/.cache && microbundle -f modern,cjs --no-compress",
|
|
55
|
-
"watch": "microbundle -
|
|
55
|
+
"watch": "microbundle -f modern,cjs --no-compress",
|
|
56
56
|
"test": "jest --coverage",
|
|
57
57
|
"play": "tsx test/play.ts",
|
|
58
58
|
"update-readme": "md-magic --path README.md"
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AccordionAdornment,
|
|
3
|
+
ActionControlDefinition,
|
|
4
|
+
AutocompleteRenderOptions,
|
|
5
|
+
CheckListRenderOptions,
|
|
6
|
+
ControlAdornmentType,
|
|
7
|
+
ControlDefinition,
|
|
8
|
+
ControlDefinitionType,
|
|
9
|
+
DataControlDefinition,
|
|
10
|
+
DataRenderType,
|
|
11
|
+
DisplayControlDefinition,
|
|
12
|
+
DisplayDataType,
|
|
13
|
+
DisplayOnlyRenderOptions,
|
|
14
|
+
DynamicProperty,
|
|
15
|
+
DynamicPropertyType,
|
|
16
|
+
GroupedControlsDefinition,
|
|
17
|
+
GroupRenderType,
|
|
18
|
+
HtmlDisplay,
|
|
19
|
+
JsonataRenderOptions,
|
|
20
|
+
RadioButtonRenderOptions,
|
|
21
|
+
RenderOptions,
|
|
22
|
+
TextDisplay,
|
|
23
|
+
TextfieldRenderOptions,
|
|
24
|
+
} from "./controlDefinition";
|
|
25
|
+
import {
|
|
26
|
+
DateValidator,
|
|
27
|
+
JsonataValidator,
|
|
28
|
+
LengthValidator,
|
|
29
|
+
ValidatorType,
|
|
30
|
+
} from "./schemaValidator";
|
|
31
|
+
import {
|
|
32
|
+
DataExpression,
|
|
33
|
+
DataMatchExpression,
|
|
34
|
+
EntityExpression,
|
|
35
|
+
ExpressionType,
|
|
36
|
+
JsonataExpression,
|
|
37
|
+
NotEmptyExpression,
|
|
38
|
+
} from "./entityExpression";
|
|
39
|
+
|
|
40
|
+
export function dataControl(
|
|
41
|
+
field: string,
|
|
42
|
+
title?: string | null,
|
|
43
|
+
options?: Partial<DataControlDefinition>,
|
|
44
|
+
): DataControlDefinition {
|
|
45
|
+
return { type: ControlDefinitionType.Data, field, title, ...options };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function validatorOptions<A extends { type: string }>(
|
|
49
|
+
type: ValidatorType,
|
|
50
|
+
): (options: Omit<A, "type">) => A {
|
|
51
|
+
return (o) => ({ type, ...o }) as A;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function adornmentOptions<A extends { type: string }>(
|
|
55
|
+
type: ControlAdornmentType,
|
|
56
|
+
): (options: Omit<A, "type">) => A {
|
|
57
|
+
return (o) => ({ type, ...o }) as A;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function renderOptionsFor<A extends RenderOptions>(
|
|
61
|
+
type: DataRenderType,
|
|
62
|
+
): (options: Omit<A, "type">) => { renderOptions: A } {
|
|
63
|
+
return (o) => ({ renderOptions: { type, ...o } as A });
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export const autocompleteOptions = renderOptionsFor<AutocompleteRenderOptions>(
|
|
67
|
+
DataRenderType.Autocomplete,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
export const checkListOptions = renderOptionsFor<CheckListRenderOptions>(
|
|
71
|
+
DataRenderType.CheckList,
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
export const radioButtonOptions = renderOptionsFor<RadioButtonRenderOptions>(
|
|
75
|
+
DataRenderType.Radio,
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
export const lengthValidatorOptions = validatorOptions<LengthValidator>(
|
|
79
|
+
ValidatorType.Length,
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
export const jsonataValidatorOptions = validatorOptions<JsonataValidator>(
|
|
83
|
+
ValidatorType.Jsonata,
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
export const dateValidatorOptions = validatorOptions<DateValidator>(
|
|
87
|
+
ValidatorType.Date,
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
export const accordionOptions = adornmentOptions<AccordionAdornment>(
|
|
91
|
+
ControlAdornmentType.Accordion,
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
export const textfieldOptions = renderOptionsFor<TextfieldRenderOptions>(
|
|
95
|
+
DataRenderType.Textfield,
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
export const displayOnlyOptions = renderOptionsFor<DisplayOnlyRenderOptions>(
|
|
99
|
+
DataRenderType.DisplayOnly,
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
export const jsonataOptions = renderOptionsFor<JsonataRenderOptions>(
|
|
103
|
+
DataRenderType.Jsonata,
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
export function textDisplayControl(
|
|
107
|
+
text: string,
|
|
108
|
+
options?: Partial<DisplayControlDefinition>,
|
|
109
|
+
): DisplayControlDefinition {
|
|
110
|
+
return {
|
|
111
|
+
type: ControlDefinitionType.Display,
|
|
112
|
+
displayData: { type: DisplayDataType.Text, text } as TextDisplay,
|
|
113
|
+
...options,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function htmlDisplayControl(
|
|
118
|
+
html: string,
|
|
119
|
+
options?: Partial<DisplayControlDefinition>,
|
|
120
|
+
): DisplayControlDefinition {
|
|
121
|
+
return {
|
|
122
|
+
type: ControlDefinitionType.Display,
|
|
123
|
+
displayData: { type: DisplayDataType.Html, html } as HtmlDisplay,
|
|
124
|
+
...options,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function dynamicDefaultValue(expr: EntityExpression): DynamicProperty {
|
|
129
|
+
return { type: DynamicPropertyType.DefaultValue, expr };
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function dynamicReadonly(expr: EntityExpression): DynamicProperty {
|
|
133
|
+
return { type: DynamicPropertyType.Readonly, expr };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function dynamicVisibility(expr: EntityExpression): DynamicProperty {
|
|
137
|
+
return { type: DynamicPropertyType.Visible, expr };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function dynamicDisabled(expr: EntityExpression): DynamicProperty {
|
|
141
|
+
return { type: DynamicPropertyType.Disabled, expr };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function dataExpr(field: string): DataExpression {
|
|
145
|
+
return { type: ExpressionType.Data, field };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* @deprecated Use dataExpr
|
|
150
|
+
*/
|
|
151
|
+
export const fieldExpr = dataExpr;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* @deprecated Use dataMatchExpr
|
|
155
|
+
*/
|
|
156
|
+
export const fieldEqExpr = dataMatchExpr;
|
|
157
|
+
|
|
158
|
+
export const uuidExpr = { type: ExpressionType.UUID };
|
|
159
|
+
export function dataMatchExpr(field: string, value: any): DataMatchExpression {
|
|
160
|
+
return { type: ExpressionType.DataMatch, field, value };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function notEmptyExpr(
|
|
164
|
+
field: string,
|
|
165
|
+
empty?: boolean,
|
|
166
|
+
): NotEmptyExpression {
|
|
167
|
+
return { type: ExpressionType.NotEmpty, field, empty };
|
|
168
|
+
}
|
|
169
|
+
export function jsonataExpr(expression: string): JsonataExpression {
|
|
170
|
+
return { type: ExpressionType.Jsonata, expression };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export function groupedControl(
|
|
174
|
+
children: ControlDefinition[],
|
|
175
|
+
title?: string,
|
|
176
|
+
options?: Partial<GroupedControlsDefinition>,
|
|
177
|
+
): GroupedControlsDefinition {
|
|
178
|
+
return {
|
|
179
|
+
type: ControlDefinitionType.Group,
|
|
180
|
+
children,
|
|
181
|
+
title,
|
|
182
|
+
groupOptions: { type: "Standard", hideTitle: !title },
|
|
183
|
+
...options,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
export function compoundControl(
|
|
187
|
+
field: string,
|
|
188
|
+
title: string | undefined | null,
|
|
189
|
+
children: ControlDefinition[],
|
|
190
|
+
options?: Partial<DataControlDefinition>,
|
|
191
|
+
): DataControlDefinition {
|
|
192
|
+
return {
|
|
193
|
+
type: ControlDefinitionType.Data,
|
|
194
|
+
field,
|
|
195
|
+
children,
|
|
196
|
+
title,
|
|
197
|
+
renderOptions: { type: "Standard" },
|
|
198
|
+
...options,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export function actionControl(
|
|
203
|
+
actionText: string,
|
|
204
|
+
actionId: string,
|
|
205
|
+
options?: Partial<ActionControlDefinition>,
|
|
206
|
+
): ActionControlDefinition {
|
|
207
|
+
return {
|
|
208
|
+
type: ControlDefinitionType.Action,
|
|
209
|
+
title: actionText,
|
|
210
|
+
actionId,
|
|
211
|
+
...options,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
export const emptyGroupDefinition: GroupedControlsDefinition = {
|
|
215
|
+
type: ControlDefinitionType.Group,
|
|
216
|
+
children: [],
|
|
217
|
+
groupOptions: { type: GroupRenderType.Standard, hideTitle: true },
|
|
218
|
+
};
|
package/src/controlDefinition.ts
CHANGED
|
@@ -22,6 +22,8 @@ export interface ControlDefinition {
|
|
|
22
22
|
childRefId?: string | null;
|
|
23
23
|
title?: string | null;
|
|
24
24
|
hidden?: boolean | null;
|
|
25
|
+
disabled?: boolean | null;
|
|
26
|
+
readonly?: boolean | null;
|
|
25
27
|
styleClass?: string | null;
|
|
26
28
|
textClass?: string | null;
|
|
27
29
|
layoutClass?: string | null;
|
|
@@ -56,6 +58,7 @@ export enum DynamicPropertyType {
|
|
|
56
58
|
AllowedOptions = "AllowedOptions",
|
|
57
59
|
Label = "Label",
|
|
58
60
|
ActionData = "ActionData",
|
|
61
|
+
GridColumns = "GridColumns",
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
export interface ControlAdornment {
|
|
@@ -133,11 +136,10 @@ export interface DataControlDefinition extends ControlDefinition {
|
|
|
133
136
|
required?: boolean | null;
|
|
134
137
|
renderOptions?: RenderOptions | null;
|
|
135
138
|
defaultValue?: any;
|
|
136
|
-
readonly?: boolean | null;
|
|
137
|
-
disabled?: boolean | null;
|
|
138
139
|
validators?: SchemaValidator[] | null;
|
|
139
140
|
hideTitle?: boolean | null;
|
|
140
141
|
dontClearHidden?: boolean | null;
|
|
142
|
+
requiredErrorText?: string | null;
|
|
141
143
|
}
|
|
142
144
|
|
|
143
145
|
export interface RenderOptions {
|
|
@@ -165,6 +167,7 @@ export enum DataRenderType {
|
|
|
165
167
|
Array = "Array",
|
|
166
168
|
ArrayElement = "ArrayElement",
|
|
167
169
|
ElementSelected = "ElementSelected",
|
|
170
|
+
ScrollList = "ScrollList",
|
|
168
171
|
}
|
|
169
172
|
|
|
170
173
|
export interface TextfieldRenderOptions extends RenderOptions {
|
|
@@ -256,6 +259,7 @@ export interface ArrayRenderOptions extends RenderOptions {
|
|
|
256
259
|
noRemove?: boolean | null;
|
|
257
260
|
noReorder?: boolean | null;
|
|
258
261
|
editExternal?: boolean | null;
|
|
262
|
+
childOverrideClass?: string | null;
|
|
259
263
|
}
|
|
260
264
|
|
|
261
265
|
export interface ArrayElementRenderOptions extends RenderOptions {
|
|
@@ -310,6 +314,12 @@ export interface IconSelectionRenderOptions extends RenderOptions {
|
|
|
310
314
|
type: DataRenderType.IconSelector;
|
|
311
315
|
}
|
|
312
316
|
|
|
317
|
+
export interface ScrollListRenderOptions extends RenderOptions {
|
|
318
|
+
type: DataRenderType.ScrollList;
|
|
319
|
+
bottomActionId?: string;
|
|
320
|
+
refreshActionId?: string;
|
|
321
|
+
}
|
|
322
|
+
|
|
313
323
|
export interface GroupedControlsDefinition extends ControlDefinition {
|
|
314
324
|
type: ControlDefinitionType.Group;
|
|
315
325
|
compoundField?: string | null;
|
|
@@ -344,11 +354,19 @@ export enum GroupRenderType {
|
|
|
344
354
|
Wizard = "Wizard",
|
|
345
355
|
Dialog = "Dialog",
|
|
346
356
|
Contents = "Contents",
|
|
357
|
+
Accordion = "Accordion",
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export interface AccordionRenderer extends GroupRenderOptions {
|
|
361
|
+
type: GroupRenderType.Accordion;
|
|
362
|
+
defaultExpanded?: boolean | null;
|
|
363
|
+
expandStateField?: string | null;
|
|
347
364
|
}
|
|
348
365
|
|
|
349
366
|
export interface DialogRenderOptions extends GroupRenderOptions {
|
|
350
367
|
type: GroupRenderType.Dialog;
|
|
351
368
|
title?: string | null;
|
|
369
|
+
portalHost?: string | null;
|
|
352
370
|
}
|
|
353
371
|
|
|
354
372
|
export interface StandardGroupRenderer extends GroupRenderOptions {
|
|
@@ -366,10 +384,11 @@ export interface GroupElementRenderer extends GroupRenderOptions {
|
|
|
366
384
|
value: any;
|
|
367
385
|
}
|
|
368
386
|
|
|
369
|
-
export interface
|
|
387
|
+
export interface GridRendererOptions extends GroupRenderOptions {
|
|
370
388
|
type: GroupRenderType.Grid;
|
|
371
389
|
columns?: number | null;
|
|
372
390
|
rowClass?: string | null;
|
|
391
|
+
cellClass?: string | null;
|
|
373
392
|
}
|
|
374
393
|
|
|
375
394
|
export interface TabsRenderOptions extends GroupRenderOptions {
|
|
@@ -422,6 +441,12 @@ export interface CustomDisplay extends DisplayData {
|
|
|
422
441
|
customId: string;
|
|
423
442
|
}
|
|
424
443
|
|
|
444
|
+
export enum ControlDisableType {
|
|
445
|
+
None = "None",
|
|
446
|
+
Self = "Self",
|
|
447
|
+
Global = "Global",
|
|
448
|
+
}
|
|
449
|
+
|
|
425
450
|
export interface ActionControlDefinition extends ControlDefinition {
|
|
426
451
|
type: ControlDefinitionType.Action;
|
|
427
452
|
actionId: string;
|
|
@@ -429,6 +454,7 @@ export interface ActionControlDefinition extends ControlDefinition {
|
|
|
429
454
|
icon?: IconReference | null;
|
|
430
455
|
actionStyle?: ActionStyle | null;
|
|
431
456
|
iconPlacement?: IconPlacement | null;
|
|
457
|
+
disableType?: ControlDisableType | null;
|
|
432
458
|
}
|
|
433
459
|
|
|
434
460
|
export enum ActionStyle {
|
|
@@ -471,7 +497,7 @@ export function visitControlDefinition<A>(
|
|
|
471
497
|
}
|
|
472
498
|
export function isGridRenderer(
|
|
473
499
|
options: GroupRenderOptions,
|
|
474
|
-
): options is
|
|
500
|
+
): options is GridRendererOptions {
|
|
475
501
|
return options.type === GroupRenderType.Grid;
|
|
476
502
|
}
|
|
477
503
|
|
|
@@ -487,9 +513,13 @@ export function isDialogRenderer(
|
|
|
487
513
|
return options.type === GroupRenderType.Dialog;
|
|
488
514
|
}
|
|
489
515
|
|
|
490
|
-
export function
|
|
516
|
+
export function isAccordionRenderer(
|
|
491
517
|
options: GroupRenderOptions,
|
|
492
|
-
): options is
|
|
518
|
+
): options is AccordionRenderer {
|
|
519
|
+
return options.type === GroupRenderType.Accordion;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
export function isInlineRenderer(options: GroupRenderOptions): boolean {
|
|
493
523
|
return options.type === GroupRenderType.Inline;
|
|
494
524
|
}
|
|
495
525
|
|
|
@@ -652,7 +682,7 @@ export function fontAwesomeIcon(icon: string) {
|
|
|
652
682
|
* @returns True if the control definition is readonly, false otherwise.
|
|
653
683
|
*/
|
|
654
684
|
export function isControlReadonly(c: ControlDefinition): boolean {
|
|
655
|
-
return
|
|
685
|
+
return !!c.readonly;
|
|
656
686
|
}
|
|
657
687
|
|
|
658
688
|
/**
|
|
@@ -661,7 +691,7 @@ export function isControlReadonly(c: ControlDefinition): boolean {
|
|
|
661
691
|
* @returns True if the control definition is disabled, false otherwise.
|
|
662
692
|
*/
|
|
663
693
|
export function isControlDisabled(c: ControlDefinition): boolean {
|
|
664
|
-
return
|
|
694
|
+
return !!c.disabled;
|
|
665
695
|
}
|
|
666
696
|
|
|
667
697
|
/**
|
|
@@ -109,7 +109,7 @@ export class DefaultSchemaInterface implements SchemaInterface {
|
|
|
109
109
|
? new Date("1970-01-01T" + value).toLocaleTimeString()
|
|
110
110
|
: undefined;
|
|
111
111
|
case FieldType.Bool:
|
|
112
|
-
return this.boolStrings[value ? 1 : 0];
|
|
112
|
+
return value != null ? this.boolStrings[value ? 1 : 0] : undefined;
|
|
113
113
|
default:
|
|
114
114
|
return value != null ? value.toString() : undefined;
|
|
115
115
|
}
|
|
@@ -122,7 +122,8 @@ export class DefaultSchemaInterface implements SchemaInterface {
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
valueLength(field: SchemaField, value: any): number {
|
|
125
|
-
|
|
125
|
+
const len = value?.length;
|
|
126
|
+
return typeof len === "number" ? len : 0;
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
compareValue(field: SchemaField, v1: unknown, v2: unknown): number {
|
|
@@ -135,7 +136,7 @@ export class DefaultSchemaInterface implements SchemaInterface {
|
|
|
135
136
|
case FieldType.String:
|
|
136
137
|
return (v1 as string).localeCompare(v2 as string);
|
|
137
138
|
case FieldType.Bool:
|
|
138
|
-
return
|
|
139
|
+
return v1 === v2 ? 0 : !v1 ? -1 : 1;
|
|
139
140
|
case FieldType.Int:
|
|
140
141
|
case FieldType.Double:
|
|
141
142
|
return (v1 as number) - (v2 as number);
|
package/src/evalExpression.ts
CHANGED
|
@@ -8,12 +8,13 @@ import {
|
|
|
8
8
|
} from "./entityExpression";
|
|
9
9
|
import {
|
|
10
10
|
AsyncEffect,
|
|
11
|
+
ChangeListenerFunc,
|
|
11
12
|
CleanupScope,
|
|
12
13
|
collectChanges,
|
|
14
|
+
Control,
|
|
13
15
|
createAsyncEffect,
|
|
14
16
|
createSyncEffect,
|
|
15
17
|
trackedValue,
|
|
16
|
-
Value,
|
|
17
18
|
} from "@astroapps/controls";
|
|
18
19
|
import { schemaDataForFieldRef, SchemaDataNode } from "./schemaDataNode";
|
|
19
20
|
import { SchemaInterface } from "./schemaInterface";
|
|
@@ -27,7 +28,7 @@ export interface ExpressionEvalContext {
|
|
|
27
28
|
returnResult: (k: unknown) => void;
|
|
28
29
|
dataNode: SchemaDataNode;
|
|
29
30
|
schemaInterface: SchemaInterface;
|
|
30
|
-
variables?:
|
|
31
|
+
variables?: (changes: ChangeListenerFunc<any>) => Record<string, any>;
|
|
31
32
|
runAsync(effect: () => void): void;
|
|
32
33
|
}
|
|
33
34
|
|
|
@@ -91,15 +92,17 @@ export const jsonataEval: ExpressionEval<JsonataExpression> = (
|
|
|
91
92
|
});
|
|
92
93
|
|
|
93
94
|
async function runJsonata(effect: AsyncEffect<any>, signal: AbortSignal) {
|
|
94
|
-
const
|
|
95
|
-
effect.collectUsage,
|
|
96
|
-
() => variables?.value,
|
|
97
|
-
);
|
|
95
|
+
const trackedVars = variables?.(effect.collectUsage);
|
|
98
96
|
const evalResult = await parsedJsonata.fields.expr.value.evaluate(
|
|
99
97
|
trackedValue(rootData, effect.collectUsage),
|
|
100
|
-
|
|
98
|
+
trackedVars,
|
|
101
99
|
);
|
|
102
|
-
// console.log(
|
|
100
|
+
// console.log(
|
|
101
|
+
// rootData,
|
|
102
|
+
// parsedJsonata.fields.fullExpr.current.value,
|
|
103
|
+
// evalResult,
|
|
104
|
+
// trackedVars,
|
|
105
|
+
// );
|
|
103
106
|
collectChanges(effect.collectUsage, () => returnResult(evalResult));
|
|
104
107
|
}
|
|
105
108
|
|
|
@@ -118,3 +121,30 @@ export const defaultEvaluators: Record<string, ExpressionEval<any>> = {
|
|
|
118
121
|
[ExpressionType.Jsonata]: jsonataEval,
|
|
119
122
|
[ExpressionType.UUID]: uuidEval,
|
|
120
123
|
};
|
|
124
|
+
|
|
125
|
+
export function createEvalExpr(
|
|
126
|
+
evalExpression: (e: EntityExpression, ctx: ExpressionEvalContext) => void,
|
|
127
|
+
context: Omit<ExpressionEvalContext, "returnResult" | "scope">,
|
|
128
|
+
) {
|
|
129
|
+
function evalExpr<A>(
|
|
130
|
+
scope: CleanupScope,
|
|
131
|
+
init: A,
|
|
132
|
+
nk: Control<A>,
|
|
133
|
+
e: EntityExpression | undefined,
|
|
134
|
+
coerce: (t: unknown) => any,
|
|
135
|
+
): boolean {
|
|
136
|
+
nk.value = init;
|
|
137
|
+
if (e?.type) {
|
|
138
|
+
evalExpression(e, {
|
|
139
|
+
returnResult: (r) => {
|
|
140
|
+
nk.value = coerce(r);
|
|
141
|
+
},
|
|
142
|
+
scope,
|
|
143
|
+
...context,
|
|
144
|
+
});
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
return evalExpr;
|
|
150
|
+
}
|