ballerina-core 1.0.27 → 1.0.30

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.27",
5
+ "version": "1.0.30",
6
6
  "main": "main.ts",
7
7
  "dependencies": {
8
8
  "immutable": "^5.0.0-beta.5",
@@ -46,7 +46,7 @@ export const editFormRunner = <E, FS>() => {
46
46
  5,
47
47
  50
48
48
  ),
49
- current.debounceRateMs ?? 15
49
+ 15
50
50
  ).embed(
51
51
  (_) => ({ ..._, ..._.apiRunner }),
52
52
  EditFormState<E, FS>().Updaters.Core.apiRunner
@@ -71,8 +71,9 @@ export const editFormRunner = <E, FS>() => {
71
71
  Co.Template<EditFormForeignMutationsExpected<E, FS>>(synchronize, {
72
72
  interval: 100,
73
73
  runFilter: (props) =>
74
- Debounced.Operations.shouldCoroutineRun(props.context.apiRunner) ||
75
- !ApiResponseChecker.Operations.checked(props.context),
74
+ props.context.entity.sync.kind == "loaded" &&
75
+ (Debounced.Operations.shouldCoroutineRun(props.context.apiRunner) ||
76
+ !ApiResponseChecker.Operations.checked(props.context)),
76
77
  }),
77
78
  ]);
78
79
  };
@@ -9,8 +9,7 @@ export type EditFormContext<E,FS> = {
9
9
  get:() => Promise<E>,
10
10
  update:BasicFun<E, Promise<ApiErrors>>
11
11
  },
12
- actualForm:Template<Value<E> & FS, FS, { onChange:SimpleCallback<BasicUpdater<E>> }>
13
- debounceRateMs?: number
12
+ actualForm:Template<Value<E> & FS, FS, { onChange:SimpleCallback<BasicUpdater<E>>}>
14
13
  }
15
14
 
16
15
  export type EditFormState<E,FS> = {
@@ -27,7 +26,7 @@ export const EditFormState = <E,FS>() => ({
27
26
  Synchronized.Default(unit)
28
27
  ),
29
28
  formState:initialFormState,
30
- ...ApiResponseChecker.Default(false),
29
+ ...ApiResponseChecker.Default(true),
31
30
  }),
