ballerina-core 1.0.61 → 1.0.62

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 CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "ballerina-core",
3
3
  "author": "Dr. Giuseppe Maggiore",
4
4
  "private": false,
5
- "version": "1.0.61",
5
+ "version": "1.0.62",
6
6
  "main": "main.ts",
7
7
  "dependencies": {
8
8
  "immutable": "^5.0.0-beta.5",
@@ -1,5 +1,5 @@
1
- import { Sum } from "../../../../../../main";
1
+ import { Sum, Value } from "../../../../../../main";
2
2
  import { CollectionReference } from "../reference/state"
3
3
 
4
- export type CollectionSelection<Element extends CollectionReference> = Sum<Element, "no selection">;
5
- export const CollectionSelection = <Element extends CollectionReference>() => Sum<Element, "no selection">();
4
+ export type CollectionSelection<Element extends CollectionReference | Value<CollectionReference>> = Sum<Element, "no selection">;
5
+ export const CollectionSelection = <Element extends CollectionReference | Value<CollectionReference>>() => Sum<Element, "no selection">();
@@ -1,4 +1,4 @@
1
- import { Map, List, Set, OrderedMap, is } from "immutable"
1
+ 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";
@@ -6,12 +6,13 @@ import { InjectedPrimitives, Maybe, ParsedType, TypeName } from "../../../../../
6
6
  import { ValueOrErrors } from "../../../../../collections/domains/valueOrErrors/state";
7
7
 
8
8
  export const PrimitiveTypes =
9
- ["string",
9
+ [
10
+ "guid", //resolves to string
11
+ "string",
10
12
  "number",
11
13
  "boolean",
12
14
  "maybeBoolean",
13
15
  "Date",
14
- "CollectionReference",
15
16
  "base64File",
16
17
  "secret",
17
18
  ] as const
@@ -21,7 +22,9 @@ export const GenericTypes = [
21
22
  "SingleSelection",
22
23
  "MultiSelection",
23
24
  "List",
24
- "Map"] as const
25
+ "Map",
26
+ "Union"
27
+ ] as const
25
28
  export type GenericType = (typeof GenericTypes)[number]
26
29
 
27
30
  export type ApiConverter<T> = { fromAPIRawValue: BasicFun<any, T>, toAPIRawValue: BasicFun<[T, boolean], any> }
@@ -35,7 +38,6 @@ export type BuiltInApiConverters = {
35
38
  "base64File": ApiConverter<string>
36
39
  "secret": ApiConverter<string>
37
40
  "Date": ApiConverter<Maybe<Date>>
38
- "CollectionReference": ApiConverter<CollectionReference>
39
41
  "SingleSelection": ApiConverter<CollectionSelection<any>>
40
42
  "MultiSelection": ApiConverter<OrderedMap<string, any>>
41
43
  "List": ApiConverter<List<any>>,
@@ -73,7 +75,6 @@ export const builtInsFromFieldViews = (fieldViews: any): BuiltIns => {
73
75
  ["maybeBoolean", { renderers: Set(["maybeBoolean"]), defaultValue: undefined }] as [string, PrimitiveBuiltIn],
74
76
  ["date", { renderers: Set(["date"]), defaultValue: undefined }] as [string, PrimitiveBuiltIn],
75
77
  ["Date", { renderers: Set(["date"]), defaultValue: undefined }] as [string, PrimitiveBuiltIn],
76
- ["CollectionReference", { renderers: Set(["enumSingleSelection", "enumMultiSelection", "streamSingleSelection", "streamMultiSelection"]), defaultValue: CollectionReference.Default("", "") }] as [string, PrimitiveBuiltIn],
77
78
  ["base64File", { renderers: Set(["base64File"]), defaultValue: "" }] as [string, PrimitiveBuiltIn],
78
79
  ["secret", { renderers: Set(["secret"]), defaultValue: "" }] as [string, PrimitiveBuiltIn],
79
80
  ]),
@@ -81,7 +82,8 @@ export const builtInsFromFieldViews = (fieldViews: any): BuiltIns => {
81
82
  ["SingleSelection", { defaultValue: CollectionSelection().Default.right("no selection") }] as [string, GenericBuiltIn],
82
83
  ["MultiSelection", { defaultValue: Map() }] as [string, GenericBuiltIn],
83
84
  ["List", { defaultValue: List() }] as [string, GenericBuiltIn],
84
- ["Map", { defaultValue: List() }] as [string, GenericBuiltIn]
85
+ ["Map", { defaultValue: List() }] as [string, GenericBuiltIn],
86
+ ["Union", { defaultValue: Map() }] as [string, GenericBuiltIn],
85
87
  ]),
