diff --git a/angular/projects/shared/src/lib/components/xsd/elements/inputs/xsd-select-state.component.html b/angular/projects/shared/src/lib/components/xsd/elements/inputs/xsd-select-state.component.html index bd04a8e8..b9a65259 100644 --- a/angular/projects/shared/src/lib/components/xsd/elements/inputs/xsd-select-state.component.html +++ b/angular/projects/shared/src/lib/components/xsd/elements/inputs/xsd-select-state.component.html @@ -1,9 +1,21 @@ - {{ val }} + {{ val.name }}   -
- -
+ diff --git a/angular/projects/shared/src/lib/components/xsd/elements/inputs/xsd-select-state.component.ts b/angular/projects/shared/src/lib/components/xsd/elements/inputs/xsd-select-state.component.ts index b39f1e86..634c7105 100644 --- a/angular/projects/shared/src/lib/components/xsd/elements/inputs/xsd-select-state.component.ts +++ b/angular/projects/shared/src/lib/components/xsd/elements/inputs/xsd-select-state.component.ts @@ -1,4 +1,8 @@ -import { Component } from '@angular/core'; +import { Component, ViewChild } from '@angular/core'; +import { HttpResponse } from '@angular/common/http'; +import { NgbTypeahead } from '@ng-bootstrap/ng-bootstrap'; +import { Observable, OperatorFunction, Subject, merge } from 'rxjs'; +import { debounceTime, distinctUntilChanged, filter, map } from 'rxjs/operators'; import { XsdElementBaseComponent } from '../xsd-element-base.component'; @@ -9,26 +13,53 @@ let STATES: any[]; templateUrl: './xsd-select-state.component.html', }) export class XsdSelectStateComponent extends XsdElementBaseComponent { + @ViewChild('instance', { static: true }) instance?: NgbTypeahead; + model: any; + + focus$ = new Subject(); + click$ = new Subject(); + STATES: any[] = []; + search: OperatorFunction = (text$: Observable) => { + const debouncedText$ = text$.pipe(debounceTime(200), distinctUntilChanged()); + const clicksWithClosedPopup$ = this.click$.pipe(filter(() => !this.instance?.isPopupOpen())); + const inputFocus$ = this.focus$; + + return merge(debouncedText$, inputFocus$, clicksWithClosedPopup$).pipe( + debounceTime(200), + distinctUntilChanged(), + map((term: string) => + (term === '' ? STATES : STATES.filter((v) => v.name.toLowerCase().indexOf(term.toLowerCase()) > -1)).slice(0, 10), + ), + ); + }; + + formatter = (x: any) => x.name; + ngOnInit() { if (STATES) { this.STATES = STATES; } else { - this.api.states.index().subscribe((res) => { + this.api.states.index().subscribe((res: HttpResponse) => { STATES = res.body; + Object.freeze(STATES); this.STATES = STATES; }); } } - get enumeratedValue(): string | null { - let result: string | null = null; + get state(): any { for (const state of this.STATES) { if (state.id === this.value) { - return state.name; + return state; } } - return result; + return this.model; + } + + onChangeState(state: any) { + this.model = state; + this.value = state?.id; } } diff --git a/angular/projects/shared/src/lib/components/xsd/elements/inputs/xsd-select.component.html b/angular/projects/shared/src/lib/components/xsd/elements/inputs/xsd-select.component.html index ccaf89fe..22338aae 100644 --- a/angular/projects/shared/src/lib/components/xsd/elements/inputs/xsd-select.component.html +++ b/angular/projects/shared/src/lib/components/xsd/elements/inputs/xsd-select.component.html @@ -2,16 +2,20 @@ {{ val }}   -
- -
+ diff --git a/angular/projects/shared/src/lib/components/xsd/elements/inputs/xsd-select.component.ts b/angular/projects/shared/src/lib/components/xsd/elements/inputs/xsd-select.component.ts index e7f6ac9d..21f3e942 100644 --- a/angular/projects/shared/src/lib/components/xsd/elements/inputs/xsd-select.component.ts +++ b/angular/projects/shared/src/lib/components/xsd/elements/inputs/xsd-select.component.ts @@ -1,4 +1,7 @@ -import { Component } from '@angular/core'; +import { Component, ViewChild } from '@angular/core'; +import { NgbTypeahead } from '@ng-bootstrap/ng-bootstrap'; +import { Observable, OperatorFunction, Subject, merge } from 'rxjs'; +import { debounceTime, distinctUntilChanged, filter, map } from 'rxjs/operators'; import { XsdElementBaseComponent } from '../xsd-element-base.component'; @@ -7,35 +10,46 @@ import { XsdElementBaseComponent } from '../xsd-element-base.component'; templateUrl: './xsd-select.component.html', }) export class XsdSelectComponent extends XsdElementBaseComponent { - get minLength(): number | null { - if (this.type?.['xs:restriction']?.['xs:minLength']?._attributes?.value) { - return parseInt(this.type['xs:restriction']['xs:minLength']._attributes.value); - } - return null; - } + @ViewChild('instance', { static: true }) instance?: NgbTypeahead; + model: any; - get maxLength(): number | null { - if (this.type?.['xs:restriction']?.['xs:maxLength']?._attributes?.value) { - return parseInt(this.type['xs:restriction']['xs:maxLength']._attributes.value); - } - return null; - } + focus$ = new Subject(); + click$ = new Subject(); + search: OperatorFunction = (text$: Observable) => { + const debouncedText$ = text$.pipe(debounceTime(200), distinctUntilChanged()); + const clicksWithClosedPopup$ = this.click$.pipe(filter(() => !this.instance?.isPopupOpen())); + const inputFocus$ = this.focus$; - get pattern(): string | null { - if (this.type?.['xs:restriction']?.['xs:pattern']?._attributes?.value) { - return this.type['xs:restriction']['xs:pattern']._attributes.value; + return merge(debouncedText$, inputFocus$, clicksWithClosedPopup$).pipe( + debounceTime(200), + distinctUntilChanged(), + map((term: string) => + (term === '' + ? this.enumeration + : this.enumeration.filter((v) => v['xs:annotation']['xs:documentation']._text.toLowerCase().indexOf(term.toLowerCase()) > -1) + ).slice(0, 10), + ), + ); + }; + + formatter = (x: any) => x['xs:annotation']['xs:documentation']._text; + + get selectValue(): any { + for (const item of this.enumeration) { + if (item._attributes.value === this.value) { + return item; + } } - return null; + return this.model; } - onChange(newValue: string) { - for (let item of this.type?.['xs:restriction']?.['xs:enumeration']) { - const { value, nemsisCode } = item._attributes ?? {}; - if (value === newValue && nemsisCode) { - this.setCustomValue(nemsisCode, value); - return; - } + onChange(newValue: any) { + this.model = newValue; + const { value, nemsisCode } = newValue?._attributes ?? {}; + if (nemsisCode) { + this.setCustomValue(nemsisCode, value); + return; } - this.value = newValue; + this.value = value; } } diff --git a/angular/projects/shared/src/lib/components/xsd/elements/xsd-element-base.component.ts b/angular/projects/shared/src/lib/components/xsd/elements/xsd-element-base.component.ts index a375b7d9..05b5aab6 100644 --- a/angular/projects/shared/src/lib/components/xsd/elements/xsd-element-base.component.ts +++ b/angular/projects/shared/src/lib/components/xsd/elements/xsd-element-base.component.ts @@ -112,6 +112,10 @@ export class XsdElementBaseComponent { return !!this.type?.['xs:restriction']?.['xs:enumeration']; } + get enumeration(): any[] { + return this.type?.['xs:restriction']?.['xs:enumeration'] ?? []; + } + get primitiveType(): string { return this.type?.['xs:restriction']?._attributes?.base; } @@ -503,7 +507,6 @@ export class XsdElementBaseComponent { if (value) { this.delValue(); this.setAttr('xsi:nil', 'true'); - this.NV = this.nilValues[0]?.['xs:restriction']?.['xs:enumeration']?._attributes?.value; // if this is a repeating element, remove the other values if (Array.isArray(this.data[this.name]) && this.data[this.name].length > 1) { this.data[this.name].splice(1, this.data[this.name].length - 1); diff --git a/angular/projects/shared/src/lib/components/xsd/elements/xsd-element-input.component.html b/angular/projects/shared/src/lib/components/xsd/elements/xsd-element-input.component.html index a4311862..e0ab69e5 100644 --- a/angular/projects/shared/src/lib/components/xsd/elements/xsd-element-input.component.html +++ b/angular/projects/shared/src/lib/components/xsd/elements/xsd-element-input.component.html @@ -45,6 +45,7 @@ [displayOnly]="displayOnly"> - - - -
- -
+ +
- +
diff --git a/angular/projects/shared/src/lib/components/xsd/elements/xsd-element-nillable.component.ts b/angular/projects/shared/src/lib/components/xsd/elements/xsd-element-nillable.component.ts index 5ee80777..ca584c8d 100644 --- a/angular/projects/shared/src/lib/components/xsd/elements/xsd-element-nillable.component.ts +++ b/angular/projects/shared/src/lib/components/xsd/elements/xsd-element-nillable.component.ts @@ -1,4 +1,7 @@ -import { Component } from '@angular/core'; +import { Component, ViewChild } from '@angular/core'; +import { NgbTypeahead } from '@ng-bootstrap/ng-bootstrap'; +import { Observable, OperatorFunction, Subject, merge } from 'rxjs'; +import { debounceTime, distinctUntilChanged, filter, map } from 'rxjs/operators'; import { XsdElementBaseComponent } from './xsd-element-base.component'; @@ -7,4 +10,59 @@ import { XsdElementBaseComponent } from './xsd-element-base.component'; templateUrl: './xsd-element-nillable.component.html', styleUrls: ['./xsd-element-nillable.component.scss'], }) -export class XsdElementNillableComponent extends XsdElementBaseComponent {} +export class XsdElementNillableComponent extends XsdElementBaseComponent { + @ViewChild('instance', { static: true }) instance?: NgbTypeahead; + model: any; + + focus$ = new Subject(); + click$ = new Subject(); + search: OperatorFunction = (text$: Observable) => { + const debouncedText$ = text$.pipe(debounceTime(200), distinctUntilChanged()); + const clicksWithClosedPopup$ = this.click$.pipe(filter(() => !this.instance?.isPopupOpen())); + const inputFocus$ = this.focus$; + + return merge(debouncedText$, inputFocus$, clicksWithClosedPopup$).pipe( + debounceTime(200), + distinctUntilChanged(), + map((term: string) => + (term === '' + ? this.nilValues + : this.nilValues.filter( + (nv: any) => + nv['xs:restriction']['xs:enumeration']['xs:annotation']['xs:documentation']._text + .toLowerCase() + .indexOf(term.toLowerCase()) > -1, + ) + ).slice(0, 10), + ), + ); + }; + + formatter = (nv: any) => nv['xs:restriction']['xs:enumeration']['xs:annotation']['xs:documentation']._text; + + get nilValue(): any { + for (const nv of this.nilValues) { + if (nv['xs:restriction']['xs:enumeration']._attributes.value === this.NV) { + return nv; + } + } + return this.model; + } + + onChange(newValue: any) { + this.model = newValue; + this.NV = newValue?.['xs:restriction']['xs:enumeration']._attributes.value; + } + + onToggle($event: any) { + const { checked } = $event?.target; + setTimeout(() => { + if (checked) { + (document.querySelector(`[id="${this.formName}-NV"]`) as HTMLElement)?.focus(); + } else { + (document.querySelector(`[id="${this.formName}"]`) as HTMLElement)?.focus(); + this.model = ''; + } + }, 100); + } +}