ballerina-core 1.0.10 → 1.0.12
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/main.ts +2 -0
- package/package.json +1 -1
- package/src/coroutines/state.ts +4 -4
- package/src/forms/domains/launcher/domains/merger/state.ts +31 -3
- package/src/forms/domains/parser/coroutines/runner.ts +4 -3
- package/src/forms/domains/parser/domains/built-ins/state.ts +189 -0
- package/src/forms/domains/parser/domains/types/domains/converter/state.ts +1 -0
- package/src/forms/domains/parser/domains/types/state.ts +31 -0
- package/src/forms/domains/parser/domains/validator/state.ts +28 -80
- package/src/forms/domains/parser/state.tsx +33 -86
- package/src/fun/domains/updater/domains/caseUpdater/state.ts +5 -5
package/main.ts
CHANGED
|
@@ -95,6 +95,8 @@ export * from "./src/forms/domains/parser/state"
|
|
|
95
95
|
export * from "./src/forms/domains/parser/template"
|
|
96
96
|
export * from "./src/forms/domains/parser/coroutines/runner"
|
|
97
97
|
export * from "./src/forms/domains/parser/domains/validator/state"
|
|
98
|
+
export * from "./src/forms/domains/parser/domains/built-ins/state"
|
|
99
|
+
export * from "./src/forms/domains/parser/domains/types/state"
|
|
98
100
|
export * from "./src/forms/domains/launcher/domains/edit/state"
|
|
99
101
|
export * from "./src/forms/domains/launcher/domains/edit/template"
|
|
100
102
|
export * from "./src/forms/domains/launcher/domains/edit/coroutines/runner"
|
package/package.json
CHANGED
package/src/coroutines/state.ts
CHANGED
|
@@ -243,10 +243,10 @@ export const Coroutine = {
|
|
|
243
243
|
return CoroutineStep.Result(nextState, step.result);
|
|
244
244
|
else {
|
|
245
245
|
if (step.excludeOthers) {
|
|
246
|
-
console.log(
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
);
|
|
246
|
+
// console.log(
|
|
247
|
+
// `exclude others detected, killing ${ps.length - 1
|
|
248
|
+
// } other coroutines`
|
|
249
|
+
// );
|
|
250
250
|
return CoroutineStep.MapState(
|
|
251
251
|
step.next([context, deltaT]),
|
|
252
252
|
((_) => thenMaybe(nextState, _) || id)
|
|
@@ -1,9 +1,37 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { merge } from 'immutable'
|
|
2
|
+
|
|
3
|
+
const INITIAL_CONFIG = {
|
|
4
|
+
types: {},
|
|
5
|
+
forms: {},
|
|
6
|
+
apis: {
|
|
7
|
+
enumOptions: {},
|
|
8
|
+
searchableStreams: {},
|
|
9
|
+
entities: {},
|
|
10
|
+
},
|
|
11
|
+
mappings: {},
|
|
12
|
+
launchers: {}
|
|
13
|
+
}
|
|
2
14
|
|
|
3
15
|
export const FormsConfigMerger = {
|
|
4
16
|
Default:{
|
|
5
|
-
merge:(formsConfigs:any
|
|
6
|
-
|
|
17
|
+
merge: (formsConfigs: any): any => {
|
|
18
|
+
if (!formsConfigs || formsConfigs.length === 0) {
|
|
19
|
+
return {...INITIAL_CONFIG};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return formsConfigs.reduce((acc: any, current: any) => {
|
|
23
|
+
return {
|
|
24
|
+
types: merge(acc.types, current.types),
|
|
25
|
+
forms: merge(acc.forms, current.forms),
|
|
26
|
+
apis: {
|
|
27
|
+
enumOptions: merge(acc.apis.enumOptions, current.apis.enumOptions),
|
|
28
|
+
searchableStreams: merge(acc.apis.searchableStreams, current.apis.searchableStreams),
|
|
29
|
+
entities: merge(acc.apis.entities, current.apis.entities),
|
|
30
|
+
},
|
|
31
|
+
mappings: merge(acc.mappings, current.mappings),
|
|
32
|
+
launchers: merge(acc.launchers, current.launchers),
|
|
33
|
+
}
|
|
34
|
+
}, {...INITIAL_CONFIG})
|
|
7
35
|
}
|
|
8
36
|
}
|
|
9
37
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AsyncState, FormsConfig, Sum, Synchronize, Unit } from "../../../../../main"
|
|
1
|
+
import { AsyncState, builtInsFromFieldViews, FormsConfig, Sum, Synchronize, Unit } from "../../../../../main"
|
|
2
2
|
import { CoTypedFactory } from "../../../../coroutines/builder"
|
|
3
|
-
import {
|
|
3
|
+
import { FormParsingResult, FormsParserContext, FormsParserState, parseForms } from "../state"
|
|
4
4
|
|
|
5
5
|
export const LoadValidateAndParseFormsConfig = () => {
|
|
6
6
|
const Co = CoTypedFactory<FormsParserContext, FormsParserState>()
|
|
@@ -9,13 +9,14 @@ export const LoadValidateAndParseFormsConfig = () => {
|
|
|
9
9
|
Co.GetState().then(current =>
|
|
10
10
|
Synchronize<Unit, FormParsingResult>(async() => {
|
|
11
11
|
const formsConfig = await current.getFormsConfig()
|
|
12
|
-
const builtIns = builtInsFromFieldViews(current.fieldViews)
|
|
12
|
+
const builtIns = builtInsFromFieldViews(current.fieldViews, current.fieldTypeConverters)
|
|
13
13
|
const validationResult = FormsConfig.Default.validateAndParseAPIResponse(builtIns)(formsConfig)
|
|
14
14
|
if (validationResult.kind == "r")
|
|
15
15
|
return Sum.Default.right(validationResult.value)
|
|
16
16
|
return parseForms(
|
|
17
17
|
builtIns,
|
|
18
18
|
current.containerFormView,
|
|
19
|
+
current.nestedContainerFormView,
|
|
19
20
|
current.fieldViews,
|
|
20
21
|
current.infiniteStreamSources,
|
|
21
22
|
current.enumOptionsSources,
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { Map, List, Set, OrderedMap } from "immutable"
|
|
2
|
+
import { CollectionReference } from "../../../collection/domains/reference/state";
|
|
3
|
+
import { CollectionSelection } from "../../../collection/domains/selection/state";
|
|
4
|
+
import { BasicFun } from "../../../../../fun/state";
|
|
5
|
+
import { Option, Sum } from "../../../../../collections/domains/sum/state"
|
|
6
|
+
import { Type, TypeDefinition, TypeName } from "../../../../../../main";
|
|
7
|
+
|
|
8
|
+
export const PrimitiveTypes =
|
|
9
|
+
["string",
|
|
10
|
+
"number",
|
|
11
|
+
"boolean",
|
|
12
|
+
"maybeBoolean",
|
|
13
|
+
"Date",
|
|
14
|
+
"CollectionReference"] as const
|
|
15
|
+
export type PrimitiveType = (typeof PrimitiveTypes)[number]
|
|
16
|
+
|
|
17
|
+
export const GenericTypes = [
|
|
18
|
+
"SingleSelection",
|
|
19
|
+
"MultiSelection",
|
|
20
|
+
"List"] as const
|
|
21
|
+
export type GenericType = (typeof GenericTypes)[number]
|
|
22
|
+
|
|
23
|
+
export type ApiConverter<T> = { fromAPIRawValue: BasicFun<any, T>, toAPIRawValue: BasicFun<T, any> }
|
|
24
|
+
export type ApiConverters = {
|
|
25
|
+
"string": ApiConverter<string>
|
|
26
|
+
"number": ApiConverter<number>
|
|
27
|
+
"boolean": ApiConverter<boolean>
|
|
28
|
+
"maybeBoolean": ApiConverter<boolean | undefined>
|
|
29
|
+
"Date": ApiConverter<Date>
|
|
30
|
+
"CollectionReference": ApiConverter<CollectionReference>
|
|
31
|
+
"SingleSelection": ApiConverter<CollectionSelection<any>>
|
|
32
|
+
"MultiSelection": ApiConverter<OrderedMap<string, any>>
|
|
33
|
+
"List": ApiConverter<List<any>>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type PrimitiveBuiltIn = { renderers: Set<keyof BuiltIns["renderers"]>, apiConverters: ApiConverter<any>, defaultValue: any }
|
|
37
|
+
export type GenericBuiltIn = { defaultValue: any, apiConverters: ApiConverter<any> }
|
|
38
|
+
export type BuiltIns = {
|
|
39
|
+
primitives: Map<string, PrimitiveBuiltIn>;
|
|
40
|
+
generics: Map<string, GenericBuiltIn>;
|
|
41
|
+
renderers: {
|
|
42
|
+
boolean: Set<string>;
|
|
43
|
+
maybeBoolean: Set<string>;
|
|
44
|
+
number: Set<string>;
|
|
45
|
+
string: Set<string>;
|
|
46
|
+
date: Set<string>;
|
|
47
|
+
enumSingleSelection: Set<string>;
|
|
48
|
+
enumMultiSelection: Set<string>;
|
|
49
|
+
streamSingleSelection: Set<string>;
|
|
50
|
+
streamMultiSelection: Set<string>;
|
|
51
|
+
list: Set<string>;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const builtInsFromFieldViews = (fieldViews: any, fieldTypeConverters: ApiConverters): BuiltIns => {
|
|
56
|
+
let builtins: BuiltIns = {
|
|
57
|
+
"primitives": Map<string, PrimitiveBuiltIn>([
|
|
58
|
+
["string", { renderers: Set(["string"]), apiConverters: fieldTypeConverters["string"], defaultValue: "" }] as [string, PrimitiveBuiltIn],
|
|
59
|
+
["number", { renderers: Set(["number"]), apiConverters: fieldTypeConverters["number"], defaultValue: 0 }] as [string, PrimitiveBuiltIn],
|
|
60
|
+
["boolean", { renderers: Set(["boolean"]), apiConverters: fieldTypeConverters["boolean"], defaultValue: false }],
|
|
61
|
+
["maybeBoolean", { renderers: Set(["maybeBoolean"]), apiConverters: fieldTypeConverters["maybeBoolean"], defaultValue: undefined }] as [string, PrimitiveBuiltIn],
|
|
62
|
+
["date", { renderers: Set(["date"]), apiConverters: fieldTypeConverters["Date"], defaultValue: new Date(Date.now()) }] as [string, PrimitiveBuiltIn],
|
|
63
|
+
["Date", { renderers: Set(["date"]), apiConverters: fieldTypeConverters["Date"], defaultValue: new Date(Date.now()) }] as [string, PrimitiveBuiltIn],
|
|
64
|
+
["CollectionReference", { renderers: Set(["enumSingleSelection", "enumMultiSelection", "streamSingleSelection", "streamMultiSelection"]), apiConverters: fieldTypeConverters["CollectionReference"], defaultValue: CollectionReference.Default("", "") }] as [string, PrimitiveBuiltIn]
|
|
65
|
+
]),
|
|
66
|
+
"generics": Map([
|
|
67
|
+
["SingleSelection", { apiConverters: fieldTypeConverters["SingleSelection"], defaultValue: CollectionSelection().Default.right("no selection") }] as [string, GenericBuiltIn],
|
|
68
|
+
["Multiselection", { apiConverters: fieldTypeConverters["SingleSelection"], defaultValue: Map() }] as [string, GenericBuiltIn],
|
|
69
|
+
["List", { apiConverters: fieldTypeConverters["SingleSelection"], defaultValue: [] }] as [string, GenericBuiltIn]
|
|
70
|
+
]),
|
|
71
|
+
"renderers": {
|
|
72
|
+
"boolean": Set(),
|
|
73
|
+
"maybeBoolean": Set(),
|
|
74
|
+
"date": Set(),
|
|
75
|
+
"enumMultiSelection": Set(),
|
|
76
|
+
"enumSingleSelection": Set(),
|
|
77
|
+
"streamMultiSelection": Set(),
|
|
78
|
+
"streamSingleSelection": Set(),
|
|
79
|
+
"number": Set(),
|
|
80
|
+
"string": Set(),
|
|
81
|
+
"list": Set(),
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
Object.keys(builtins.renderers).forEach((_categoryName) => {
|
|
85
|
+
const categoryName = _categoryName as keyof BuiltIns["renderers"]
|
|
86
|
+
if (categoryName in fieldViews) {
|
|
87
|
+
Object.keys(fieldViews[categoryName]).forEach(viewName => {
|
|
88
|
+
builtins.renderers[categoryName] = builtins.renderers[categoryName].add(viewName)
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
return builtins
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
export const defaultValue = (types:Map<TypeName, TypeDefinition>, builtIns:BuiltIns) => (t: TypeName): any => {
|
|
97
|
+
let primitive = builtIns.primitives.get(t)
|
|
98
|
+
if (primitive != undefined) {
|
|
99
|
+
return primitive.defaultValue
|
|
100
|
+
} else {
|
|
101
|
+
let generic = builtIns.generics.get(t)
|
|
102
|
+
if (generic != undefined) {
|
|
103
|
+
return generic.defaultValue
|
|
104
|
+
} else {
|
|
105
|
+
let custom = types.get(t)
|
|
106
|
+
if (custom != undefined) {
|
|
107
|
+
let res = {} as any
|
|
108
|
+
custom.fields.forEach((field, fieldName) => {
|
|
109
|
+
res[fieldName] = defaultValue(types, builtIns)(field.kind == "primitive" ? field.value : field.kind == "lookup" ? field.name : field.value)
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
return res
|
|
113
|
+
} else {
|
|
114
|
+
throw `cannot find type ${t} when resolving defaultValue`
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export const fromAPIRawValue = (t:Type, types:Map<TypeName, TypeDefinition>, builtIns:BuiltIns, converters:ApiConverters) => (raw:any) : any => {
|
|
121
|
+
if (raw == undefined) {
|
|
122
|
+
console.error(`instantiating default value for type ${JSON.stringify(t)}: something is missing from the API response`)
|
|
123
|
+
return defaultValue(types, builtIns)(t.kind == "primitive" ? t.value : t.kind == "lookup" ? t.name : t.value)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (t.kind == "primitive") {
|
|
127
|
+
return converters[t.value].fromAPIRawValue(raw)
|
|
128
|
+
} else if (t.kind == "application") { // application here means "generic type application"
|
|
129
|
+
if (t.value == "SingleSelection" && t.args.length == 1) {
|
|
130
|
+
let result = converters[t.value].fromAPIRawValue(raw)
|
|
131
|
+
result = CollectionSelection().Updaters.left(
|
|
132
|
+
fromAPIRawValue({ kind:"lookup", name:t.args[0] }, types, builtIns, converters))(result)
|
|
133
|
+
return result
|
|
134
|
+
}
|
|
135
|
+
if (t.value == "MultiSelection" && t.args.length == 1) {
|
|
136
|
+
let result = converters[t.value].fromAPIRawValue(raw)
|
|
137
|
+
result = result.map(fromAPIRawValue({ kind:"lookup", name:t.args[0] }, types, builtIns, converters))
|
|
138
|
+
return result
|
|
139
|
+
}
|
|
140
|
+
if (t.value == "List" && t.args.length == 1) {
|
|
141
|
+
let result = converters[t.value].fromAPIRawValue(raw)
|
|
142
|
+
result = result.map(fromAPIRawValue({ kind:"lookup", name:t.args[0] }, types, builtIns, converters))
|
|
143
|
+
return result
|
|
144
|
+
}
|
|
145
|
+
} else { // t.kind == lookup: we are dealing with a record/object
|
|
146
|
+
let result:any = {}
|
|
147
|
+
const tDef = types.get(t.name)!
|
|
148
|
+
tDef.fields.forEach((fieldType, fieldName) => {
|
|
149
|
+
result[fieldName] = fromAPIRawValue(fieldType, types, builtIns, converters)(raw[fieldName])
|
|
150
|
+
})
|
|
151
|
+
return result
|
|
152
|
+
}
|
|
153
|
+
console.error(`instantiating default value for type ${JSON.stringify(t)}: something is missing from the API response`)
|
|
154
|
+
return defaultValue(types, builtIns)(t.value)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
export const toAPIRawValue = (t:Type, types:Map<TypeName, TypeDefinition>, builtIns:BuiltIns, converters:ApiConverters) => (raw:any) : any => {
|
|
159
|
+
if (t.kind == "primitive") {
|
|
160
|
+
// t.value == ""
|
|
161
|
+
return converters[t.value].toAPIRawValue(raw as never)
|
|
162
|
+
} else if (t.kind == "application") { // application here means "generic type application"
|
|
163
|
+
if (t.value == "SingleSelection" && t.args.length == 1) {
|
|
164
|
+
let result = converters[t.value].toAPIRawValue(raw)
|
|
165
|
+
result = CollectionSelection().Updaters.left(
|
|
166
|
+
toAPIRawValue({ kind:"lookup", name:t.args[0] }, types, builtIns, converters))(result)
|
|
167
|
+
return result
|
|
168
|
+
}
|
|
169
|
+
if (t.value == "MultiSelection" && t.args.length == 1) {
|
|
170
|
+
let result = converters[t.value].toAPIRawValue(raw)
|
|
171
|
+
result = result.map(toAPIRawValue({ kind:"lookup", name:t.args[0] }, types, builtIns, converters))
|
|
172
|
+
return result
|
|
173
|
+
}
|
|
174
|
+
if (t.value == "List" && t.args.length == 1) {
|
|
175
|
+
let result = converters[t.value].toAPIRawValue(raw)
|
|
176
|
+
result = result.map(toAPIRawValue({ kind:"lookup", name:t.args[0] }, types, builtIns, converters))
|
|
177
|
+
return result
|
|
178
|
+
}
|
|
179
|
+
} else { // t.kind == lookup: we are dealing with a record/object
|
|
180
|
+
let result:any = {}
|
|
181
|
+
const tDef = types.get(t.name)!
|
|
182
|
+
tDef.fields.forEach((fieldType, fieldName) => {
|
|
183
|
+
result[fieldName] = toAPIRawValue(fieldType, types, builtIns, converters)(raw[fieldName])
|
|
184
|
+
})
|
|
185
|
+
return result
|
|
186
|
+
}
|
|
187
|
+
console.error(`instantiating default value for type ${JSON.stringify(t)}: something is missing from the API response`)
|
|
188
|
+
return defaultValue(types, builtIns)(t.value)
|
|
189
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// export type
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { OrderedMap } from "immutable";
|
|
2
|
+
|
|
3
|
+
export type FieldName = string;
|
|
4
|
+
export type TypeName = string;
|
|
5
|
+
export type TypeDefinition = {
|
|
6
|
+
extends: Array<TypeName>;
|
|
7
|
+
name: TypeName;
|
|
8
|
+
fields: OrderedMap<FieldName, Type>;
|
|
9
|
+
};
|
|
10
|
+
export type Type = {
|
|
11
|
+
kind: "lookup"; name: TypeName;
|
|
12
|
+
} | {
|
|
13
|
+
kind: "primitive"; value: "string" | "number" | "maybeBoolean" | "boolean" | "Date" | "CollectionReference";
|
|
14
|
+
} | {
|
|
15
|
+
kind: "application"; value: TypeName; args: Array<TypeName>;
|
|
16
|
+
};
|
|
17
|
+
export const Type = {
|
|
18
|
+
Default: {
|
|
19
|
+
lookup: (name: TypeName): Type => ({ kind: "lookup", name })
|
|
20
|
+
},
|
|
21
|
+
Operations: {
|
|
22
|
+
Equals: (fst: Type, snd: Type): boolean =>
|
|
23
|
+
fst.kind == "lookup" && snd.kind == "lookup" ? fst.name == snd.name :
|
|
24
|
+
fst.kind == "primitive" && snd.kind == "primitive" ? fst.value == snd.value :
|
|
25
|
+
fst.kind == "application" && snd.kind == "application" ?
|
|
26
|
+
fst.value == snd.value &&
|
|
27
|
+
fst.args.length == snd.args.length &&
|
|
28
|
+
fst.args.every((v, i) => v == snd.args[i]) :
|
|
29
|
+
false
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -1,35 +1,6 @@
|
|
|
1
1
|
import { Set, Map, OrderedMap } from "immutable";
|
|
2
|
-
import { BoolExpr, FormsConfigMerger, MappingPaths, Sum } from "../../../../../../main";
|
|
2
|
+
import { BoolExpr, BuiltIns, FieldName, FormsConfigMerger, MappingPaths, Sum, Type, TypeDefinition, TypeName } from "../../../../../../main";
|
|
3
3
|
|
|
4
|
-
export type FieldName = string;
|
|
5
|
-
export type TypeName = string;
|
|
6
|
-
export type TypeDefinition = {
|
|
7
|
-
extends: Array<TypeName>;
|
|
8
|
-
name: TypeName;
|
|
9
|
-
fields: OrderedMap<FieldName, Type>;
|
|
10
|
-
};
|
|
11
|
-
export type Type = {
|
|
12
|
-
kind: "lookup"; name: TypeName;
|
|
13
|
-
} | {
|
|
14
|
-
kind: "primitive"; value: "string" | "number" | "maybeBoolean" | "boolean" | "Date" | "CollectionReference";
|
|
15
|
-
} | {
|
|
16
|
-
kind: "application"; value: TypeName; args: Array<TypeName>;
|
|
17
|
-
};
|
|
18
|
-
export const Type = {
|
|
19
|
-
Default: {
|
|
20
|
-
lookup: (name: TypeName): Type => ({ kind: "lookup", name })
|
|
21
|
-
},
|
|
22
|
-
Operations: {
|
|
23
|
-
Equals: (fst: Type, snd: Type): boolean =>
|
|
24
|
-
fst.kind == "lookup" && snd.kind == "lookup" ? fst.name == snd.name :
|
|
25
|
-
fst.kind == "primitive" && snd.kind == "primitive" ? fst.value == snd.value :
|
|
26
|
-
fst.kind == "application" && snd.kind == "application" ?
|
|
27
|
-
fst.value == snd.value &&
|
|
28
|
-
fst.args.length == snd.args.length &&
|
|
29
|
-
fst.args.every((v, i) => v == snd.args[i]) :
|
|
30
|
-
false
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
4
|
export type FieldConfig = {
|
|
34
5
|
renderer: string;
|
|
35
6
|
label: string
|
|
@@ -91,37 +62,12 @@ export type FormsConfig = {
|
|
|
91
62
|
};
|
|
92
63
|
export type FormValidationError = string;
|
|
93
64
|
|
|
94
|
-
export type PrimitiveBuiltIn = { renderers: Set<keyof BuiltIns["renderers"]>, defaultValue: any }
|
|
95
|
-
export type GenericBuiltIn = { defaultValue: any }
|
|
96
|
-
export type BuiltIns = {
|
|
97
|
-
primitives: Map<string, PrimitiveBuiltIn>;
|
|
98
|
-
generics: Map<string, GenericBuiltIn>;
|
|
99
|
-
renderers: {
|
|
100
|
-
BooleanViews: Set<string>;
|
|
101
|
-
MaybeBooleanViews: Set<string>;
|
|
102
|
-
NumberViews: Set<string>;
|
|
103
|
-
StringViews: Set<string>;
|
|
104
|
-
DateViews: Set<string>;
|
|
105
|
-
EnumViews: Set<string>;
|
|
106
|
-
EnumMultiselectViews: Set<string>;
|
|
107
|
-
InfiniteStreamViews: Set<string>;
|
|
108
|
-
InfiniteStreamMultiselectViews: Set<string>;
|
|
109
|
-
ListViews: Set<string>;
|
|
110
|
-
};
|
|
111
|
-
};
|
|
112
|
-
|
|
113
65
|
export type FormValidationResult = Sum<FormsConfig, Array<FormValidationError>>
|
|
114
66
|
export const FormsConfig = {
|
|
115
67
|
Default: {
|
|
116
|
-
validateAndParseAPIResponse: (builtIns: BuiltIns) => (
|
|
68
|
+
validateAndParseAPIResponse: (builtIns: BuiltIns) => (fc: any): FormValidationResult => {
|
|
117
69
|
let errors: Array<FormValidationError> = [];
|
|
118
|
-
|
|
119
|
-
alert("formsConfig is an array!")
|
|
120
|
-
const merged = FormsConfigMerger.Default.merge(formsConfig, errors)
|
|
121
|
-
formsConfig = merged[0]
|
|
122
|
-
errors = merged[0]
|
|
123
|
-
}
|
|
124
|
-
|
|
70
|
+
const formsConfig = Array.isArray(fc) ? FormsConfigMerger.Default.merge(fc) : fc;
|
|
125
71
|
let types: Map<TypeName, TypeDefinition> = Map();
|
|
126
72
|
if ("types" in formsConfig == false) {
|
|
127
73
|
errors.push("the formsConfig does not contain a 'types' field");
|
|
@@ -346,57 +292,59 @@ export const FormsConfig = {
|
|
|
346
292
|
if (fieldTypeDef.value == "maybeBoolean") {
|
|
347
293
|
// alert(JSON.stringify(fieldConfig["renderer"]))
|
|
348
294
|
// alert(JSON.stringify(builtIns.renderers.MaybeBooleanViews))
|
|
349
|
-
if (!builtIns.renderers.
|
|
295
|
+
if (!builtIns.renderers.maybeBoolean.has(fieldConfig["renderer"]))
|
|
350
296
|
errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
|
|
351
297
|
} else if (fieldTypeDef.value == "boolean") {
|
|
352
|
-
if (!builtIns.renderers.
|
|
298
|
+
if (!builtIns.renderers.boolean.has(fieldConfig["renderer"]))
|
|
353
299
|
errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
|
|
354
300
|
} else if (fieldTypeDef.value == "number") {
|
|
355
|
-
if (!builtIns.renderers.
|
|
301
|
+
if (!builtIns.renderers.number.has(fieldConfig["renderer"]))
|
|
356
302
|
errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
|
|
357
303
|
} else if (fieldTypeDef.value == "string") {
|
|
358
|
-
if (!builtIns.renderers.
|
|
304
|
+
if (!builtIns.renderers.string.has(fieldConfig["renderer"]))
|
|
359
305
|
errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
|
|
360
306
|
} else if (fieldTypeDef.value == "Date") {
|
|
361
|
-
if (!builtIns.renderers.
|
|
307
|
+
if (!builtIns.renderers.date.has(fieldConfig["renderer"])) {
|
|
308
|
+
alert(JSON.stringify(builtIns.renderers))
|
|
362
309
|
errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
|
|
363
|
-
|
|
310
|
+
}
|
|
311
|
+
} else {
|
|
364
312
|
errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
|
|
365
313
|
}
|
|
366
314
|
} else if (fieldTypeDef?.kind == "application") {
|
|
367
315
|
if (fieldTypeDef?.value == "SingleSelection") {
|
|
368
|
-
if (!builtIns.renderers.
|
|
369
|
-
!builtIns.renderers.
|
|
316
|
+
if (!builtIns.renderers.enumSingleSelection.has(fieldConfig["renderer"]) &&
|
|
317
|
+
!builtIns.renderers.streamSingleSelection.has(fieldConfig["renderer"]))
|
|
370
318
|
errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
|
|
371
319
|
} else if (fieldTypeDef?.value == "Multiselection") {
|
|
372
|
-
if (!builtIns.renderers.
|
|
373
|
-
!builtIns.renderers.
|
|
320
|
+
if (!builtIns.renderers.enumMultiSelection.has(fieldConfig["renderer"]) &&
|
|
321
|
+
!builtIns.renderers.streamMultiSelection.has(fieldConfig["renderer"]))
|
|
374
322
|
errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
|
|
375
323
|
} else if (fieldTypeDef?.value == "List") {
|
|
376
|
-
if (!builtIns.renderers.
|
|
324
|
+
if (!builtIns.renderers.list.has(fieldConfig["renderer"]))
|
|
377
325
|
errors.push(`field ${fieldName} of form ${formName} references non-existing ${fieldTypeDef.value} 'renderer' ${fieldConfig["renderer"]}`);
|
|
378
326
|
}
|
|
379
327
|
if (fieldTypeDef.args.length < 1)
|
|
380
328
|
errors.push(`field ${fieldName} of form ${formName} should have one type argument}`);
|
|
381
329
|
else if (
|
|
382
|
-
(builtIns.renderers.
|
|
330
|
+
(builtIns.renderers.list.has(fieldConfig["renderer"])) && "elementRenderer" in fieldConfig != true)
|
|
383
331
|
errors.push(`field ${fieldName} of form ${formName} is missing the 'elementRenderer' property`);
|
|
384
332
|
else if (
|
|
385
|
-
(builtIns.renderers.
|
|
386
|
-
builtIns.renderers.
|
|
333
|
+
(builtIns.renderers.enumMultiSelection.has(fieldConfig["renderer"]) ||
|
|
334
|
+
builtIns.renderers.enumSingleSelection.has(fieldConfig["renderer"])) && "options" in fieldConfig != true)
|
|
387
335
|
errors.push(`field ${fieldName} of form ${formName} is missing the 'options' property`);
|
|
388
336
|
else if (
|
|
389
|
-
(builtIns.renderers.
|
|
390
|
-
builtIns.renderers.
|
|
337
|
+
(builtIns.renderers.streamSingleSelection.has(fieldConfig["renderer"]) ||
|
|
338
|
+
builtIns.renderers.streamMultiSelection.has(fieldConfig["renderer"])) && "stream" in fieldConfig != true)
|
|
391
339
|
errors.push(`field ${fieldName} of form ${formName} is missing the 'stream' property`);
|
|
392
|
-
else if ((builtIns.renderers.
|
|
393
|
-
builtIns.renderers.
|
|
340
|
+
else if ((builtIns.renderers.enumMultiSelection.has(fieldConfig["renderer"]) ||
|
|
341
|
+
builtIns.renderers.enumSingleSelection.has(fieldConfig["renderer"])) && (enums.get(fieldConfig["options"])) != fieldTypeDef.args[0]) {
|
|
394
342
|
if (enums.has(fieldConfig["options"]))
|
|
395
343
|
errors.push(`field ${fieldName} of form ${formName} references an enum api with type ${enums.get(fieldConfig["options"])} when ${fieldTypeDef.args[0]} was expected`);
|
|
396
344
|
else
|
|
397
345
|
errors.push(`field ${fieldName} of form ${formName} references a non-existing enum api`);
|
|
398
|
-
} else if ((builtIns.renderers.
|
|
399
|
-
builtIns.renderers.
|
|
346
|
+
} else if ((builtIns.renderers.streamMultiSelection.has(fieldConfig["renderer"]) ||
|
|
347
|
+
builtIns.renderers.streamSingleSelection.has(fieldConfig["renderer"])) && (streams.get(fieldConfig["stream"])) != fieldTypeDef.args[0]) {
|
|
400
348
|
if (streams.has(fieldConfig["stream"]))
|
|
401
349
|
errors.push(`field ${fieldName} of form ${formName} references an api with type ${streams.get(fieldConfig["stream"])} when ${fieldTypeDef.args[0]} was expected`);
|
|
402
350
|
else
|
|
@@ -415,7 +363,7 @@ export const FormsConfig = {
|
|
|
415
363
|
Object.keys(configFormDef["fields"]).forEach(fieldName => {
|
|
416
364
|
const fieldConfig = configFormDef["fields"][fieldName]
|
|
417
365
|
const fieldTypeDef = formTypeDef?.fields.get(fieldName);
|
|
418
|
-
if (fieldTypeDef && fieldTypeDef.kind == "application" && fieldTypeDef.value == "List" && (builtIns.renderers.
|
|
366
|
+
if (fieldTypeDef && fieldTypeDef.kind == "application" && fieldTypeDef.value == "List" && (builtIns.renderers.list.has(fieldConfig["renderer"]))) {
|
|
419
367
|
let elementRenderer = fieldConfig["elementRenderer"]
|
|
420
368
|
let elementType = fieldTypeDef.args[0]
|
|
421
369
|
const rendererHasType = (elementRenderer: string, elementType: string): Array<string> => {
|
|
@@ -570,8 +518,8 @@ export const FormsConfig = {
|
|
|
570
518
|
})
|
|
571
519
|
|
|
572
520
|
if (errors.length > 0) {
|
|
573
|
-
console.
|
|
574
|
-
console.
|
|
521
|
+
console.error("parsing errors")
|
|
522
|
+
console.error(errors)
|
|
575
523
|
return Sum.Default.right(errors);
|
|
576
524
|
}
|
|
577
525
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Collection, Map, OrderedMap, OrderedSet, Set } from "immutable";
|
|
2
|
-
import { BoolExpr, Unit, PromiseRepo, Guid, LeafPredicatesEvaluators, Predicate, FormsConfig, BuiltIns, FormDef, Sum, BasicFun, Template, unit, EditFormState, EditFormTemplate, ApiErrors, CreateFormTemplate, EntityFormTemplate, SharedFormState, CreateFormState, Entity, EditFormContext, CreateFormContext, MappedEntityFormTemplate, Mapping, FormValidationResult, Synchronized, simpleUpdater,
|
|
2
|
+
import { BoolExpr, Unit, PromiseRepo, Guid, LeafPredicatesEvaluators, Predicate, FormsConfig, BuiltIns, FormDef, Sum, BasicFun, Template, unit, EditFormState, EditFormTemplate, ApiErrors, CreateFormTemplate, EntityFormTemplate, SharedFormState, CreateFormState, Entity, EditFormContext, CreateFormContext, MappedEntityFormTemplate, Mapping, FormValidationResult, Synchronized, simpleUpdater, PrimitiveType, GenericType, ApiConverter, TypeName, ListFieldState, ListForm, TypeDefinition, ApiConverters, defaultValue, fromAPIRawValue } from "../../../../main";
|
|
3
3
|
import { Value } from "../../../value/state";
|
|
4
4
|
import { CollectionReference } from "../collection/domains/reference/state";
|
|
5
5
|
import { CollectionSelection } from "../collection/domains/selection/state";
|
|
@@ -26,43 +26,43 @@ const parseOptions = (leafPredicates: any, options: any) => {
|
|
|
26
26
|
export const FieldView = //<Context, FieldViews extends DefaultFieldViews, EnumFieldConfigs extends {}, EnumSources extends {}>() => <ViewType extends keyof FieldViews, ViewName extends keyof FieldViews[ViewType]>
|
|
27
27
|
(fieldViews: any, viewType: any, viewName: any, fieldName: string, label: string, enumFieldConfigs: any, enumSources: any, leafPredicates: any): any => // FieldView<Context, FieldViews, ViewType, ViewName> =>
|
|
28
28
|
{
|
|
29
|
-
if (viewType == "
|
|
29
|
+
if (viewType == "maybeBoolean")
|
|
30
30
|
return MaybeBooleanForm<any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
|
|
31
31
|
.withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
|
|
32
32
|
.mapContext<any & SharedFormState & Value<boolean>>(_ => ({ ..._, label: label })) as any
|
|
33
|
-
if (viewType == "
|
|
33
|
+
if (viewType == "boolean")
|
|
34
34
|
return BooleanForm<any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
|
|
35
35
|
.withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
|
|
36
36
|
.mapContext<any & SharedFormState & Value<boolean>>(_ => ({ ..._, label: label })) as any
|
|
37
|
-
if (viewType == "
|
|
37
|
+
if (viewType == "date")
|
|
38
38
|
return DateForm<any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
|
|
39
39
|
.withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
|
|
40
40
|
.mapContext<any & DateFormState & Value<Date>>(_ => ({ ..._, label: label })) as any
|
|
41
|
-
if (viewType == "
|
|
41
|
+
if (viewType == "number")
|
|
42
42
|
return NumberForm<any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
|
|
43
43
|
.withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
|
|
44
44
|
.mapContext<any & SharedFormState & Value<number>>(_ => ({ ..._, label: label })) as any
|
|
45
|
-
if (viewType == "
|
|
45
|
+
if (viewType == "string")
|
|
46
46
|
return StringForm<any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
|
|
47
47
|
.withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
|
|
48
48
|
.mapContext<any & SharedFormState & Value<string>>(_ => ({ ..._, label: label })) as any
|
|
49
|
-
if (viewType == "
|
|
49
|
+
if (viewType == "enumSingleSelection")
|
|
50
50
|
return EnumForm<any & FormLabel & BaseEnumContext<any, CollectionReference>, Unit, CollectionReference>(_ => PromiseRepo.Default.mock(() => []))
|
|
51
51
|
.withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
|
|
52
52
|
.mapContext<any & EnumFormState<any & BaseEnumContext<any, CollectionReference>, CollectionReference> & Value<CollectionSelection<CollectionReference>>>(_ => ({
|
|
53
53
|
..._, label: label, getOptions: () => ((enumFieldConfigs as any)((enumSources as any)[fieldName]) as Promise<any>).then(options => parseOptions(leafPredicates, options))
|
|
54
54
|
})) as any
|
|
55
|
-
if (viewType == "
|
|
55
|
+
if (viewType == "enumMultiSelection")
|
|
56
56
|
return EnumMultiselectForm<any & FormLabel & BaseEnumContext<any, CollectionReference>, Unit, CollectionReference>(_ => PromiseRepo.Default.mock(() => []))
|
|
57
57
|
.withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
|
|
58
58
|
.mapContext<any & EnumFormState<any & BaseEnumContext<any, CollectionReference>, CollectionReference> & Value<OrderedMap<Guid, CollectionReference>>>(_ => ({
|
|
59
59
|
..._, label: label, getOptions: () => ((enumFieldConfigs as any)((enumSources as any)[fieldName]) as Promise<any>).then(options => parseOptions(leafPredicates, options))
|
|
60
60
|
})) as any
|
|
61
|
-
if (viewType == "
|
|
61
|
+
if (viewType == "streamSingleSelection")
|
|
62
62
|
return SearchableInfiniteStreamForm<CollectionReference, any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
|
|
63
63
|
.withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
|
|
64
64
|
.mapContext<any & SearchableInfiniteStreamState<CollectionReference> & Value<CollectionSelection<CollectionReference>>>(_ => ({ ..._, label: label })) as any
|
|
65
|
-
if (viewType == "
|
|
65
|
+
if (viewType == "streamMultiSelection")
|
|
66
66
|
return InfiniteMultiselectDropdownForm<CollectionReference, any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
|
|
67
67
|
.withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
|
|
68
68
|
.mapContext<any & FormLabel & SharedFormState & SearchableInfiniteStreamState<CollectionReference> & Value<OrderedMap<Guid, CollectionReference>>>(_ => ({ ..._, label: label })) as any
|
|
@@ -71,19 +71,19 @@ export const FieldView = //<Context, FieldViews extends DefaultFieldViews, EnumF
|
|
|
71
71
|
|
|
72
72
|
export const FieldFormState = //<Context, FieldViews extends DefaultFieldViews, InfiniteStreamSources extends {}, InfiniteStreamConfigs extends {}>() => <ViewType extends keyof FieldViews, ViewName extends keyof FieldViews[ViewType]>
|
|
73
73
|
(fieldViews: any, viewType: any, viewName: any, fieldName: string, InfiniteStreamSources: any, infiniteStreamConfigs: any): any => {
|
|
74
|
-
if (viewType == "
|
|
74
|
+
if (viewType == "maybeBoolean" || viewType == "boolean" || viewType == "number" || viewType == "string")
|
|
75
75
|
return SharedFormState.Default();
|
|
76
|
-
if (viewType == "
|
|
76
|
+
if (viewType == "date")
|
|
77
77
|
return DateFormState.Default("");
|
|
78
|
-
if (viewType == "
|
|
78
|
+
if (viewType == "enumSingleSelection" || viewType == "enumMultiSelection")
|
|
79
79
|
return ({ ...EnumFormState<any, any>().Default(), ...SharedFormState.Default() });
|
|
80
|
-
if (viewType == "
|
|
80
|
+
if (viewType == "streamSingleSelection" || viewType == "streamMultiSelection") {
|
|
81
81
|
return ({
|
|
82
82
|
...SearchableInfiniteStreamState<any>().Default("", (InfiniteStreamSources as any)((infiniteStreamConfigs as any)[fieldName])
|
|
83
83
|
), ...SharedFormState.Default()
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
|
-
if (viewType == "
|
|
86
|
+
if (viewType == "list")
|
|
87
87
|
return ListFieldState<any, any>().Default(Map())
|
|
88
88
|
return `error: the view for ${viewType as string}::${viewName as string} cannot be found when creating the corresponding field form state`;
|
|
89
89
|
};
|
|
@@ -97,6 +97,7 @@ export type ParsedForm = {
|
|
|
97
97
|
export const ParseForm = (
|
|
98
98
|
formDef: FormDef,
|
|
99
99
|
containerFormView: any,
|
|
100
|
+
nestedContainerFormView: any,
|
|
100
101
|
fieldViews: any,
|
|
101
102
|
otherForms: ParsedForms,
|
|
102
103
|
fieldsViewsConfig: any,
|
|
@@ -145,17 +146,15 @@ export const ParseForm = (
|
|
|
145
146
|
}
|
|
146
147
|
});
|
|
147
148
|
const formConfig: any = {};
|
|
148
|
-
console.log(fieldsViewsConfig)
|
|
149
|
-
console.log(Object.keys(fieldsViewsConfig))
|
|
150
149
|
Object.keys(fieldsViewsConfig).forEach(fieldName => {
|
|
151
150
|
const label = formDef.fields.get(fieldName)!.label
|
|
152
151
|
const viewName = (fieldsViewsConfig as any)[fieldName];
|
|
153
152
|
const otherForm = otherForms.get(viewName)
|
|
154
153
|
if (otherForm != undefined) {
|
|
155
|
-
formConfig[fieldName] = otherForm.form.withView(
|
|
154
|
+
formConfig[fieldName] = otherForm.form.withView(nestedContainerFormView).mapContext<any>(_ => ({ ..._, label: label }))
|
|
156
155
|
} else {
|
|
157
156
|
const viewType = fieldNameToViewCategory(fieldName) as any
|
|
158
|
-
if (viewType == "
|
|
157
|
+
if (viewType == "list") {
|
|
159
158
|
const elementRendererName = formFieldElementRenderers[fieldName]
|
|
160
159
|
const field = type.fields.get(fieldName)!
|
|
161
160
|
const initialElementValue = defaultValue(field.kind == "primitive" ? field.value : field.kind == "lookup" ? field.name : field.args[0])
|
|
@@ -166,7 +165,7 @@ export const ParseForm = (
|
|
|
166
165
|
{ Default: () => ({ ...initialFormState }) },
|
|
167
166
|
{ Default: () => ({ ...initialElementValue }) },
|
|
168
167
|
_ => PromiseRepo.Default.mock(() => []),
|
|
169
|
-
elementForm.form.withView(
|
|
168
|
+
elementForm.form.withView(nestedContainerFormView)
|
|
170
169
|
).withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
|
|
171
170
|
.mapContext<any>(_ => ({ ..._, label: label }))
|
|
172
171
|
} else { // the list argument is a primitive
|
|
@@ -187,7 +186,7 @@ export const ParseForm = (
|
|
|
187
186
|
if (typeof formConfig[fieldName] == "string") {
|
|
188
187
|
debugger
|
|
189
188
|
const err = formConfig[fieldName]
|
|
190
|
-
console.
|
|
189
|
+
console.error(`error processing field ${fieldName}`, err)
|
|
191
190
|
formConfig[fieldName] = (props: any) => <>Error: field {fieldName} with {viewName} could not be instantiated</>
|
|
192
191
|
throw err
|
|
193
192
|
}
|
|
@@ -214,44 +213,6 @@ export const parseVisibleFields = (
|
|
|
214
213
|
visibleFields.map(([fieldName, boolExpr]) => ([fieldName, boolExpr.eval<any>(leafPredicates)]) as any)
|
|
215
214
|
);
|
|
216
215
|
|
|
217
|
-
export const builtInsFromFieldViews = (fieldViews: any): BuiltIns => {
|
|
218
|
-
let builtins: BuiltIns = {
|
|
219
|
-
"primitives": Map([
|
|
220
|
-
["string", { renderers: Set(["StringViews"]), defaultValue: "" }] as [string, PrimitiveBuiltIn],
|
|
221
|
-
["number", { renderers: Set(["NumberViews"]), defaultValue: 0 }],
|
|
222
|
-
["boolean", { renderers: Set(["BooleanViews"]), defaultValue: false }],
|
|
223
|
-
["maybeBoolean", { renderers: Set(["MaybeBooleanViews"]), defaultValue: undefined }],
|
|
224
|
-
["Date", { renderers: Set(["DateViews"]), defaultValue: new Date(Date.now()) }],
|
|
225
|
-
["CollectionReference", { renderers: Set(["EnumViews"]), defaultValue: CollectionReference.Default("", "") }]]),
|
|
226
|
-
"generics": Map([
|
|
227
|
-
["SingleSelection", { defaultValue: CollectionSelection().Default.right("no selection") }] as [string, GenericBuiltIn],
|
|
228
|
-
["Multiselection", { defaultValue: Map() }],
|
|
229
|
-
["List", { defaultValue: [] }]
|
|
230
|
-
]),
|
|
231
|
-
"renderers": {
|
|
232
|
-
"BooleanViews": Set(),
|
|
233
|
-
"MaybeBooleanViews": Set(),
|
|
234
|
-
"DateViews": Set(),
|
|
235
|
-
"EnumMultiselectViews": Set(),
|
|
236
|
-
"EnumViews": Set(),
|
|
237
|
-
"InfiniteStreamMultiselectViews": Set(),
|
|
238
|
-
"InfiniteStreamViews": Set(),
|
|
239
|
-
"NumberViews": Set(),
|
|
240
|
-
"StringViews": Set(),
|
|
241
|
-
"ListViews": Set(),
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
Object.keys(builtins.renderers).forEach((_categoryName) => {
|
|
245
|
-
const categoryName = _categoryName as keyof BuiltIns["renderers"]
|
|
246
|
-
if (categoryName in fieldViews) {
|
|
247
|
-
Object.keys(fieldViews[categoryName]).forEach(viewName => {
|
|
248
|
-
builtins.renderers[categoryName] = builtins.renderers[categoryName].add(viewName)
|
|
249
|
-
})
|
|
250
|
-
}
|
|
251
|
-
})
|
|
252
|
-
return builtins
|
|
253
|
-
}
|
|
254
|
-
|
|
255
216
|
export type EditLauncherContext<Entity, FormState, ExtraContext> =
|
|
256
217
|
Omit<
|
|
257
218
|
EditFormContext<Entity, FormState> &
|
|
@@ -306,11 +267,14 @@ export type EntityApis = {
|
|
|
306
267
|
get: BasicFun<EntityName, BasicFun<Guid, Promise<any>>>
|
|
307
268
|
}
|
|
308
269
|
export type EnumName = string
|
|
270
|
+
|
|
271
|
+
|
|
309
272
|
export type EnumOptionsSources = BasicFun<EnumName, Promise<Array<[CollectionReference, BoolExpr<Unit>]>>>
|
|
310
273
|
export const parseForms =
|
|
311
274
|
<LeafPredicates,>(
|
|
312
275
|
builtIns: BuiltIns,
|
|
313
276
|
containerFormView: any,
|
|
277
|
+
nestedContainerFormView: any,
|
|
314
278
|
fieldViews: any,
|
|
315
279
|
infiniteStreamSources: InfiniteStreamSources,
|
|
316
280
|
enumOptionsSources: EnumOptionsSources,
|
|
@@ -322,31 +286,6 @@ export const parseForms =
|
|
|
322
286
|
let seen = Set<string>()
|
|
323
287
|
let formProcessingOrder = OrderedSet<string>()
|
|
324
288
|
|
|
325
|
-
const defaultValue = (t: TypeName): any => {
|
|
326
|
-
let primitive = builtIns.primitives.get(t)
|
|
327
|
-
if (primitive != undefined) {
|
|
328
|
-
return primitive.defaultValue
|
|
329
|
-
} else {
|
|
330
|
-
let generic = builtIns.generics.get(t)
|
|
331
|
-
if (generic != undefined) {
|
|
332
|
-
return generic.defaultValue
|
|
333
|
-
} else {
|
|
334
|
-
let custom = formsConfig.types.get(t)
|
|
335
|
-
if (custom != undefined) {
|
|
336
|
-
let res = {} as any
|
|
337
|
-
custom.fields.forEach((field, fieldName) => {
|
|
338
|
-
res[fieldName] = defaultValue(field.kind == "primitive" ? field.value : field.kind == "lookup" ? field.name : field.value)
|
|
339
|
-
}
|
|
340
|
-
)
|
|
341
|
-
return res
|
|
342
|
-
} else {
|
|
343
|
-
errors.push(`cannot find type ${t} when resolving defaultValue`)
|
|
344
|
-
return undefined
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
289
|
let parsedLaunchers: ParsedLaunchers = {
|
|
351
290
|
create: Map(),
|
|
352
291
|
edit: Map(),
|
|
@@ -384,6 +323,7 @@ export const parseForms =
|
|
|
384
323
|
const parsedForm = ParseForm(
|
|
385
324
|
formConfig,
|
|
386
325
|
containerFormView,
|
|
326
|
+
nestedContainerFormView,
|
|
387
327
|
fieldViews,
|
|
388
328
|
parsedForms,
|
|
389
329
|
formFieldRenderers,
|
|
@@ -395,7 +335,7 @@ export const parseForms =
|
|
|
395
335
|
leafPredicates,
|
|
396
336
|
formFieldVisibilities,
|
|
397
337
|
formFieldDisabled,
|
|
398
|
-
defaultValue,
|
|
338
|
+
defaultValue(formsConfig.types, builtIns),
|
|
399
339
|
formConfig.typeDef,
|
|
400
340
|
)
|
|
401
341
|
const formBuilder = Form<any, any, any, any>().Default<any>()
|
|
@@ -442,7 +382,12 @@ export const parseForms =
|
|
|
442
382
|
const initialState = parsedForm.initialFormState
|
|
443
383
|
const api = {
|
|
444
384
|
create: entityApis.create(launcher.api),
|
|
445
|
-
default: entityApis.default(launcher.api)
|
|
385
|
+
default: (_:Unit) => entityApis.default(launcher.api)(unit)
|
|
386
|
+
// .then((raw:undefined) => {
|
|
387
|
+
// alert(JSON.stringify(parsedForm.formConfig))
|
|
388
|
+
// const parsed = fromAPIRawValue({ kind:"lookup", name:"" }, null!, null!, null!)(raw)
|
|
389
|
+
// return parsed
|
|
390
|
+
// })
|
|
446
391
|
}
|
|
447
392
|
parsedLaunchers.create = parsedLaunchers.create.set(
|
|
448
393
|
launcherName,
|
|
@@ -497,7 +442,9 @@ export const parseForms =
|
|
|
497
442
|
|
|
498
443
|
export type FormsParserContext = {
|
|
499
444
|
containerFormView: any,
|
|
445
|
+
nestedContainerFormView: any,
|
|
500
446
|
fieldViews: any,
|
|
447
|
+
fieldTypeConverters: ApiConverters,
|
|
501
448
|
infiniteStreamSources: InfiniteStreamSources,
|
|
502
449
|
enumOptionsSources: EnumOptionsSources,
|
|
503
450
|
entityApis: EntityApis,
|
|
@@ -35,10 +35,10 @@ const X = {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
const visitor =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
// const visitor =
|
|
39
|
+
// X.Updaters.y.l(LeftValue.Updaters.value(_ => _ + 1)).then(
|
|
40
|
+
// X.Updaters.y.r(RightValue.Updaters.value(_ => !_))
|
|
41
|
+
// )
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
console.log(visitor)
|
|
44
|
+
// console.log(visitor)
|