32
31
  Updaters:{
33
32
  Core:{
@@ -39,19 +38,19 @@ export const EditFormState = <E,FS>() => ({
39
38
  toChecked: () => ApiResponseChecker.Updaters.toChecked<EditFormState<E, FS>>(),
40
39
  toUnchecked: () => ApiResponseChecker.Updaters.toUnchecked<EditFormState<E, FS>>(),
41
40
  entity:(_:BasicUpdater<E>) : Updater<EditFormState<E,FS>> =>
42
- EditFormState<E,FS>().Updaters.Core.apiRunner(
43
- Debounced.Updaters.Template.value(
41
+ EditFormState<E,FS>().Updaters.Core.entity(
44
42
  Synchronized.Updaters.sync(
45
43
  AsyncState.Operations.map(
46
- id
44
+ _
47
45
  )
48
46
  )
49
- )
50
- ).then(
51
- EditFormState<E,FS>().Updaters.Core.entity(
47
+ ),
48
+ submit: () : Updater<EditFormState<E,FS>> =>
49
+ EditFormState<E,FS>().Updaters.Core.apiRunner(
50
+ Debounced.Updaters.Template.value(
52
51
  Synchronized.Updaters.sync(
53
52
  AsyncState.Operations.map(
54
- _
53
+ id
55
54
  )
56
55
  )
57
56
  )
@@ -1,19 +1,41 @@
1
- import { AsyncState, editFormRunner, replaceWith, unit } from "../../../../../../main";
1
+ import { AsyncState, editFormRunner, replaceWith, SimpleCallback, unit } from "../../../../../../main";
2
2
  import { Template } from "../../../../../template/state";
3
3
  import { EditFormContext, EditFormForeignMutationsExpected, EditFormState, EditFormWritableState } from "./state";
4
4
 
5
+ export type EditFormView<E, FS> =
6
+ Template<
7
+ EditFormContext<E, FS> & EditFormWritableState<E, FS>,
8
+ EditFormWritableState<E, FS>,
9
+ EditFormForeignMutationsExpected<E, FS> & { onSubmit: SimpleCallback<void> },
10
+ {
11
+ actualForm: JSX.Element | undefined
12
+ }>
5
13
  export type EditFormTemplate<E, FS> =
6
14
  Template<
7
15
  EditFormContext<E, FS> & EditFormWritableState<E, FS>,
8
16
  EditFormWritableState<E, FS>,
9
- EditFormForeignMutationsExpected<E, FS>>
17
+ EditFormForeignMutationsExpected<E, FS>,
18
+ EditFormView<E, FS>>
10
19
  export const EditFormTemplate = <E, FS>() : EditFormTemplate<E,FS> =>
11
20
  Template.Default<
12
21
  EditFormContext<E, FS> & EditFormWritableState<E, FS>,
13
22
  EditFormWritableState<E, FS>,
14
- EditFormForeignMutationsExpected<E, FS>>(props =>
23
+ EditFormForeignMutationsExpected<E, FS>,
24
+ EditFormView<E, FS>
25
+ >(props =>
15
26
  <>
16
- {
27
+ {
28
+ props.view({
29
+ ...props,
30
+ foreignMutations: {
31
+ ...props.foreignMutations,
32
+ onSubmit: () => {
33
+ props.setState(EditFormState<E, FS>().Updaters.Template.submit())
34
+ }
35
+ },
36
+ view: {
37
+ ...props.view,
38
+ actualForm:
17
39
  !AsyncState.Operations.hasValue(props.context.entity.sync) ? undefined :
18
40
  props.context.actualForm({
19
41
  context: {
@@ -28,11 +50,13 @@ export const EditFormTemplate = <E, FS>() : EditFormTemplate<E,FS> =>
28
50
  foreignMutations: {
29
51
  onChange: (e) => {
30
52
  props.setState(EditFormState<E, FS>().Updaters.Template.entity(e))
31
- }
53
+ },
32
54
  },
33
55
  view: unit
34
56
  })
35
- }
57
+ }
58
+ })
59
+ }
36
60
  </>
37
61
  ).any([
38
62
  editFormRunner<E, FS>().mapContextFromProps(props => ({
@@ -6,8 +6,8 @@ export type FormRef = {
6
6
  formName:string
7
7
  } & ({
8
8
  kind:"edit",
9
+ submitButtonWrapper:any
9
10
  entityId:Guid,
10
- debounceRateMs?:number
11
11
  apiHandlers?: {
12
12
  success?: (_: any) => void,
13
13
  error?: (_: any) => void,
@@ -25,7 +25,6 @@ export const FormRunnerTemplate =
25
25
  <props.context.form.value.form
26
26
  context={{
27
27
  ...props.context.form.value.formState,
28
- debounceRateMs: props.context.formRef.kind == "edit" ? props.context.formRef.debounceRateMs : undefined,
29
28
  entityId: props.context.formRef.kind == "edit" ? props.context.formRef.entityId : undefined,
30
29
  value: props.context.formRef.kind == "map" ? props.context.formRef.value : undefined,
31
30
  formState: props.context.formRef.kind == "map" ? props.context.form.value.formState : props.context.form.value.formState.formState,
@@ -35,7 +34,7 @@ export const FormRunnerTemplate =
35
34
  props.context.formRef.kind == "map" ? props.context.form.value.mapping.from(props.context.formRef.value) :
36
35
  props.context.form.value.formState?.entity.sync?.value,
37
36
  },
38
- submitButtonWrapper: props.context.formRef.kind == "create" ? props.context.formRef.submitButtonWrapper : undefined
37
+ submitButtonWrapper: (props.context.formRef.kind == "create" || props.context.formRef.kind == "edit" ) ? props.context.formRef.submitButtonWrapper : undefined
39
38
  }}
40
39
  setState={(_: BasicUpdater<any>) => props.setState(
41
40
  FormRunnerState.Updaters.form(
@@ -27,43 +27,43 @@ export const FieldView = //<Context, FieldViews extends DefaultFieldViews, EnumF
27
27
  (fieldViews: any, viewType: any, viewName: any, fieldName: string, label: string, enumFieldConfigs: EnumOptionsSources, enumSources: any, leafPredicates: any): any => // FieldView<Context, FieldViews, ViewType, ViewName> =>
28
28
  {
29
29
  if (viewType == "maybeBoolean")
30
- return MaybeBooleanForm<any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
30
+ return MaybeBooleanForm<any & FormLabel, Unit>()
31
31
  .withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
32
32
  .mapContext<any & SharedFormState & Value<boolean>>(_ => ({ ..._, label: label })) as any
33
33
  if (viewType == "boolean")
34
- return BooleanForm<any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
34
+ return BooleanForm<any & FormLabel, Unit>()
35
35
  .withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
36
36
  .mapContext<any & SharedFormState & Value<boolean>>(_ => ({ ..._, label: label })) as any
37
37
  if (viewType == "date")
38
- return DateForm<any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
38
+ return DateForm<any & FormLabel, Unit>()
39
39
  .withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
40
40
  .mapContext<any & DateFormState & Value<Date>>(_ => ({ ..._, label: label })) as any
41
41
  if (viewType == "number")
42
- return NumberForm<any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
42
+ return NumberForm<any & FormLabel, Unit>()
43
43
  .withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
44
44
  .mapContext<any & SharedFormState & Value<number>>(_ => ({ ..._, label: label })) as any
45
45
  if (viewType == "string")
46
- return StringForm<any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
46
+ return StringForm<any & FormLabel, Unit>()
47
47
  .withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
48
48
  .mapContext<any & SharedFormState & Value<string>>(_ => ({ ..._, label: label })) as any
49
49
  if (viewType == "enumSingleSelection")
50
- return EnumForm<any & FormLabel & BaseEnumContext<any, CollectionReference>, Unit, CollectionReference>(_ => PromiseRepo.Default.mock(() => []))
50
+ return EnumForm<any & FormLabel & BaseEnumContext<any, CollectionReference>, Unit, CollectionReference>()
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
55
  if (viewType == "enumMultiSelection")
56
- return EnumMultiselectForm<any & FormLabel & BaseEnumContext<any, CollectionReference>, Unit, CollectionReference>(_ => PromiseRepo.Default.mock(() => []))
56
+ return EnumMultiselectForm<any & FormLabel & BaseEnumContext<any, CollectionReference>, Unit, CollectionReference>()
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
61
  if (viewType == "streamSingleSelection")
62
- return SearchableInfiniteStreamForm<CollectionReference, any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
62
+ return SearchableInfiniteStreamForm<CollectionReference, any & FormLabel, Unit>()
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
65
  if (viewType == "streamMultiSelection")
66
- return InfiniteMultiselectDropdownForm<CollectionReference, any & FormLabel, Unit>(_ => PromiseRepo.Default.mock(() => []))
66
+ return InfiniteMultiselectDropdownForm<CollectionReference, any & FormLabel, Unit>()
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
69
69
  return `error: the view for ${viewType as string}::${viewName as string} cannot be found`;
@@ -167,8 +167,7 @@ export const ParseForm = (
167
167
  formConfig[fieldName] = ListForm<any, any, any & FormLabel, Unit>(
168
168
  { Default: () => ({ ...initialFormState }) },
169
169
  { Default: () => ({ ...initialElementValue }) },
170
- _ => PromiseRepo.Default.mock(() => []),
171
- elementForm.form.withView(nestedContainerFormView)
170
+ elementForm.form.withView(nestedContainerFormView),
172
171
  ).withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
173
172
  .mapContext<any>(_ => ({ ..._, label: label }))
174
173
  } else { // the list argument is a primitive
@@ -177,8 +176,7 @@ export const ParseForm = (
177
176
  formConfig[fieldName] = ListForm<any, any, any & FormLabel, Unit>(
178
177
  { Default: () => initialFormState },
179
178
  { Default: () => initialElementValue },
180
- _ => PromiseRepo.Default.mock(() => []),
181
- elementForm
179
+ elementForm,
182
180
  ).withView(((fieldViews as any)[viewType] as any)[viewName]() as any)
183
181
  .mapContext<any>(_ => ({ ..._, label: label }))
184
182
  }
@@ -222,7 +220,8 @@ export type EditLauncherContext<Entity, FormState, ExtraContext> =
222
220
  EditFormContext<Entity, FormState> &
223
221
  EditFormState<Entity, FormState> & {
224
222
  extraContext: ExtraContext,
225
- containerFormView: any
223
+ containerFormView: any,
224
+ submitButtonWrapper: any
226
225
  }, "api" | "actualForm">
227
226
 
228
227
  export type CreateLauncherContext<Entity, FormState, ExtraContext> =
@@ -230,7 +229,7 @@ export type CreateLauncherContext<Entity, FormState, ExtraContext> =
230
229
  CreateFormContext<Entity, FormState> &
231
230
  CreateFormState<Entity, FormState> & {
232
231
  extraContext: ExtraContext,
233
- containerFormView: any
232
+ containerFormView: any,
234
233
  submitButtonWrapper: any
235
234
  }, "api" | "actualForm">
236
235
 
@@ -361,9 +360,7 @@ export const parseForms =
361
360
  const formBuilder = Form<any, any, any, any>().Default<any>()
362
361
  const form = formBuilder.template({
363
362
  ...(parsedForm.formConfig)
364
- }, _ => PromiseRepo.Default.mock(() =>
365
- [
366
- ])).mapContext<Unit>(_ => ({ ..._, disabledFields: parsedForm.disabledFields, visibleFields: parsedForm.visibleFields, layout: formConfig.tabs }))
363
+ }).mapContext<Unit>(_ => ({ ..._, disabledFields: parsedForm.disabledFields, visibleFields: parsedForm.visibleFields, layout: formConfig.tabs }))
367
364
  parsedForms = parsedForms.set(formName, { ...parsedForm, form })
368
365
  } catch (error: any) {
369
366
  errors.push(error)
@@ -396,7 +393,9 @@ export const parseForms =
396
393
  ...parentContext,
397
394
  api: api,
398
395
  actualForm: form.withView(containerFormView).mapContext((_: any) => ({ ..._, rootValue: _.value, ...parentContext.extraContext }))
399
- }) as any).mapForeignMutationsFromProps(props => props.foreignMutations as any),
396
+ }) as any)
397
+ .withViewFromProps(props => props.context.submitButtonWrapper)
398
+ .mapForeignMutationsFromProps(props => props.foreignMutations as any),
400
399
  initialState: EditFormState<Entity, FormState>().Default(initialState),
401
400
  })
402
401
  )
@@ -7,7 +7,7 @@ import { FieldValidation, FieldValidationWithPath, FormValidatorSynchronized, On
7
7
 
8
8
 
9
9
  export const BooleanForm = <Context extends FormLabel, ForeignMutationsExpected>(
10
- validation: BasicFun<boolean, Promise<FieldValidation>>
10
+ validation?: BasicFun<boolean, Promise<FieldValidation>>
11
11
  ) => {
12
12
  return Template.Default<Context & Value<boolean> & { disabled:boolean }, SharedFormState, ForeignMutationsExpected & { onChange: OnChange<boolean>; }, BooleanView<Context, ForeignMutationsExpected>>(props => <>
13
13
  <props.view {...props}
@@ -18,13 +18,13 @@ export const BooleanForm = <Context extends FormLabel, ForeignMutationsExpected>
18
18
  </>
19
19
  ).any([
20
20
  ValidateRunner<Context & { disabled:boolean }, SharedFormState, ForeignMutationsExpected, boolean>(
21
- _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation)
21
+ validation ? _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation) : undefined
22
22
  ),
23
23
  ]);
24
24
  }
25
25
 
26
26
  export const MaybeBooleanForm = <Context extends FormLabel, ForeignMutationsExpected>(
27
- validation: BasicFun<boolean | undefined, Promise<FieldValidation>>
27
+ validation?: BasicFun<boolean | undefined, Promise<FieldValidation>>
28
28
  ) => {
29
29
  return Template.Default<Context & Value<boolean | undefined> & { disabled:boolean }, SharedFormState, ForeignMutationsExpected & { onChange: OnChange<boolean | undefined>; }, MaybeBooleanView<Context, ForeignMutationsExpected>>(props => <>
30
30
  <props.view {...props}
@@ -35,7 +35,7 @@ export const MaybeBooleanForm = <Context extends FormLabel, ForeignMutationsExpe
35
35
  </>
36
36
  ).any([
37
37
  ValidateRunner<Context & { disabled:boolean }, SharedFormState, ForeignMutationsExpected, boolean | undefined>(
38
- _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation)
38
+ validation ? _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation) : undefined
39
39
  ),
40
40
  ]);
41
41
  }
@@ -7,7 +7,7 @@ import { FieldValidation, FieldValidationWithPath, FormValidatorSynchronized, On
7
7
  import { DateFormState, DateView } from "./state";
8
8
 
9
9
  export const DateForm = <Context extends FormLabel, ForeignMutationsExpected>(
10
- validation: BasicFun<Date, Promise<FieldValidation>>
10
+ validation?: BasicFun<Date, Promise<FieldValidation>>
11
11
  ) => {
12
12
  return Template.Default<Context & Value<Date> & { disabled:boolean }, DateFormState, ForeignMutationsExpected & { onChange: OnChange<Date>; }, DateView<Context, ForeignMutationsExpected>>(props => <>
13
13
  <props.view {...props}
@@ -25,7 +25,7 @@ export const DateForm = <Context extends FormLabel, ForeignMutationsExpected>(
25
25
  </>
26
26
  ).any([
27
27
  ValidateRunner<Context & { disabled:boolean }, DateFormState, ForeignMutationsExpected, Date>(
28
- _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation)
28
+ validation ? _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation) : undefined
29
29
  ),
30
30
  ]);
31
31
  }
@@ -10,7 +10,7 @@ import { BaseEnumContext, EnumFormState, EnumView } from "./state";
10
10
 
11
11
 
12
12
  export const EnumForm = <Context extends FormLabel & BaseEnumContext<Context, Element>, ForeignMutationsExpected, Element extends CollectionReference>(
13
- validation: BasicFun<CollectionSelection<Element>, Promise<FieldValidation>>
13
+ validation?: BasicFun<CollectionSelection<Element>, Promise<FieldValidation>>
14
14
  ) => {
15
15
  const Co = CoTypedFactory<Context & Value<CollectionSelection<Element>> & { disabled:boolean }, EnumFormState<Context, Element>>()
16
16
  return Template.Default<Context & Value<CollectionSelection<Element>> & { disabled:boolean }, EnumFormState<Context, Element>, ForeignMutationsExpected & { onChange: OnChange<CollectionSelection<Element>>; },
@@ -36,7 +36,7 @@ export const EnumForm = <Context extends FormLabel & BaseEnumContext<Context, El
36
36
  </>
37
37
  ).any([
38
38
  ValidateRunner<Context & { disabled:boolean }, EnumFormState<Context, Element>, ForeignMutationsExpected, CollectionSelection<Element>>(
39
- _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation)
39
+ validation ? _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation) : undefined
40
40
  ),
41
41
  Co.Template<ForeignMutationsExpected & { onChange: OnChange<CollectionSelection<Element>>; }>(
42
42
  Co.GetState().then(current =>
@@ -10,7 +10,7 @@ import { EnumMultiselectView } from "./state";
10
10
 
11
11
 
12
12
  export const EnumMultiselectForm = <Context extends FormLabel & BaseEnumContext<Context, Element>, ForeignMutationsExpected, Element extends CollectionReference>(
13
- validation:BasicFun<OrderedMap<Guid, Element>, Promise<FieldValidation>>
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>>()
16
16
  return Template.Default<Context & Value<OrderedMap<Guid, Element>> & { disabled: boolean }, EnumFormState<Context, Element>, ForeignMutationsExpected & { onChange: OnChange<OrderedMap<Guid, Element>>; }, EnumMultiselectView<Context, Element, ForeignMutationsExpected>>(props => <>
@@ -40,7 +40,7 @@ export const EnumMultiselectForm = <Context extends FormLabel & BaseEnumContext<
40
40
  </>
41
41
  ).any([
42
42
  ValidateRunner<Context & { disabled:boolean }, EnumFormState<Context, Element>, ForeignMutationsExpected, OrderedMap<Guid, Element>>(
43
- _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation)
43
+ validation ? _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation) : undefined
44
44
  ),
45
45
  Co.Template<ForeignMutationsExpected & { onChange: OnChange<OrderedMap<Guid, Element>>; }>(
46
46
  Co.GetState().then(current =>
@@ -9,13 +9,13 @@ import { ListFieldState, ListFieldView } from "./state";
9
9
  export const ListForm = <Element, ElementFormState, Context extends FormLabel, ForeignMutationsExpected>(
10
10
  ElementFormState: { Default: () => ElementFormState },
11
11
  Element: { Default: () => Element },
12
- validation: BasicFun<List<Element>, Promise<FieldValidation>>,
13
12
  elementTemplate: Template<
14
13
  Context & Value<Element> & ElementFormState,
15
14
  ElementFormState,
16
15
  ForeignMutationsExpected & {
17
16
  onChange: OnChange<Element>;
18
- }>
17
+ }>,
18
+ validation?: BasicFun<List<Element>, Promise<FieldValidation>>,
19
19
  ) => {
20
20
  const embeddedElementTemplate = (elementIndex:number) =>
21
21
  elementTemplate
@@ -68,7 +68,7 @@ export const ListForm = <Element, ElementFormState, Context extends FormLabel, F
68
68
  </>
69
69
  ).any([
70
70
  ValidateRunner<Context & { disabled: boolean }, ListFieldState<Element, ElementFormState>, ForeignMutationsExpected, List<Element>>(
71
- _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation)
71
+ validation ? _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation) : undefined
72
72
  ),
73
73
  ]);
74
74
  };
@@ -7,7 +7,7 @@ import { FieldValidation, FieldValidationWithPath, FormValidatorSynchronized, On
7
7
 
8
8
 
9
9
  export const NumberForm = <Context extends FormLabel, ForeignMutationsExpected>(
10
- validation:BasicFun<number, Promise<FieldValidation>>
10
+ validation?: BasicFun<number, Promise<FieldValidation>>
11
11
  ) => {
12
12
  const Co = CoTypedFactory<Context & Value<number> & SharedFormState & { disabled:boolean }, SharedFormState>()
13
13
  return Template.Default<Context & Value<number> & { disabled:boolean }, SharedFormState, ForeignMutationsExpected & { onChange: OnChange<number>; },
@@ -20,7 +20,7 @@ export const NumberForm = <Context extends FormLabel, ForeignMutationsExpected>(
20
20
  </>
21
21
  ).any([
22
22
  ValidateRunner<Context & { disabled:boolean }, SharedFormState, ForeignMutationsExpected, number>(
23
- _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation)
23
+ validation ? _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation) : undefined
24
24
  ),
25
25
  ]);
26
26
  }
@@ -13,7 +13,7 @@ import { SearchableInfiniteStreamState, SearchableInfiniteStreamView } from "./s
13
13
 
14
14
 
15
15
  export const SearchableInfiniteStreamForm = <Element extends CollectionReference, Context extends FormLabel, ForeignMutationsExpected>(
16
- validation:BasicFun<CollectionSelection<Element>, Promise<FieldValidation>>
16
+ validation?: BasicFun<CollectionSelection<Element>, Promise<FieldValidation>>
17
17
  ) => {
18
18
  const Co = CoTypedFactory<Context & Value<CollectionSelection<Element>> & { disabled:boolean }, SearchableInfiniteStreamState<Element>>();
19
19
  const DebouncerCo = CoTypedFactory<Context & { onDebounce: SimpleCallback<void>; } & Value<CollectionSelection<Element>>, SearchableInfiniteStreamState<Element>>();
@@ -108,7 +108,7 @@ export const SearchableInfiniteStreamForm = <Element extends CollectionReference
108
108
  )
109
109
  })),
110
110
  ValidateRunner<Context & { disabled:boolean }, SearchableInfiniteStreamState<Element>, ForeignMutationsExpected, CollectionSelection<Element>>(
111
- _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation)
111
+ validation ? _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation) : undefined
112
112
  ),
113
113
  ]);
