ballerina-core 1.0.50 → 1.0.51
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/package.json +1 -1
- package/src/collections/domains/valueOrErrors/state.ts +23 -23
- package/src/forms/domains/launcher/domains/edit/coroutines/runner.ts +21 -9
- package/src/forms/domains/launcher/domains/edit/state.ts +3 -1
- package/src/forms/domains/parser/domains/built-ins/state.ts +27 -36
- package/src/forms/domains/parser/domains/validator/state.ts +0 -3
- package/src/forms/domains/parser/state.tsx +5 -5
- package/src/forms/domains/primitives/domains/list/template.tsx +17 -17
package/package.json
CHANGED
|
@@ -7,25 +7,25 @@ export type ValueOrErrors<v, e> = (
|
|
|
7
7
|
| (Value<v> & { kind: "value" })
|
|
8
8
|
| { errors: List<e>; kind: "errors" }
|
|
9
9
|
) & {
|
|
10
|
-
|
|
10
|
+
Map: <a, b, e>(
|
|
11
11
|
this: ValueOrErrors<a, e>,
|
|
12
12
|
f: BasicFun<a, b>
|
|
13
13
|
) => ValueOrErrors<b, e>;
|
|
14
|
-
|
|
14
|
+
MapErrors: <a, e, e2>(
|
|
15
15
|
this: ValueOrErrors<a, e>,
|
|
16
16
|
f: BasicFun<List<e>, List<e2>>
|
|
17
17
|
) => ValueOrErrors<a, e2>;
|
|
18
|
-
|
|
18
|
+
Flatten: <a, e>(
|
|
19
19
|
this: ValueOrErrors<ValueOrErrors<a, e>, e>
|
|
20
20
|
) => ValueOrErrors<a, e>;
|
|
21
|
-
|
|
21
|
+
Then: <a, b, e>(
|
|
22
22
|
this: ValueOrErrors<a, e>,
|
|
23
23
|
k: BasicFun<a, ValueOrErrors<b, e>>
|
|
24
24
|
) => ValueOrErrors<b, e>;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
const operations = {
|
|
28
|
-
|
|
28
|
+
Map: function <a, b, e>(
|
|
29
29
|
this: ValueOrErrors<a, e>,
|
|
30
30
|
f: BasicFun<a, b>
|
|
31
31
|
): ValueOrErrors<b, e> {
|
|
@@ -34,7 +34,7 @@ const operations = {
|
|
|
34
34
|
}
|
|
35
35
|
return ValueOrErrors.Default.return(f(this.value));
|
|
36
36
|
},
|
|
37
|
-
|
|
37
|
+
MapErrors: function <a, e, e2>(
|
|
38
38
|
this: ValueOrErrors<a, e>,
|
|
39
39
|
f: BasicFun<List<e>, List<e2>>
|
|
40
40
|
): ValueOrErrors<a, e2> {
|
|
@@ -43,7 +43,7 @@ const operations = {
|
|
|
43
43
|
}
|
|
44
44
|
return this;
|
|
45
45
|
},
|
|
46
|
-
|
|
46
|
+
Flatten: function <a, e>(
|
|
47
47
|
this: ValueOrErrors<ValueOrErrors<a, e>, e>
|
|
48
48
|
): ValueOrErrors<a, e> {
|
|
49
49
|
if (this.kind == "errors") {
|
|
@@ -54,11 +54,11 @@ const operations = {
|
|
|
54
54
|
return this.value;
|
|
55
55
|
}
|
|
56
56
|
},
|
|
57
|
-
|
|
57
|
+
Then: function <a, b, e>(
|
|
58
58
|
this: ValueOrErrors<a, e>,
|
|
59
59
|
k: BasicFun<a, ValueOrErrors<b, e>>
|
|
60
60
|
): ValueOrErrors<b, e> {
|
|
61
|
-
return this.
|
|
61
|
+
return this.Map(k).Flatten();
|
|
62
62
|
},
|
|
63
63
|
};
|
|
64
64
|
|
|
@@ -76,23 +76,23 @@ export const ValueOrErrors = {
|
|
|
76
76
|
}),
|
|
77
77
|
},
|
|
78
78
|
Operations: {
|
|
79
|
-
|
|
79
|
+
Return: <v, e>(_: v): ValueOrErrors<v, e> =>
|
|
80
80
|
ValueOrErrors.Default.return(_),
|
|
81
|
-
|
|
82
|
-
ValueOrErrors.Default.throw(
|
|
83
|
-
|
|
81
|
+
Throw: <v, e>(_: List<e>): ValueOrErrors<v, e> =>
|
|
82
|
+
ValueOrErrors.Default.throw(_),
|
|
83
|
+
Map: <a, b, e>(
|
|
84
84
|
f: BasicFun<a, b>
|
|
85
85
|
): Fun<ValueOrErrors<a, e>, ValueOrErrors<b, e>> =>
|
|
86
86
|
Fun((_) =>
|
|
87
87
|
_.kind == "errors" ? _ : ValueOrErrors.Default.return(f(_.value))
|
|
88
88
|
),
|
|
89
|
-
|
|
89
|
+
MapErrors: <a, e, e2>(
|
|
90
90
|
f: BasicFun<List<e>, List<e2>>
|
|
91
91
|
): BasicFun<ValueOrErrors<a, e>, ValueOrErrors<a, e2>> =>
|
|
92
92
|
Fun((_) =>
|
|
93
93
|
_.kind == "errors" ? ValueOrErrors.Default.throw(f(_.errors)) : _
|
|
94
94
|
),
|
|
95
|
-
|
|
95
|
+
Flatten: <a, e>(): Fun<
|
|
96
96
|
ValueOrErrors<ValueOrErrors<a, e>, e>,
|
|
97
97
|
ValueOrErrors<a, e>
|
|
98
98
|
> =>
|
|
@@ -105,30 +105,30 @@ export const ValueOrErrors = {
|
|
|
105
105
|
return _.value;
|
|
106
106
|
}
|
|
107
107
|
}),
|
|
108
|
-
|
|
108
|
+
Then: <a, b, e>(
|
|
109
109
|
k: BasicFun<a, ValueOrErrors<b, e>>
|
|
110
110
|
): Fun<ValueOrErrors<a, e>, ValueOrErrors<b, e>> =>
|
|
111
111
|
Fun((_: ValueOrErrors<a, e>) =>
|
|
112
|
-
ValueOrErrors.Operations.
|
|
113
|
-
ValueOrErrors.Operations.
|
|
112
|
+
ValueOrErrors.Operations.Flatten<b, e>()(
|
|
113
|
+
ValueOrErrors.Operations.Map<a, ValueOrErrors<b, e>, e>(k)(_)
|
|
114
114
|
)
|
|
115
115
|
),
|
|
116
|
-
|
|
116
|
+
Fold: <v, e, c>(
|
|
117
117
|
l: BasicFun<v, c>,
|
|
118
118
|
r: BasicFun<List<e>, c>
|
|
119
119
|
): Fun<ValueOrErrors<v, e>, c> =>
|
|
120
120
|
Fun((_) => (_.kind == "value" ? l(_.value) : r(_.errors))),
|
|
121
|
-
|
|
121
|
+
All: <v, e>(_: List<ValueOrErrors<v, e>>): ValueOrErrors<List<v>, e> =>
|
|
122
122
|
_.reduce(
|
|
123
123
|
(reduction, value) =>
|
|
124
|
-
ValueOrErrors.Operations.
|
|
124
|
+
ValueOrErrors.Operations.Fold<v, e, ValueOrErrors<List<v>, e>>(
|
|
125
125
|
(v: v) =>
|
|
126
126
|
reduction.kind == "errors"
|
|
127
127
|
? reduction
|
|
128
|
-
: reduction.
|
|
128
|
+
: reduction.Map((_) => _.concat(v)),
|
|
129
129
|
(es: List<e>) =>
|
|
130
130
|
reduction.kind == "errors"
|
|
131
|
-
? reduction.
|
|
131
|
+
? reduction.MapErrors((_) => _.concat(es))
|
|
132
132
|
: ValueOrErrors.Default.throw(es)
|
|
133
133
|
)(value),
|
|
134
134
|
ValueOrErrors.Default.return(List<v>())
|
|
@@ -37,15 +37,27 @@ export const editFormRunner = <E, FS>() => {
|
|
|
37
37
|
EditFormState<E, FS>().Updaters.Template.toUnchecked()
|
|
38
38
|
),
|
|
39
39
|
Debounce<Synchronized<Unit, ApiErrors>, EditFormWritableState<E, FS>>(
|
|
40
|
-
|
|
41
|
-
(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
(() => {
|
|
41
|
+
if(current.entity.sync.kind != "loaded") return Synchronize<Unit, ApiErrors, EditFormWritableState<E, FS>>(
|
|
42
|
+
(_) => Promise.resolve([]),
|
|
43
|
+
(_) => "transient failure",
|
|
44
|
+
5,
|
|
45
|
+
50
|
|
46
|
+
)
|
|
47
|
+
const parsed = current.parser(current.entity.sync.value, current.formState)
|
|
48
|
+
|
|
49
|
+
return Synchronize<Unit, ApiErrors, EditFormWritableState<E, FS>>(
|
|
50
|
+
(_) =>
|
|
51
|
+
{
|
|
52
|
+
if(parsed.kind == "errors") return Promise.reject(parsed.errors)
|
|
53
|
+
return current.api.update(current.entityId, parsed)
|
|
54
|
+
},
|
|
55
|
+
(_) => "transient failure",
|
|
56
|
+
parsed.kind == "errors" ? 1 : 5,
|
|
57
|
+
50
|
|
58
|
+
)
|
|
59
|
+
})(),
|
|
60
|
+
|
|
49
61
|
15
|
|
50
62
|
).embed(
|
|
51
63
|
(_) => ({ ..._, ..._.apiRunner }),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ApiResponseChecker, AsyncState, BasicUpdater, Debounced, ForeignMutationsInput, Guid, id, SimpleCallback, simpleUpdater, Synchronized, Template, unit, Unit, Updater, Value } from "../../../../../../main"
|
|
2
|
+
import { ValueOrErrors } from "../../../../../collections/domains/valueOrErrors/state"
|
|
2
3
|
import { BasicFun } from "../../../../../fun/state"
|
|
3
4
|
|
|
4
5
|
export type ApiErrors = Array<string>
|
|
@@ -7,8 +8,9 @@ export type EditFormContext<E,FS> = {
|
|
|
7
8
|
entityId:string,
|
|
8
9
|
api:{
|
|
9
10
|
get:(id: Guid) => Promise<E>,
|
|
10
|
-
update:(id: Guid,
|
|
11
|
+
update:(id: Guid, raw: any) => Promise<ApiErrors>
|
|
11
12
|
},
|
|
13
|
+
parser: (entity:E, formstate: FS) => ValueOrErrors<E, ApiErrors>
|
|
12
14
|
actualForm:Template<Value<E> & FS, FS, { onChange:SimpleCallback<BasicUpdater<E>>}>
|
|
13
15
|
}
|
|
14
16
|
|
|
@@ -2,7 +2,7 @@ import { Map, List, Set, OrderedMap } from "immutable"
|
|
|
2
2
|
import { CollectionReference } from "../../../collection/domains/reference/state";
|
|
3
3
|
import { CollectionSelection } from "../../../collection/domains/selection/state";
|
|
4
4
|
import { BasicFun } from "../../../../../fun/state";
|
|
5
|
-
import { InjectedPrimitives, Maybe, replaceKeyword, replaceKeywords, revertKeyword, Type, TypeDefinition, TypeName, Unit, Value } from "../../../../../../main";
|
|
5
|
+
import { InjectedPrimitives, Maybe, replaceKeyword, replaceKeywords, revertKeyword, Sum, Type, TypeDefinition, TypeName, Unit, Value } from "../../../../../../main";
|
|
6
6
|
import { ValueOrErrors } from "../../../../../collections/domains/valueOrErrors/state";
|
|
7
7
|
|
|
8
8
|
export const PrimitiveTypes =
|
|
@@ -186,7 +186,6 @@ export const fromAPIRawValue = <T>(t: Type, types: Map<TypeName, TypeDefinition>
|
|
|
186
186
|
return result
|
|
187
187
|
}
|
|
188
188
|
if (t.value == "Map" && t.args.length == 2) {
|
|
189
|
-
console.log("t", t)
|
|
190
189
|
let result = converters[t.value].fromAPIRawValue(obj)
|
|
191
190
|
|
|
192
191
|
const isKeyPrimitive = typeof t.args[0] == "string" && PrimitiveTypes.some(_ => _ == t.args[0]) || injectedPrimitives?.injectedPrimitives.has(t.args[0] as keyof T)
|
|
@@ -229,24 +228,24 @@ export const fromAPIRawValue = <T>(t: Type, types: Map<TypeName, TypeDefinition>
|
|
|
229
228
|
export const toAPIRawValue = <T>(t: Type, types: Map<TypeName, TypeDefinition>, builtIns: BuiltIns, converters: BuiltInApiConverters, isKeywordsReverted: boolean = false, injectedPrimitives?: InjectedPrimitives<T>) => (raw: any, formState: any) : ValueOrErrors<any, string> => {
|
|
230
229
|
const obj = !isKeywordsReverted ? replaceKeywords(raw, "to api") : raw
|
|
231
230
|
if (t.kind == "primitive") {
|
|
232
|
-
return ValueOrErrors.Operations.
|
|
231
|
+
return ValueOrErrors.Operations.Return(converters[t.value].toAPIRawValue([obj, formState.modifiedByUser] as never))
|
|
233
232
|
} else if (t.kind == "application") { // application here means "generic type application"
|
|
234
233
|
if (t.value == "SingleSelection" && t.args.length == 1) {
|
|
235
234
|
const result = converters[t.value].toAPIRawValue([obj, formState.modifiedByUser])
|
|
236
|
-
if(typeof result != "object") return ValueOrErrors.Operations.
|
|
235
|
+
if(typeof result != "object") return ValueOrErrors.Operations.Return(result)
|
|
237
236
|
|
|
238
237
|
return toAPIRawValue({ kind:"lookup", name:t.args[0] }, types, builtIns, converters, true, injectedPrimitives)(result, formState)
|
|
239
238
|
}
|
|
240
239
|
if ((t.value == "Multiselection" || t.value == "MultiSelection") && t.args.length == 1) {
|
|
241
240
|
const result = converters["MultiSelection"].toAPIRawValue([obj, formState.modifiedByUser])
|
|
242
241
|
|
|
243
|
-
return ValueOrErrors.Operations.
|
|
244
|
-
typeof _ == "object" ? toAPIRawValue({ kind:"lookup", name: t.args[0] }, types, builtIns, converters, true, injectedPrimitives)(_, formState) : ValueOrErrors.Operations.
|
|
242
|
+
return ValueOrErrors.Operations.All(List<ValueOrErrors<any, string>>(result.map((_:any) =>
|
|
243
|
+
typeof _ == "object" ? toAPIRawValue({ kind:"lookup", name: t.args[0] }, types, builtIns, converters, true, injectedPrimitives)(_, formState) : ValueOrErrors.Operations.Return(_))))
|
|
245
244
|
}
|
|
246
245
|
if (t.value == "List" && t.args.length == 1) {
|
|
247
246
|
const converterResult = converters[t.value].toAPIRawValue([obj, formState.modifiedByUser])
|
|
248
247
|
const isPrimitive = PrimitiveTypes.some(_ => _ == t.args[0]) || injectedPrimitives?.injectedPrimitives.has(t.args[0] as keyof T)
|
|
249
|
-
return ValueOrErrors.Operations.
|
|
248
|
+
return ValueOrErrors.Operations.All(List<ValueOrErrors<any, string>>(converterResult.map((item: any, index: number) =>
|
|
250
249
|
toAPIRawValue(
|
|
251
250
|
isPrimitive ?
|
|
252
251
|
{ kind:"primitive", value:t.args[0] as PrimitiveType }
|
|
@@ -256,12 +255,12 @@ export const toAPIRawValue = <T>(t: Type, types: Map<TypeName, TypeDefinition>,
|
|
|
256
255
|
))))
|
|
257
256
|
}
|
|
258
257
|
if (t.value == "Map" && t.args.length == 2) {
|
|
259
|
-
const converterResult = converters[t.value].toAPIRawValue([obj, formState.modifiedByUser])
|
|
258
|
+
const [converterResult, toIdentiferAndDisplayName] = converters[t.value].toAPIRawValue([obj, formState.modifiedByUser])
|
|
260
259
|
const isKeyPrimitive = PrimitiveTypes.some(_ => _ == t.args[0]) || injectedPrimitives?.injectedPrimitives.has(t.args[0] as keyof T)
|
|
261
260
|
const isValuePrimitive = PrimitiveTypes.some(_ => _ == t.args[1]) || injectedPrimitives?.injectedPrimitives.has(t.args[1] as keyof T)
|
|
262
261
|
|
|
263
|
-
const parsedMap: ValueOrErrors<{key: ValueOrErrors<any, any>, value: ValueOrErrors<any, any>}, any
|
|
264
|
-
const
|
|
262
|
+
const parsedMap: List<ValueOrErrors<{key: ValueOrErrors<any, any>, value: ValueOrErrors<any, any>}, any>> = converterResult.map((keyValue: any, index: number) => {
|
|
263
|
+
const possiblyUndefinedKey = toAPIRawValue(
|
|
265
264
|
typeof t.args[0] == "string" ?
|
|
266
265
|
isKeyPrimitive ?
|
|
267
266
|
{ kind: "primitive", value: t.args[0] as PrimitiveType }
|
|
@@ -271,11 +270,12 @@ export const toAPIRawValue = <T>(t: Type, types: Map<TypeName, TypeDefinition>,
|
|
|
271
270
|
types, builtIns, converters, true, injectedPrimitives)(keyValue[0], formState.elementFormStates.get(index).KeyFormState
|
|
272
271
|
)
|
|
273
272
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
273
|
+
const key: ValueOrErrors<any, string> = (() => {
|
|
274
|
+
if(possiblyUndefinedKey.kind == "value" && (possiblyUndefinedKey.value == undefined || possiblyUndefinedKey.value == null || possiblyUndefinedKey.value == "" || (typeof possiblyUndefinedKey.value == "object" && Object.keys(possiblyUndefinedKey.value).length == 0))) {
|
|
275
|
+
return ValueOrErrors.Operations.Throw(List([`A mapped key is undefined for type ${JSON.stringify(t.args[0])}`]))
|
|
276
|
+
}
|
|
277
|
+
return possiblyUndefinedKey
|
|
278
|
+
})()
|
|
279
279
|
|
|
280
280
|
const value = toAPIRawValue(
|
|
281
281
|
typeof t.args[1] == "string" ?
|
|
@@ -286,31 +286,22 @@ export const toAPIRawValue = <T>(t: Type, types: Map<TypeName, TypeDefinition>,
|
|
|
286
286
|
t.args[1],
|
|
287
287
|
types, builtIns, converters, true, injectedPrimitives)(keyValue[1], formState.elementFormStates.get(index).ValueFormState)
|
|
288
288
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
return ValueOrErrors.Operations.return({key, value})
|
|
289
|
+
return key.kind == "errors" || value.kind == "errors" ? ValueOrErrors.Operations.All(List([key, value])) : ValueOrErrors.Default.return({key: key.value, value: value.value})
|
|
292
290
|
}
|
|
293
291
|
)
|
|
294
|
-
|
|
295
|
-
if(parsedMap.length > 0 && parsedMap.some((_: ValueOrErrors<any, any>) => _.kind == "errors")) {
|
|
296
|
-
return ValueOrErrors.Operations.all(List(parsedMap))
|
|
297
|
-
}
|
|
298
|
-
// TODO this needs improvement
|
|
299
|
-
const allKeysStringified = parsedMap.map((_) => _.kind == "value" ? JSON.stringify((_.value.key as any).value) : "")
|
|
300
|
-
const allKeysUnique = Set(allKeysStringified).size == allKeysStringified.length
|
|
301
|
-
|
|
302
|
-
if(allKeysStringified.length > 0 && !allKeysUnique) {
|
|
303
|
-
return ValueOrErrors.Operations.throw(`Keys in the map are not unique: ${JSON.stringify(allKeysStringified)}`)
|
|
304
|
-
}
|
|
305
292
|
|
|
306
|
-
|
|
307
|
-
|
|
293
|
+
const nonUniqueKeyErrors = parsedMap.filter(_ => _.kind == "value").reduce((acc, _) => {
|
|
294
|
+
const [id, displayName] = toIdentiferAndDisplayName(_.value.key)
|
|
295
|
+
acc.ids.contains(id) ? acc.errors = acc.errors.push(ValueOrErrors.Default.throw(List([`Keys in the map are not unique: ${displayName}`]))) : acc.ids = acc.ids.push(id)
|
|
296
|
+
return acc
|
|
297
|
+
}, {ids: List<string>(), errors: List<ValueOrErrors<any, string>>()}).errors
|
|
308
298
|
|
|
299
|
+
return ValueOrErrors.Operations.All(parsedMap.concat(nonUniqueKeyErrors))
|
|
309
300
|
}
|
|
310
301
|
} else { // t.kind == lookup: we are dealing with a record/object or extended type
|
|
311
302
|
const tDef = types.get(t.name)!
|
|
312
303
|
if("extends" in tDef && tDef.extends.length == 1) {
|
|
313
|
-
return ValueOrErrors.Operations.
|
|
304
|
+
return ValueOrErrors.Operations.Return(converters[(tDef.extends[0] as keyof BuiltInApiConverters)].toAPIRawValue([obj, formState.modifiedByUser] as never))
|
|
314
305
|
}
|
|
315
306
|
const convertedMap = tDef.fields.mapEntries(([fieldName, fieldType] ) => {
|
|
316
307
|
const revertedFieldName = revertKeyword(fieldName)
|
|
@@ -320,10 +311,10 @@ export const toAPIRawValue = <T>(t: Type, types: Map<TypeName, TypeDefinition>,
|
|
|
320
311
|
})
|
|
321
312
|
if(convertedMap.some((valueOrError) => valueOrError.kind == "errors")) {
|
|
322
313
|
const propertiesWithErrors = convertedMap.filter((valueOrError) => valueOrError.kind == "errors")
|
|
323
|
-
const namedErrors = propertiesWithErrors.map((value, key) => value.
|
|
324
|
-
return ValueOrErrors.Operations.
|
|
314
|
+
const namedErrors = propertiesWithErrors.map((value, key) => value.MapErrors(_ => _.map((_: string) => `${key}: ${_}`)))
|
|
315
|
+
return ValueOrErrors.Operations.All(List<ValueOrErrors<any, string>>(namedErrors.valueSeq().toList()))
|
|
325
316
|
}
|
|
326
|
-
return ValueOrErrors.Operations.
|
|
317
|
+
return ValueOrErrors.Operations.Return(convertedMap.map(valueOrError => valueOrError.kind == "value" ? valueOrError.value : valueOrError.errors).toJS())
|
|
327
318
|
}
|
|
328
|
-
return ValueOrErrors.Operations.
|
|
319
|
+
return ValueOrErrors.Operations.Return(defaultValue(types, builtIns, injectedPrimitives)(t.value))
|
|
329
320
|
}
|
|
@@ -161,7 +161,6 @@ export const FormsConfig = {
|
|
|
161
161
|
errors = errors.push(`type ${typeName} extends non-existent type ${extendedTypeName}`);
|
|
162
162
|
});
|
|
163
163
|
typeDef.fields.forEach((fieldDef, fieldName) => {
|
|
164
|
-
// TODO - check application args are a valid type (-refs, primtives, lookups, possible here? or may have to do at end) also no undefined
|
|
165
164
|
if (fieldDef.kind == "primitive" && (!builtIns.primitives.has(fieldDef.value) && !injectedPrimitives?.injectedPrimitives.has(fieldDef.value as keyof T) ))
|
|
166
165
|
errors = errors.push(`field ${fieldName} of type ${typeName} is non-existent primitive type ${fieldDef.value}`);
|
|
167
166
|
if (fieldDef.kind == "lookup" && !types.has(fieldDef.name))
|
|
@@ -570,8 +569,6 @@ export const FormsConfig = {
|
|
|
570
569
|
return
|
|
571
570
|
}
|
|
572
571
|
const launcherKind = formsConfig["launchers"][launcherName]["kind"] as Launcher["kind"] | MappingLauncher["kind"]
|
|
573
|
-
console.log(formsConfig["launchers"][launcherName]["form"])
|
|
574
|
-
console.log(forms.keySeq().toArray());
|
|
575
572
|
if (forms.has(formsConfig["launchers"][launcherName]["form"]) == false) {
|
|
576
573
|
errors = errors.push(`launcher '${launcherName}' references non-existing form '${formsConfig.launchers[launcherName].form}'`);
|
|
577
574
|
return
|
|
@@ -209,7 +209,7 @@ export const ParseForm = <T,>(
|
|
|
209
209
|
.mapContext<any>(_ => ({ ..._, label, tooltip }))
|
|
210
210
|
} else { // the list argument is a primitive
|
|
211
211
|
const elementForm = FieldView(fieldConfig, fieldViews, fieldNameToElementViewCategory(formFieldElementRenderers)(fieldName) as any, elementRendererName, elementLabel, elementTooltip, EnumOptionsSources, fieldsOptionsConfig, leafPredicates, injectedPrimitives)
|
|
212
|
-
const initialFormState = FieldFormState(fieldConfig, fieldViews, fieldNameToElementViewCategory(formFieldElementRenderers)(fieldName) as any, elementRendererName, InfiniteStreamSources, fieldsInfiniteStreamsConfig, injectedPrimitives);
|
|
212
|
+
const initialFormState = FieldFormState(fieldConfig, fieldViews, fieldNameToElementViewCategory(formFieldElementRenderers)(fieldName) as any, elementRendererName, fieldName, InfiniteStreamSources, fieldsInfiniteStreamsConfig, injectedPrimitives);
|
|
213
213
|
formConfig[fieldName] = ListForm<any, any, any & FormLabel, Unit>(
|
|
214
214
|
{ Default: () => initialFormState },
|
|
215
215
|
{ Default: () => initialElementValue },
|
|
@@ -305,7 +305,7 @@ export type EditLauncherContext<Entity, FormState, ExtraContext> =
|
|
|
305
305
|
extraContext: ExtraContext,
|
|
306
306
|
containerFormView: any,
|
|
307
307
|
submitButtonWrapper: any
|
|
308
|
-
}, "api" | "actualForm">
|
|
308
|
+
}, "api" | "parser" | "actualForm">
|
|
309
309
|
|
|
310
310
|
export type CreateLauncherContext<Entity, FormState, ExtraContext> =
|
|
311
311
|
Omit<
|
|
@@ -477,9 +477,8 @@ export const parseForms =
|
|
|
477
477
|
get: (id: string) => entityApis.get(launcher.api)(id).then((raw: any) => {
|
|
478
478
|
return fromAPIRawValue({ kind: "lookup", name: parsedForm.formDef.type }, formsConfig.types, builtIns, apiConverters, false, injectedPrimitives)(raw)
|
|
479
479
|
}),
|
|
480
|
-
update: (id:
|
|
481
|
-
|
|
482
|
-
return raw.kind == "errors" ? Promise.reject(raw.errors) : entityApis.update(launcher.api)(id, raw.value)
|
|
480
|
+
update: (id: any, parsed: any) => {
|
|
481
|
+
return entityApis.update(launcher.api)(id, parsed)
|
|
483
482
|
}
|
|
484
483
|
}
|
|
485
484
|
parsedLaunchers.edit = parsedLaunchers.edit.set(
|
|
@@ -489,6 +488,7 @@ export const parseForms =
|
|
|
489
488
|
({
|
|
490
489
|
...parentContext,
|
|
491
490
|
api: api,
|
|
491
|
+
parser: (value: any, formState: any) => toAPIRawValue({ kind: "lookup", name: parsedForm.formDef.type }, formsConfig.types, builtIns, apiConverters, false, injectedPrimitives)(value, formState),
|
|
492
492
|
actualForm: form.withView(containerFormView).mapContext((_: any) => ({ ..._, rootValue: _.value, ...parentContext.extraContext }))
|
|
493
493
|
}) as any)
|
|
494
494
|
.withViewFromProps(props => props.context.submitButtonWrapper)
|
|
@@ -8,44 +8,44 @@ import { ListFieldState, ListFieldView } from "./state";
|
|
|
8
8
|
|
|
9
9
|
export const ListForm = <Element, ElementFormState, Context extends FormLabel, ForeignMutationsExpected>(
|
|
10
10
|
ElementFormState: { Default: () => ElementFormState },
|
|
11
|
-
Element: { Default: () => Element },
|
|
11
|
+
Element: { Default: () => Element | undefined},
|
|
12
12
|
elementTemplate: Template<
|
|
13
|
-
Context & Value<Element> & ElementFormState,
|
|
13
|
+
Context & Value<Element | undefined> & ElementFormState,
|
|
14
14
|
ElementFormState,
|
|
15
15
|
ForeignMutationsExpected & {
|
|
16
|
-
onChange: OnChange<Element>;
|
|
16
|
+
onChange: OnChange<Element | undefined>;
|
|
17
17
|
}>,
|
|
18
|
-
validation?: BasicFun<List<Element>, Promise<FieldValidation>>,
|
|
18
|
+
validation?: BasicFun<List<Element | undefined>, Promise<FieldValidation>>,
|
|
19
19
|
) => {
|
|
20
20
|
const embeddedElementTemplate = (elementIndex:number) =>
|
|
21
21
|
elementTemplate
|
|
22
22
|
.mapForeignMutationsFromProps<ForeignMutationsExpected & {
|
|
23
|
-
onChange: OnChange<List<Element>>;
|
|
23
|
+
onChange: OnChange<List<Element| undefined>>;
|
|
24
24
|
add: SimpleCallback<Unit>;
|
|
25
|
-
remove: SimpleCallback<number>;}>((props): ForeignMutationsExpected & {onChange: OnChange<Element>} => ({
|
|
25
|
+
remove: SimpleCallback<number>;}>((props): ForeignMutationsExpected & {onChange: OnChange<Element | undefined>} => ({
|
|
26
26
|
...props.foreignMutations,
|
|
27
27
|
onChange: (elementUpdater, path) => {
|
|
28
|
-
props.foreignMutations.onChange(Updater((elements:List<Element>) =>
|
|
29
|
-
elements.
|
|
28
|
+
props.foreignMutations.onChange(Updater((elements:List<Element | undefined>) =>
|
|
29
|
+
elements.has(elementIndex) ? elements.update(elementIndex, undefined, elementUpdater) : elements), path)
|
|
30
30
|
props.setState(_ => ({..._,
|
|
31
31
|
modifiedByUser:true,
|
|
32
32
|
})) },
|
|
33
33
|
add: (newElement: Element) => { },
|
|
34
34
|
remove: (elementIndex: number) => { }
|
|
35
35
|
}))
|
|
36
|
-
.mapContext((_: Context & Value<List<Element>> & ListFieldState<Element, ElementFormState>) : (Context & Value<Element> & ElementFormState) | undefined => {
|
|
36
|
+
.mapContext((_: Context & Value<List<Element | undefined>> & ListFieldState<Element | undefined, ElementFormState>) : (Context & Value<Element | undefined> & ElementFormState) | undefined => {
|
|
37
|
+
if(!_.value.has(elementIndex)) return undefined
|
|
37
38
|
const element = _.value.get(elementIndex)
|
|
38
|
-
if (element == undefined) return undefined
|
|
39
39
|
const elementFormState = _.elementFormStates.get(elementIndex) || ElementFormState.Default()
|
|
40
|
-
const elementContext : Context & Value<Element> & ElementFormState = ({ ..._, ...elementFormState, value: element })
|
|
40
|
+
const elementContext : Context & Value<Element | undefined> & ElementFormState = ({ ..._, ...elementFormState, value: element })
|
|
41
41
|
return elementContext
|
|
42
42
|
})
|
|
43
|
-
.mapState((_:BasicUpdater<ElementFormState>) : Updater<ListFieldState<Element, ElementFormState>> =>
|
|
44
|
-
ListFieldState<Element, ElementFormState>().Updaters.Core.elementFormStates(
|
|
43
|
+
.mapState((_:BasicUpdater<ElementFormState>) : Updater<ListFieldState<Element | undefined, ElementFormState>> =>
|
|
44
|
+
ListFieldState<Element | undefined, ElementFormState>().Updaters.Core.elementFormStates(
|
|
45
45
|
MapRepo.Updaters.upsert(elementIndex, () => ElementFormState.Default(), _)
|
|
46
46
|
))
|
|
47
|
-
return Template.Default<Context & Value<List<Element>> & { disabled: boolean }, ListFieldState<Element, ElementFormState>, ForeignMutationsExpected & { onChange: OnChange<List<Element>>; },
|
|
48
|
-
ListFieldView<Element, ElementFormState, Context, ForeignMutationsExpected>>(props => <>
|
|
47
|
+
return Template.Default<Context & Value<List<Element | undefined>> & { disabled: boolean }, ListFieldState<Element | undefined, ElementFormState>, ForeignMutationsExpected & { onChange: OnChange<List<Element | undefined>>; },
|
|
48
|
+
ListFieldView<Element | undefined, ElementFormState, Context, ForeignMutationsExpected>>(props => <>
|
|
49
49
|
<props.view {...props}
|
|
50
50
|
context={{
|
|
51
51
|
...props.context,
|
|
@@ -54,7 +54,7 @@ export const ListForm = <Element, ElementFormState, Context extends FormLabel, F
|
|
|
54
54
|
...props.foreignMutations,
|
|
55
55
|
add: (_) => {
|
|
56
56
|
props.foreignMutations.onChange(
|
|
57
|
-
ListRepo.Updaters.push(Element.Default()), List()
|
|
57
|
+
ListRepo.Updaters.push<Element | undefined>(Element.Default()), List()
|
|
58
58
|
)
|
|
59
59
|
},
|
|
60
60
|
remove: (_) => {
|
|
@@ -67,7 +67,7 @@ export const ListForm = <Element, ElementFormState, Context extends FormLabel, F
|
|
|
67
67
|
/>
|
|
68
68
|
</>
|
|
69
69
|
).any([
|
|
70
|
-
ValidateRunner<Context & { disabled: boolean }, ListFieldState<Element, ElementFormState>, ForeignMutationsExpected, List<Element>>(
|
|
70
|
+
ValidateRunner<Context & { disabled: boolean }, ListFieldState<Element | undefined, ElementFormState>, ForeignMutationsExpected, List<Element | undefined>>(
|
|
71
71
|
validation ? _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation) : undefined
|
|
72
72
|
),
|
|
73
73
|
]);
|