86
88
  "renderers": {
87
89
  "boolean": Set(),
@@ -147,6 +149,9 @@ export const fromAPIRawValue = <T extends { [key in keyof T]: { type: any; state
147
149
  if (t.kind == "primitive") {
148
150
  return converters[t.value].fromAPIRawValue(raw)
149
151
  }
152
+ if(t.kind == "union") {
153
+ return CollectionReference.Default(raw, raw, "enum")
154
+ }
150
155
  if (t.kind == "application") {
151
156
  if (t.value == "SingleSelection") {
152
157
  return CollectionSelection().Updaters.left(
@@ -191,7 +196,9 @@ export const fromAPIRawValue = <T extends { [key in keyof T]: { type: any; state
191
196
  export const toAPIRawValue = <T extends { [key in keyof T]: { type: any; state: any; }}>(t: ParsedType<T>, types: Map<TypeName, ParsedType<T>>, builtIns: BuiltIns, converters: ApiConverters<T>, injectedPrimitives?: InjectedPrimitives<T>) => (raw: any, formState: any) : ValueOrErrors<any, string> => {
192
197
  if (t.kind == "primitive")
193
198
  return ValueOrErrors.Operations.Return(converters[t.value as string | keyof T].toAPIRawValue([raw, formState.modifiedByUser]))
194
-
199
+ if(t.kind == "union"){
200
+ return ValueOrErrors.Operations.Return(raw.id)
201
+ }
195
202
  if (t.kind == "application") {
196
203
  if (t.value == "SingleSelection") {
197
204
  const result = converters[t.value].toAPIRawValue([raw, formState.modifiedByUser])
@@ -1,5 +1,5 @@
1
1
  import { List, Map, OrderedMap, Set } from "immutable";
2
- import { Base64FileForm, BaseEnumContext, BasicFun, BooleanForm, BoolExpr, CollectionReference, CollectionSelection, CommonFormState, DateForm, DateFormState, EnumForm, EnumFormState, EnumMultiselectForm, EnumOptionsSources, FormLabel, Guid, InfiniteMultiselectDropdownForm, InjectedPrimitives, ListFieldState, ListForm, MapFieldState, MapForm, Maybe, MaybeBooleanForm, NumberForm, ParsedForms, ParsedType, SearchableInfiniteStreamForm, SearchableInfiniteStreamState, SecretForm, StringForm, Template, Unit, Value } from "../../../../../../main";
2
+ import { Base64FileForm, BaseEnumContext, BasicFun, BasicPredicate, BooleanForm, BoolExpr, CollectionReference, CollectionSelection, CommonFormState, DateForm, DateFormState, EnumForm, EnumFormState, EnumMultiselectForm, EnumOptionsSources, FormLabel, Guid, InfiniteMultiselectDropdownForm, InjectedPrimitives, ListFieldState, ListForm, MapFieldState, MapForm, Maybe, MaybeBooleanForm, NumberForm, OrderedMapRepo, ParsedForms, ParsedType, SearchableInfiniteStreamForm, SearchableInfiniteStreamState, SecretForm, StringForm, Template, Unit, Value } from "../../../../../../main";
3
3
  import { ValueOrErrors } from "../../../../../collections/domains/valueOrErrors/state";
4
4
 
5
5
  type Form = {
@@ -128,11 +128,6 @@ export const ParsedRenderer = {
128
128
  console.error(`Invalid field type ${JSON.stringify(fieldType)} for field ${JSON.stringify(field)}`)
129
129
  throw new Error("Invalid field type")
130
130
  },
131
- ParseOptions: (leafPredicates: any, options: any) => {
132
- const result = options.map((_: any) => ([_[0].id, [_[0], (_[1] as BoolExpr<any>).eval<any>(leafPredicates)]]));
133
- const resultMap = result.reduce((a: any, b: any) => a.set(b[0], b[1]), OrderedMap<any, any>());
134
- return resultMap;
135
- },
136
131
  FormViewToViewKind: (viewName: string | undefined, formViews: Record<string, any>, formNames: Set<string>) => {
137
132
  if (viewName == undefined) {
138
133
  throw Error(`cannot resolve view ${viewName}`) // TODO -- better error handling
@@ -223,18 +218,18 @@ export const ParsedRenderer = {
223
218
  .withView(formViews[viewKind][viewName]())
224
219
  .mapContext<any & CommonFormState & Value<string>>(_ => ({ ..._, label: label, tooltip }))
225
220
  if (viewKind == "enumSingleSelection" && rendererConfig.kind == "enum")
226
- return EnumForm<any & FormLabel & BaseEnumContext<any, CollectionReference>, Unit, CollectionReference>()
221
+ return EnumForm<any & FormLabel & BaseEnumContext<Value<CollectionReference>>, Unit, Value<CollectionReference>>()
227
222
  .withView(formViews[viewKind][viewName]())
228
- .mapContext<any & EnumFormState<any & BaseEnumContext<any, CollectionReference>, CollectionReference> & Value<CollectionSelection<CollectionReference>>>(_ => ({
223
+ .mapContext<any & EnumFormState<any & BaseEnumContext<Value<CollectionReference>>, Value<CollectionReference>> & Value<CollectionSelection<Value<CollectionReference>>>>(_ => ({
229
224
  ..._, label: label, tooltip, getOptions: () => {
230
- return ((enumOptionsSources as any)(rendererConfig.options)() as Promise<any>).then(options => ParsedRenderer.Operations.ParseOptions(leafPredicates, options))
225
+ return ((enumOptionsSources as any)(rendererConfig.options)() as Promise<any>).then(options => Map(options.map((o: {value: CollectionReference}) => [o.value.id, o])))
231
226
  }
232
227
  }))
233
228
  if (viewKind == "enumMultiSelection" && rendererConfig.kind == "enum")
234
- return EnumMultiselectForm<any & FormLabel & BaseEnumContext<any, CollectionReference>, Unit, CollectionReference>()
229
+ return EnumMultiselectForm<any & FormLabel & BaseEnumContext<Value<CollectionReference>>, Unit, Value<CollectionReference>>()
235
230
  .withView(formViews[viewKind][viewName]() )
236
- .mapContext<any & EnumFormState<any & BaseEnumContext<any, CollectionReference>, CollectionReference> & Value<OrderedMap<Guid, CollectionReference>>>(_ => ({
237
- ..._, label: label, tooltip, getOptions: () => ((enumOptionsSources as any)(rendererConfig.options)() as Promise<any>).then(options => ParsedRenderer.Operations.ParseOptions(leafPredicates, options))
231
+ .mapContext<any & EnumFormState<any & BaseEnumContext<Value<CollectionReference>>, Value<CollectionReference>> & Value<OrderedMap<Guid, CollectionReference>>>(_ => ({
232
+ ..._, label: label, tooltip, getOptions: () => ((enumOptionsSources as any)(rendererConfig.options)() as Promise<any>).then(options => OrderedMap(options.map((o: {value: CollectionReference}) => [o.value.id, o])))
238
233
  }))
239
234
  if (viewKind == "streamSingleSelection")
240
235
  return SearchableInfiniteStreamForm<CollectionReference, any & FormLabel, Unit>()
@@ -2,12 +2,14 @@ import { Set, List, Map, OrderedMap } from "immutable";
2
2
  import { GenericType, GenericTypes, PrimitiveTypes } from "../built-ins/state";
3
3
  import { InjectedPrimitives } from "../injectables/state";
4
4
  import { ValueOrErrors } from "../../../../../collections/domains/valueOrErrors/state";
5
+ import { Value } from "../../../../../value/state";
5
6
 
6
7
  export const isString = (_: any): _ is string => typeof _ == "string"
7
8
  export const isObject = (_: any): _ is Object => typeof _ == "object"
8
9
  export const isGenericType = (_: any): _ is GenericType => _ && GenericTypes.includes(_)
9
10
  export const hasFun = (_: any): _ is { fun: string } => isObject(_) && "fun" in _ && isString(_.fun)
10
11
  export const hasArgs = (_: any): _ is { args: Array<any> } => isObject(_) && "args" in _ && Array.isArray(_.args)
12
+ export type CaseName = string;
11
13
  export type FieldName = string;
12
14
  export type TypeName = string;
13
15
  export type RawType<T> = {
@@ -18,13 +20,26 @@ export const RawType = {
18
20
  isMaybeExtendedType: <T>(type: RawType<T>): type is RawType<T> & {extends: unknown} => "extends" in type,
19
21
  isExtendedType: <T>(type: RawType<T>): type is RawType<T> & {extends: Array<TypeName>} => "extends" in type && Array.isArray(type.extends) && type.extends.length == 1 && (isString(type.extends[0])) ,
20
22
  hasFields: <T>(type: RawType<T>): type is {fields: any} => "fields" in type,
23
+ isMaybeUnion: (_: any): _ is RawUnionType => isObject(_) && "fun" in _ && "args" in _ && _.fun == "Union" && Array.isArray(_["args"]) && _["args"].every(__ => typeof __ == "object" && "case" in __ && "fields" in __),
21
24
  }
22
25
  export type RawApplicationType<T> = {
23
26
  fun?: GenericType;
24
27
  args?: Array<RawFieldType<T>>;
25
28
  }
26
29
 
27
- export type RawFieldType<T> = RawApplicationType<T> | string | PrimitiveTypeName<T>
30
+ export type RawUnionCase = {
31
+ case?: string;
32
+ fields?: Object;
33
+ }
34
+
35
+ export type RawUnionType = {
36
+ fun?: "Union";
37
+ args?: Array<RawUnionCase>;
38
+ }
39
+
40
+ export type RawFormType = {fields?: Object}
41
+
42
+ export type RawFieldType<T> = RawApplicationType<T> | string | PrimitiveTypeName<T> | RawUnionType | RawFormType | RawUnionCase;
28
43
  export const RawFieldType = {
29
44
  isMaybePrimitive: (_: any) => isString(_),
30
45
  isPrimitive: <T>(_: RawFieldType<T>, injectedPrimitives: InjectedPrimitives<T> | undefined): _ is PrimitiveTypeName<T> => Boolean(PrimitiveTypes.some(__ => _ == __) || injectedPrimitives?.injectedPrimitives.has(_ as keyof T)),
@@ -36,24 +51,32 @@ export const RawFieldType = {
36
51
  isMap: <T>(_: RawFieldType<T>): _ is {fun: "Map", args: Array<RawFieldType<T>>} => RawFieldType.isApplication(_) && _.fun == "Map" && _.args.length == 2,
37
52
  isSingleSelection: <T>(_: RawFieldType<T>): _ is {fun: "SingleSelection", args: Array<RawFieldType<T>>} => RawFieldType.isApplication(_) && _.fun == "SingleSelection" && _.args.length == 1,
38
53
  isMultiSelection: <T>(_: RawFieldType<T>): _ is {fun: "MultiSelection", args: Array<RawFieldType<T>>} => RawFieldType.isApplication(_) && _.fun == "MultiSelection" && _.args.length == 1,
54
+ isUnionCase: <T>(_: RawFieldType<T>): _ is {case: string, fields: object} => typeof _ == "object" && "case" in _ && "fields" in _,
55
+ isUnion: <T>(_: RawFieldType<T>): _ is {fun: "Union", args: Array<{case: string, fields: object}>} => hasFun(_) && isGenericType(_.fun) && hasArgs(_) && _.fun == "Union" && _.args.length > 1 && _.args.every(__ => typeof __ == "object" && "case" in __ && "fields" in __),
56
+ isForm: <T>(_: RawFieldType<T>): _ is {fields: Object} => typeof _ == "object" && "fields" in _ && isObject(_.fields),
39
57
  }
40
58
 
41
- export type PrimitiveTypeName<T> = "string" | "number" | "maybeBoolean" | "boolean" | "Date" | "CollectionReference" | "base64File" | "secret" | keyof T;
59
+ export type PrimitiveTypeName<T> = "string" | "number" | "maybeBoolean" | "boolean" | "Date" | "base64File" | "secret" | keyof T | "guid";
60
+ export type FormFields<T> = Map<FieldName, ParsedType<T>>
42
61
  export type ParsedType<T> =
43
- | { kind: "form"; value: TypeName; fields: Map<FieldName, ParsedType<T>> }
62
+ | { kind: "unionCase", name: CaseName, fields: ParsedType<T> }
63
+ | { kind: "form"; value: TypeName; fields: FormFields<T> }
44
64
  | { kind: "lookup"; name: TypeName; }
45
- | { kind: "primitive"; value: PrimitiveTypeName<T>}
46
- | { kind: "application"; value: GenericType; args: Array<ParsedType<T>>;
47
- };
65
+ | { kind: "primitive"; value: PrimitiveTypeName<T> ;}
66
+ | { kind: "application"; value: GenericType; args: Array<ParsedType<T>>; }
67
+ | { kind: "union"; args: Map<CaseName, ParsedType<T>> }
48
68
 
49
69
  export const ParsedType = {
50
70
  Default: {
51
- form: <T>(value: TypeName, fields: Map<FieldName, ParsedType<T>>): ParsedType<T> => ({ kind: "form", value, fields }),
71
+ unionCase: <T>(name: CaseName, fields: ParsedType<T>): ParsedType<T> => ({ kind: "unionCase", name, fields }),
72
+ form: <T>(value: TypeName, fields: FormFields<T>): ParsedType<T> => ({ kind: "form", value, fields }),
52
73
  primitive: <T>(name: PrimitiveTypeName<T> | keyof T): ParsedType<T> => ({ kind: "primitive", value: name }),
53
74
  application: <T>(value: GenericType, args: Array<ParsedType<T>>): ParsedType<T> => ({ kind: "application", value, args }),
75
+ union: <T>(args: Map<CaseName, ParsedType<T>>): ParsedType<T> => ({ kind: "union", args }),
54
76
  lookup: <T>(name: string): ParsedType<T> => ({ kind: "lookup", name }),
55
77
  },
56
78
  Operations: {
79
+ //TODO: Add cases
57
80
  Equals: <T>(fst: ParsedType<T>, snd: ParsedType<T>): boolean =>
58
81
  fst.kind == "form" && snd.kind == "form" ? fst.value == snd.value :
59
82
  fst.kind == "lookup" && snd.kind == "lookup" ? fst.name == snd.name :
@@ -65,9 +88,8 @@ export const ParsedType = {
65
88
  false,
66
89
 
67
90
  ParseRawFieldType: <T>(fieldName: TypeName, rawFieldType: RawFieldType<T>, types: Set<TypeName>, injectedPrimitives?: InjectedPrimitives<T>) : ValueOrErrors<ParsedType<T>, string> => {
68
-
69
91
  if (RawFieldType.isPrimitive(rawFieldType, injectedPrimitives))
70
- return ValueOrErrors.Default.return(ParsedType.Default.primitive(rawFieldType))
92
+ return ValueOrErrors.Default.return(ParsedType.Default.primitive(rawFieldType == "guid" ? "string" : rawFieldType))
71
93
  if (RawFieldType.isSingleSelection(rawFieldType))
72
94
  return ParsedType.Operations.ParseRawFieldType(fieldName, rawFieldType.args[0], types, injectedPrimitives).Then(parsedArgs =>
73
95
  ValueOrErrors.Default.return(ParsedType.Default.application("SingleSelection", [parsedArgs]))
@@ -86,9 +108,25 @@ export const ParsedType = {
86
108
  ValueOrErrors.Default.return(ParsedType.Default.application("Map", [parsedArgs0, parsedArgs1]))
87
109
  )
88
110
  )
111
+ if(RawFieldType.isForm(rawFieldType))
112
+ return ValueOrErrors.Operations
113
+ .All(List(Object.entries(rawFieldType.fields).map(([fieldName, fieldType]) => ParsedType.Operations.ParseRawFieldType(fieldName, fieldType as RawFieldType<T>, types, injectedPrimitives)
114
+ .Then(parsedField => ValueOrErrors.Default.return([fieldName, parsedField] as const))
115
+ )))
116
+ .Then(parsedFields => ValueOrErrors.Default.return(Map(parsedFields.map(([fieldName, parsedField]) => [fieldName, parsedField]))))
117
+ .Then(parsedField => ValueOrErrors.Default.return<ParsedType<T>, string>(ParsedType.Default.form(fieldName, parsedField)))
118
+ if(RawFieldType.isUnionCase(rawFieldType))
119
+ return ParsedType.Operations.ParseRawFieldType(rawFieldType.case, rawFieldType.fields, types, injectedPrimitives).Then(parsedFields =>
120
+ ValueOrErrors.Default.return(ParsedType.Default.unionCase(rawFieldType.case, parsedFields))
121
+ )
122
+ if(RawFieldType.isUnion(rawFieldType))
123
+ return ValueOrErrors.Operations.All(List(
124
+ rawFieldType.args.map(_ => ParsedType.Operations.ParseRawFieldType(_.case, _, types, injectedPrimitives).Map(parsedFields => ({name: _.case, fields: parsedFields})))))
125
+ .Then(parsedFields => ValueOrErrors.Default.return(ParsedType.Default.union(Map(parsedFields.toArray().map(_ => [_.name, _.fields] as const)))))
126
+
89
127
  if(RawFieldType.isLookup(rawFieldType, types))
90
128
  return ValueOrErrors.Default.return(ParsedType.Default.lookup(rawFieldType))
91
129
  return ValueOrErrors.Default.throw(List([`Invalid type ${JSON.stringify(rawFieldType)} for field ${JSON.stringify(fieldName)}`]))
92
130
  }
93
131
  }
94
- }
132
+ }
@@ -94,8 +94,17 @@ export const FormsConfig = {
94
94
  let parsedTypes: Map<TypeName, ParsedType<T>> = Map();
95
95
  const rawTypesFromConfig = formsConfig.types;
96
96
  const rawTypeNames = Set(Object.keys(rawTypesFromConfig))
97
- Object.entries(formsConfig.types).forEach(([rawTypeName, rawType]) => {
97
+ Object.entries(rawTypesFromConfig).forEach(([rawTypeName, rawType]) => {
98
98
  const parsedType: ParsedType<T> = { kind: "form", value: rawTypeName, fields: Map() };
99
+ if (RawFieldType.isUnion(rawType)){
100
+ const parsingResult = ParsedType.Operations.ParseRawFieldType(rawTypeName, rawType, rawTypeNames, injectedPrimitives)
101
+ if(parsingResult.kind == "errors"){
102
+ errors = errors.concat(parsingResult.errors.toArray());
103
+ return;
104
+ }
105
+ parsedTypes = parsedTypes.set(rawTypeName, parsingResult.value)
106
+ return
107
+ }
99
108
 
100
109
  if (!RawType.hasFields(rawType)){
101
110
  errors = errors.push(`missing 'fields' in type ${rawTypeName}: expected object`);
@@ -136,6 +145,7 @@ export const FormsConfig = {
136
145
  enums = enums.set(enumOptionName, enumOption)
137
146
  )
138
147
 
148
+
139
149
  let streams: Map<string, TypeName> = Map();
140
150
  Object.entries(formsConfig.apis.searchableStreams).forEach(([searchableStreamName, searchableStream]) =>
141
151
  streams = streams.set(searchableStreamName, searchableStream)
@@ -193,6 +203,7 @@ export const FormsConfig = {
193
203
  forms = forms.set(formName, parsedForm);
194
204
  })
195
205
 
206
+
196
207
  let launchers: ParsedFormJSON<T>["launchers"] = {
197
208
  create: Map<string, Launcher>(),
198
209
  edit: Map<string, Launcher>(),
@@ -121,7 +121,7 @@ export type EntityApis = {
121
121
  export type EnumName = string
122
122
 
123
123
 
124
- export type EnumOptionsSources = BasicFun<EnumName, BasicFun<Unit, Promise<Array<[CollectionReference, BoolExpr<Unit>]>>>>
124
+ export type EnumOptionsSources = BasicFun<EnumName, BasicFun<Unit, Promise<Array<{value: CollectionReference}>>>>
125
125
  export const parseForms =
126
126
  <LeafPredicates, T extends { [key in keyof T]: { type: any; state: any; }; },>(
127
127
  builtIns: BuiltIns,
@@ -155,6 +155,7 @@ export const parseForms =
155
155
  }
156
156
  seen = seen.add(formDef.name)
157
157
  formDef.fields.forEach((field, fieldName) => {
158
+ // TODO add a union case
158
159
  if (field.type.kind == "lookup" || field.type.kind == "form") {
159
160
  traverse(formsConfig.forms.get(field.renderer)!)
160
161
  }
@@ -187,6 +188,7 @@ export const parseForms =
187
188
  traverse(form)
188
189
  })
189
190
 
191
+
190
192
  formProcessingOrder.forEach(formName => {
191
193
  const formConfig = formsConfig.forms.get(formName)!
192
194
  const formFieldRenderers = formConfig.fields.map(field => field.renderer).toObject()
@@ -241,7 +243,8 @@ export const parseForms =
241
243
  const initialState = parsedForm.initialFormState
242
244
  const api = {
243
245
  get: (id: string) => entityApis.get(launcher.api)(id).then((raw: any) => {
244
- return fromAPIRawValue(parsedForm.formDef.type , formsConfig.types, builtIns, apiConverters, injectedPrimitives)(raw)
246
+ const x =fromAPIRawValue(parsedForm.formDef.type , formsConfig.types, builtIns, apiConverters, injectedPrimitives)(raw)
247
+ return x
245
248
  }),
246
249
  update: (id: any, parsed: any) => {
247
250
  return parsed.kind =="errors" ? Promise.reject(parsed.errors) : entityApis.update(launcher.api)(id, parsed.value)
@@ -285,13 +288,12 @@ export const parseForms =
285
288
  const form = parsedForm.form
286
289
  const initialState = parsedForm.initialFormState
287
290
  const api = {
288
- default: (_: Unit) => entityApis.default(launcher.api)(unit)
289
- .then((raw: any) => {
290
- return fromAPIRawValue(parsedForm.formDef.type , formsConfig.types, builtIns, apiConverters, injectedPrimitives)(raw)
291
- }),
292
- create: (parsed: any) => {
293
- return parsed.kind == "errors" ? Promise.reject(parsed.errors) : entityApis.create(launcher.api)(parsed.value)
294
- },
291
+ default: (_: Unit) =>
292
+ entityApis.default(launcher.api)(unit).then((raw: any) =>
293
+ fromAPIRawValue(parsedForm.formDef.type , formsConfig.types, builtIns, apiConverters, injectedPrimitives)(raw)),
294
+ create: (parsed: any) =>
295
+ parsed.kind == "errors" ? Promise.reject(parsed.errors) : entityApis.create(launcher.api)(parsed.value)
296
+ ,
295
297
  }
296
298
  parsedLaunchers.create = parsedLaunchers.create.set(
297
299
  launcherName,
@@ -8,17 +8,17 @@ import { FormLabel } from "../../../singleton/domains/form-label/state";
8
8
  import { OnChange, CommonFormState } from "../../../singleton/state";
9
9
 
10
10
 
11
- export type BaseEnumContext<Context, Element extends CollectionReference> = { getOptions:() => Promise<OrderedMap<Guid, [Element, BasicPredicate<Context>]>> }
12
- export type EnumFormState<Context, Element extends CollectionReference> =
11
+ export type BaseEnumContext<Element extends Value<CollectionReference>> = { getOptions:() => Promise<OrderedMap<Guid, Element>> }
12
+ export type EnumFormState<Context, Element extends Value<CollectionReference>> =
13
13
  { commonFormState: CommonFormState,
14
- customFormState: { options: Synchronized<Unit, OrderedMap<Guid, [Element, BasicPredicate<Context>]>>; }; };
15
- export const EnumFormState = <Context extends BaseEnumContext<Context, Element>, Element extends CollectionReference>() => ({
16
- Default: (): EnumFormState<Context, Element> => ({
14
+ customFormState: { options: Synchronized<Unit, OrderedMap<Guid, Element>>; }; };
15
+ export const EnumFormState = <Context extends BaseEnumContext<Value<Element>>, Element extends CollectionReference>() => ({
16
+ Default: (): EnumFormState<Context, Value<Element>> => ({
17
17
  commonFormState: CommonFormState.Default(),
18
18
  customFormState: { options: Synchronized.Default(unit) }
19
19
  }),
20
20
  });
21
- export type EnumView<Context extends FormLabel & BaseEnumContext<Context, Element>, Element extends CollectionReference, ForeignMutationsExpected> = View<
21
+ export type EnumView<Context extends FormLabel & BaseEnumContext<Element>, Element extends Value<CollectionReference>, ForeignMutationsExpected> = View<
22
22
  Context & Value<CollectionSelection<Element>> & EnumFormState<Context, Element> &
23
23
  { activeOptions: "loading" | Array<Element>; } & { disabled:boolean }, EnumFormState<Context, Element>,
24
24
  ForeignMutationsExpected & {
@@ -9,7 +9,7 @@ import { FieldValidation, FieldValidationWithPath, FormValidatorSynchronized, On
9
9
  import { BaseEnumContext, EnumFormState, EnumView } from "./state";
10
10
 
11
11
 
12
- export const EnumForm = <Context extends FormLabel & BaseEnumContext<Context, Element>, ForeignMutationsExpected, Element extends CollectionReference>(
12
+ export const EnumForm = <Context extends FormLabel & BaseEnumContext<Element>, ForeignMutationsExpected, Element extends Value<CollectionReference>>(
13
13
  validation?: BasicFun<CollectionSelection<Element>, Promise<FieldValidation>>
14
14
  ) => {
15
15
  const Co = CoTypedFactory<Context & Value<CollectionSelection<Element>> & { disabled:boolean }, EnumFormState<Context, Element>>()
@@ -20,7 +20,7 @@ export const EnumForm = <Context extends FormLabel & BaseEnumContext<Context, El
20
20
  context={{
21
21
  ...props.context,
22
22
  activeOptions: !AsyncState.Operations.hasValue(props.context.customFormState.options.sync) ? "loading"
23
- : props.context.customFormState.options.sync.value.valueSeq().filter(o => o[1](props.context)).map(o => o[0]).toArray()
23
+ : props.context.customFormState.options.sync.value.valueSeq().toArray()
24
24
  }}
25
25
  foreignMutations={{
26
26
  ...props.foreignMutations,
@@ -30,7 +30,7 @@ export const EnumForm = <Context extends FormLabel & BaseEnumContext<Context, El
30
30
  if (newSelection == undefined)
31
31
  return props.foreignMutations.onChange(replaceWith(CollectionSelection<Element>().Default.right("no selection")), List());
32
32
  else
33
- return props.foreignMutations.onChange(replaceWith(CollectionSelection<Element>().Default.left(newSelection[0])), List());
33
+ return props.foreignMutations.onChange(replaceWith(CollectionSelection<Element>().Default.left(newSelection)), List());
34
34
 
35
35
  }
36
36
  }} />
@@ -42,7 +42,7 @@ export const EnumForm = <Context extends FormLabel & BaseEnumContext<Context, El
42
42
  Co.Template<ForeignMutationsExpected & { onChange: OnChange<CollectionSelection<Element>>; }>(
43
43
  Co.GetState().then(current =>
44
44
  {
45
- return Synchronize<Unit, OrderedMap<Guid, [Element, BasicPredicate<Context>]>>(current.getOptions, () => "transient failure", 5, 50)
45
+ return Synchronize<Unit, OrderedMap<Guid, Element>>(current.getOptions, () => "transient failure", 5, 50)
46
46
  .embed(_ => _.customFormState.options,
47
47
  _ => current => ({ ...current, customFormState: { ...current.customFormState, options: _(current.customFormState.options) } })
48
48
  )}
@@ -8,7 +8,7 @@ import { OnChange } from "../../../singleton/state";
8
8
  import { BaseEnumContext, EnumFormState } from "../enum/state";
9
9
 
10
10
 
11
- export type EnumMultiselectView<Context extends FormLabel & BaseEnumContext<Context, Element>, Element extends CollectionReference, ForeignMutationsExpected> = View<
11
+ export type EnumMultiselectView<Context extends FormLabel & BaseEnumContext<Element>, Element extends Value<CollectionReference>, ForeignMutationsExpected> = View<
12
12
  Context & Value<OrderedMap<Guid, Element>> & EnumFormState<Context, Element> & {
13
13
  selectedIds: Array<Guid>;
14
14
  activeOptions: "loading" | Array<Element>;
@@ -1,15 +1,15 @@
1
1
  import { List, OrderedMap } from "immutable";
2
- import { AsyncState, BasicFun, BasicPredicate, CoTypedFactory, Debounce, Debounced, Guid, OrderedMapRepo, replaceWith, Synchronize, Unit, ValidateRunner } from "../../../../../../main";
2
+ import { AsyncState, BasicFun, CoTypedFactory, Guid, OrderedMapRepo, replaceWith, Synchronize, Unit, ValidateRunner } from "../../../../../../main";
3
3
  import { Template } from "../../../../../template/state";
4
4
  import { Value } from "../../../../../value/state";
5
5
  import { CollectionReference } from "../../../collection/domains/reference/state";
6
6
  import { FormLabel } from "../../../singleton/domains/form-label/state";
7
- import { FieldValidation, FieldValidationWithPath, FormValidatorSynchronized, OnChange, CommonFormState, ValidationError } from "../../../singleton/state";
7
+ import { FieldValidation, FieldValidationWithPath, OnChange,} from "../../../singleton/state";
8
8
  import { BaseEnumContext, EnumFormState } from "../enum/state";
9
9
  import { EnumMultiselectView } from "./state";
10
10
 
11
11
 
12
- export const EnumMultiselectForm = <Context extends FormLabel & BaseEnumContext<Context, Element>, ForeignMutationsExpected, Element extends CollectionReference>(
12
+ export const EnumMultiselectForm = <Context extends FormLabel & BaseEnumContext<Element>, ForeignMutationsExpected, Element extends Value<CollectionReference>>(
13
13
  validation?: BasicFun<OrderedMap<Guid, Element>, Promise<FieldValidation>>
14
14
  ) => {
15
15
  const Co = CoTypedFactory<Context & Value<OrderedMap<Guid, Element>> & EnumFormState<Context, Element> & { disabled:boolean }, EnumFormState<Context, Element>>()
@@ -17,9 +17,9 @@ export const EnumMultiselectForm = <Context extends FormLabel & BaseEnumContext<
17
17
  <props.view {...props}
18
18
  context={{
19
19
  ...props.context,
20
- selectedIds: props.context.value.map(_ => _.id).valueSeq().toArray(),
20
+ selectedIds: props.context.value.map(_ => _.value.id).valueSeq().toArray(),
21
21
  activeOptions: !AsyncState.Operations.hasValue(props.context.customFormState.options.sync) ? "loading"
22
- : props.context.customFormState.options.sync.value.valueSeq().filter(o => o[1](props.context)).map(o => o[0]).toArray()
22
+ : props.context.customFormState.options.sync.value.valueSeq().toArray()
23
23
  }}
24
24
  foreignMutations={{
25
25
  ...props.foreignMutations,
@@ -27,13 +27,15 @@ export const EnumMultiselectForm = <Context extends FormLabel & BaseEnumContext<
27
27
  if (!AsyncState.Operations.hasValue(props.context.customFormState.options.sync)) return
28
28
  const options = props.context.customFormState.options.sync.value
29
29
  const newSelection = _
30
- .flatMap(_ => {
30
+ .flatMap(_ => {
31
31
  const selectedItem = options.get(_);
32
- if (selectedItem != undefined) return [selectedItem[0]];
32
+ if (selectedItem != undefined) {
33
+ const item: [string, Element] = [selectedItem.value.id, selectedItem];
34
+ return [item];
35
+ }
33
36
  return [];
34
37
  });
35
-
36
- props.foreignMutations.onChange(replaceWith(OrderedMapRepo.Default.fromSmallIdentifiables(newSelection)), List());
38
+ props.foreignMutations.onChange(replaceWith(OrderedMap<string, Element>(newSelection)), List());
37
39
  }
38
40
  }}
39
41
  />
@@ -44,7 +46,7 @@ export const EnumMultiselectForm = <Context extends FormLabel & BaseEnumContext<
44
46
  ),
45
47
  Co.Template<ForeignMutationsExpected & { onChange: OnChange<OrderedMap<Guid, Element>>; }>(
46
48
  Co.GetState().then(current =>
47
- Synchronize<Unit, OrderedMap<Guid, [Element, BasicPredicate<Context>]>>(current.getOptions, () => "transient failure", 5, 50)
49
+ Synchronize<Unit, OrderedMap<Guid, Element>>(current.getOptions, () => "transient failure", 5, 50)
48
50
  .embed(_ => _.customFormState.options, _ => current => ({ ...current, customFormState: { ...current.customFormState, options: _(current.customFormState.options) } }))
49
51
  ),
50
52
  {