From 4e22f130075a8c8cbe90f6ab19503b5f81a19dd8 Mon Sep 17 00:00:00 2001 From: Alex Inkin Date: Thu, 6 Feb 2025 21:06:04 +0400 Subject: [PATCH] Fix/unions (#2825) * mocks for union value * fix: properly handle values in unions --------- Co-authored-by: Matt Hill --- .../form/form-union/form-union.component.ts | 4 ++ .../ui/src/app/services/api/api.fixures.ts | 42 ++++++++++++++++++- .../ui/src/app/services/form.service.ts | 26 ++++-------- 3 files changed, 53 insertions(+), 19 deletions(-) diff --git a/web/projects/ui/src/app/components/form/form-union/form-union.component.ts b/web/projects/ui/src/app/components/form/form-union/form-union.component.ts index 83c69bd6d..d1a3b61c1 100644 --- a/web/projects/ui/src/app/components/form/form-union/form-union.component.ts +++ b/web/projects/ui/src/app/components/form/form-union/form-union.component.ts @@ -30,6 +30,7 @@ export class FormUnionComponent implements OnChanges { private readonly form = inject(FormGroupName) private readonly formService = inject(FormService) + private readonly values: Record = {} get union(): string { return this.form.value.selection @@ -37,10 +38,13 @@ export class FormUnionComponent implements OnChanges { @tuiPure onUnion(union: string) { + this.values[this.union] = this.form.control.controls['value'].value this.form.control.setControl( 'value', this.formService.getFormGroup( union ? this.spec.variants[union].spec : {}, + [], + this.values[union], ), { emitEvent: false, diff --git a/web/projects/ui/src/app/services/api/api.fixures.ts b/web/projects/ui/src/app/services/api/api.fixures.ts index 8ca8864e2..f6d5ed58d 100644 --- a/web/projects/ui/src/app/services/api/api.fixures.ts +++ b/web/projects/ui/src/app/services/api/api.fixures.ts @@ -1519,7 +1519,43 @@ export module Mock { }, internal: { name: 'Internal', - spec: ISB.InputSpec.of({}), + spec: ISB.InputSpec.of({ + listitems: ISB.Value.list( + ISB.List.text( + { + name: 'RPC Allowed IPs', + minLength: 1, + maxLength: 10, + default: ['192.168.1.1'], + description: + 'external ip addresses that are authorized to access your Bitcoin node', + warning: + 'Any IP you allow here will have RPC access to your Bitcoin node.', + }, + { + patterns: [ + { + regex: + '((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|((^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$)|(^[a-z2-7]{16}\\.onion$)|(^([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]$))', + description: + 'must be a valid ipv4, ipv6, or domain name', + }, + ], + }, + ), + ), + name: ISB.Value.text({ + name: 'Name', + required: false, + default: null, + patterns: [ + { + regex: '^[a-zA-Z]+$', + description: 'Must contain only letters.', + }, + ], + }), + }), }, external: { name: 'External', @@ -1667,6 +1703,10 @@ export module Mock { }, 'bitcoin-node': { selection: 'internal', + value: { + listitems: ['192.168.1.1', '192.1681.23'], + name: 'Matt', + }, }, port: 20, rpcallowip: undefined, diff --git a/web/projects/ui/src/app/services/form.service.ts b/web/projects/ui/src/app/services/form.service.ts index 76e35b942..04ee483a6 100644 --- a/web/projects/ui/src/app/services/form.service.ts +++ b/web/projects/ui/src/app/services/form.service.ts @@ -37,18 +37,14 @@ export class FormService { } } - getUnionObject( - spec: IST.ValueSpecUnion, - selected: string | null, - ): UntypedFormGroup { - const group = this.getFormGroup({ - selection: this.getUnionSelectSpec(spec, selected), - }) + getUnionObject(spec: IST.ValueSpecUnion, value: any): UntypedFormGroup { + const valid = spec.variants[value?.selection] + const selected = valid ? value?.selection : spec.default + const selection = this.getUnionSelectSpec(spec, selected) + const group = this.getFormGroup({ selection }) + const control = selected ? spec.variants[selected].spec : {} - group.setControl( - 'value', - this.getFormGroup(selected ? spec.variants[selected].spec : {}), - ) + group.setControl('value', this.getFormGroup(control, [], value?.value)) return group } @@ -129,13 +125,7 @@ export class FormService { listValidators(spec), ) case 'union': - const currentSelection = currentValue?.selection - const isValid = !!spec.variants[currentSelection] - - return this.getUnionObject( - spec, - isValid ? currentSelection : spec.default, - ) + return this.getUnionObject(spec, currentValue) case 'toggle': value = currentValue === undefined ? spec.default : currentValue return this.formBuilder.control(value)