114
114
  };
@@ -13,7 +13,7 @@ import { InfiniteStreamMultiselectView } from "./state";
13
13
 
14
14
 
15
15
  export const InfiniteMultiselectDropdownForm = <Element extends CollectionReference, Context extends FormLabel, ForeignMutationsExpected>(
16
- validation:BasicFun<OrderedMap<Guid, Element>, Promise<FieldValidation>>
16
+ validation? :BasicFun<OrderedMap<Guid, Element>, Promise<FieldValidation>>
17
17
  ) => {
18
18
  const Co = CoTypedFactory<Context & Value<OrderedMap<Guid, Element>> & { disabled:boolean }, SearchableInfiniteStreamState<Element>>();
19
19
  const DebouncerCo = CoTypedFactory<Context & { onDebounce: SimpleCallback<void>; } & Value<OrderedMap<Guid, Element>>, SearchableInfiniteStreamState<Element>>();
@@ -113,7 +113,7 @@ export const InfiniteMultiselectDropdownForm = <Element extends CollectionRefere
113
113
  )
114
114
  })),
115
115
  ValidateRunner<Context & { disabled:boolean }, SearchableInfiniteStreamState<Element>, ForeignMutationsExpected, OrderedMap<Guid, Element>>(
116
- _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation)
116
+ validation ? _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation) : undefined
117
117
  ),
118
118
  ]);
119
119
  };
@@ -8,7 +8,7 @@ import { StringView } from "./state";
8
8
 
9
9
 
10
10
  export const StringForm = <Context extends FormLabel, ForeignMutationsExpected>(
11
- validation:BasicFun<string, Promise<FieldValidation>>) => {
11
+ validation?:BasicFun<string, Promise<FieldValidation>>) => {
12
12
  return Template.Default<Context & Value<string> & { disabled:boolean }, SharedFormState, ForeignMutationsExpected & { onChange: OnChange<string>; }, StringView<Context, ForeignMutationsExpected>>(props => <>
13
13
  <props.view {...props}
14
14
  foreignMutations={{
@@ -18,7 +18,7 @@ export const StringForm = <Context extends FormLabel, ForeignMutationsExpected>(
18
18
  </>
19
19
  ).any([
20
20
  ValidateRunner<Context & { disabled:boolean }, SharedFormState, ForeignMutationsExpected, string>(
21
- _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation)
21
+ validation ? _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation) : undefined
22
22
  ),
23
23
  ])
24
24
  }
@@ -11,7 +11,7 @@ export const Form = <Entity, FieldStates, Context, ForeignMutationsExpected>() =
11
11
 
12
12
  return {
13
13
  config: id<EntityFormConfig>,
14
- template: (config: EntityFormConfig, validation:BasicFun<Entity, Promise<FieldValidationWithPath>>): EntityFormTemplate<Entity, Fields, FieldStates, Context, ForeignMutationsExpected> => {
14
+ template: (config: EntityFormConfig, validation?: BasicFun<Entity, Promise<FieldValidationWithPath>>): EntityFormTemplate<Entity, Fields, FieldStates, Context, ForeignMutationsExpected> => {
15
15
  const fieldTemplates: FieldTemplates<Entity, Fields, FieldStates, Context, ForeignMutationsExpected> = {} as FieldTemplates<Entity, Fields, FieldStates, Context, ForeignMutationsExpected>
16
16
  const setFieldTemplate = <field extends Fields>(field: field) => {
17
17
  fieldTemplates[field] =
@@ -26,7 +26,7 @@ export const Form = <Entity, FieldStates, Context, ForeignMutationsExpected>() =
26
26
  ({
27
27
  ...props.foreignMutations,
28
28
  onChange: (_: BasicUpdater<Entity[field]>, path) => {
29
- props.setState(_ => ({ ..._,
29
+ if(validation) {props.setState(_ => ({ ..._,
30
30
  modifiedByUser: true,
31
31
  validation:Debounced.Updaters.Template.value<FormValidatorSynchronized>(Synchronized.Updaters.value(replaceWith(unit)))(_.validation),
32
32
  [field]:({
@@ -34,6 +34,7 @@ export const Form = <Entity, FieldStates, Context, ForeignMutationsExpected>() =
34
34
  modifiedByUser:true,
35
35
  validation:Debounced.Updaters.Template.value<FormValidatorSynchronized>(Synchronized.Updaters.value(replaceWith(unit)))(_[field].validation),
36
36
  }) }))
37
+ }
37
38
  setTimeout(() =>
38
39
  props.foreignMutations.onChange((current: Entity): Entity => ({
39
40
  ...current,
@@ -81,21 +82,21 @@ export const Form = <Entity, FieldStates, Context, ForeignMutationsExpected>() =
81
82
  })
82
83
 
83
84
  export const ValidateRunner = <Context, FormState extends SharedFormState, ForeignMutationsExpected, Entity,>(
84
- validation:BasicFun<Entity, Promise<FieldValidationWithPath>>,
85
+ validation?:BasicFun<Entity, Promise<FieldValidationWithPath>>,
85
86
  ) => {
86
87
  const Co = CoTypedFactory<Context & Value<Entity> & FormState, FormState>()
87
88
  return Co.Template<ForeignMutationsExpected & { onChange: OnChange<Entity>; }>(
88
89
  Co.Repeat(
89
90
  Debounce<FormValidatorSynchronized, Value<Entity>>(
90
91
  Synchronize<Unit, FieldValidationWithPath, Value<Entity>>(
91
- _ => validation(_.value),
92
+ _ => validation ? validation(_.value) : Promise.resolve([]),
92
93
  () => "transient failure", 3, 50
93
94
  ), 50
94
95
  ).embed(_ => ({..._.validation, value:_.value}), (_) => curr => ({...curr, validation:_(curr.validation)}))
95
96
  ),
96
97
  {
97
98
  interval:15,
98
- runFilter:props => Debounced.Operations.shouldCoroutineRun(props.context.validation)
99
+ runFilter:props => Boolean(validation) && Debounced.Operations.shouldCoroutineRun(props.context.validation)
99
100
  }
100
101
  )
101
102
  }