From d85872466b6e6d06bc10cfadd2610dadc78b9735 Mon Sep 17 00:00:00 2001 From: Thomas <4159106+dtslvr@users.noreply.github.com> Date: Tue, 13 Jun 2023 20:01:14 +0200 Subject: [PATCH] Refactoring --- ...create-or-update-activity-dialog.module.ts | 5 +- .../abstract-mat-form-field.ts | 32 +++++---- .../symbol-autocomplete.component.scss | 3 + .../symbol-autocomplete.component.ts | 71 ++++++++++--------- .../symbol-autocomplete.module.ts | 2 +- 5 files changed, 64 insertions(+), 49 deletions(-) rename libs/ui/src/lib/{ => symbol-autocomplete}/abstract-mat-form-field.ts (93%) diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.module.ts b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.module.ts index 0c062c764..e1eb70a10 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.module.ts +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.module.ts @@ -11,9 +11,10 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSelectModule } from '@angular/material/select'; -import { GfSymbolAutoCompleteModule } from '@ghostfolio/ui/symbol-autocomplete/symbol-autocomplete.module'; import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; +import { GfSymbolAutocompleteModule } from '@ghostfolio/ui/symbol-autocomplete/symbol-autocomplete.module'; import { GfValueModule } from '@ghostfolio/ui/value'; + import { CreateOrUpdateActivityDialog } from './create-or-update-activity-dialog.component'; @NgModule({ @@ -21,7 +22,7 @@ import { CreateOrUpdateActivityDialog } from './create-or-update-activity-dialog imports: [ CommonModule, FormsModule, - GfSymbolAutoCompleteModule, + GfSymbolAutocompleteModule, GfSymbolModule, GfValueModule, MatAutocompleteModule, diff --git a/libs/ui/src/lib/abstract-mat-form-field.ts b/libs/ui/src/lib/symbol-autocomplete/abstract-mat-form-field.ts similarity index 93% rename from libs/ui/src/lib/abstract-mat-form-field.ts rename to libs/ui/src/lib/symbol-autocomplete/abstract-mat-form-field.ts index 4b39248f3..b0ce3dc9b 100644 --- a/libs/ui/src/lib/abstract-mat-form-field.ts +++ b/libs/ui/src/lib/symbol-autocomplete/abstract-mat-form-field.ts @@ -6,7 +6,6 @@ import { ElementRef, HostBinding, HostListener, - Injector, Input, OnDestroy } from '@angular/core'; @@ -18,21 +17,24 @@ import { Subject } from 'rxjs'; template: '' }) export abstract class AbstractMatFormField - implements DoCheck, OnDestroy, ControlValueAccessor, MatFormFieldControl + implements ControlValueAccessor, DoCheck, MatFormFieldControl, OnDestroy { - private static nextId: number = 0; @HostBinding() - public id: string = `${this.controlType}-${AbstractMatFormField.nextId++}`; - @HostBinding('attr.aria-describedBy') - public describedBy: string = ''; - public focused = false; + public id = `${this.controlType}-${AbstractMatFormField.nextId++}`; + + @HostBinding('attr.aria-describedBy') public describedBy = ''; + public readonly autofilled: boolean; public errorState: boolean; + public focused = false; public readonly stateChanges = new Subject(); public readonly userAriaDescribedBy: string; + protected onChange?: (value: T) => void; protected onTouched?: () => void; + private static nextId: number = 0; + protected constructor( protected _elementRef: ElementRef, protected _focusMonitor: FocusMonitor, @@ -69,6 +71,7 @@ export abstract class AbstractMatFormField public set value(value: T) { this._value = value; + if (this.onChange) { this.onChange(value); } @@ -108,6 +111,7 @@ export abstract class AbstractMatFormField if (this.ngControl && this.ngControl.disabled !== null) { return this.ngControl.disabled; } + return this._disabled; } @@ -121,6 +125,8 @@ export abstract class AbstractMatFormField } } + public abstract focus(): void; + public get shouldLabelFloat(): boolean { return this.focused || !this.empty; } @@ -145,22 +151,22 @@ export abstract class AbstractMatFormField this.onTouched = fn; } - public writeValue(value: T): void { - this.value = value; - } - public setDescribedByIds(ids: string[]): void { this.describedBy = ids.join(' '); } - public abstract focus(): void; + public writeValue(value: T): void { + this.value = value; + } @HostListener('focusout') - onBlur() { + public onBlur() { this.focused = false; + if (this.onTouched) { this.onTouched(); } + this.stateChanges.next(); } diff --git a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.scss b/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.scss index e69de29bb..5d4e87f30 100644 --- a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.scss +++ b/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.scss @@ -0,0 +1,3 @@ +:host { + display: block; +} diff --git a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts b/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts index 0f06447f0..e08db461e 100644 --- a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts +++ b/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts @@ -17,6 +17,7 @@ import { import { MatFormFieldControl } from '@angular/material/form-field'; import { MatInput } from '@angular/material/input'; import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; +import { DataService } from '@ghostfolio/client/services/data.service'; import { isString } from 'lodash'; import { Observable, Subject, of, tap } from 'rxjs'; import { @@ -26,16 +27,15 @@ import { switchMap } from 'rxjs/operators'; -import { DataService } from '../../../../../apps/client/src/app/services/data.service'; -import { AbstractMatFormField } from '../abstract-mat-form-field'; +import { AbstractMatFormField } from './abstract-mat-form-field'; @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, host: { '[attr.aria-describedBy]': 'describedBy', '[id]': 'id' }, selector: 'gf-symbol-autocomplete', - changeDetection: ChangeDetectionStrategy.OnPush, styleUrls: ['./symbol-autocomplete.component.scss'], templateUrl: 'symbol-autocomplete.component.html', providers: [ @@ -49,17 +49,19 @@ export class SymbolAutocompleteComponent extends AbstractMatFormField implements OnInit, OnDestroy { + @Input() public isLoading = false; + + @ViewChild(MatInput, { static: false }) private input: MatInput; + + @ViewChild('symbolAutocomplete') public symbolAutocomplete: MatAutocomplete; + public control = new FormControl(); - filteredLookupItemsObservable: Observable = of([]); public filteredLookupItems: LookupItem[] = []; - @Input() - public isLoading: boolean = false; - @ViewChild('symbolAutocomplete') symbolAutocomplete: MatAutocomplete; - @ViewChild(MatInput, { static: false }) - private input: MatInput; + public filteredLookupItemsObservable: Observable = of([]); + private unsubscribeSubject = new Subject(); - constructor( + public constructor( public readonly _elementRef: ElementRef, public readonly _focusMonitor: FocusMonitor, public readonly changeDetectorRef: ChangeDetectorRef, @@ -71,15 +73,6 @@ export class SymbolAutocompleteComponent this.controlType = 'symbol-autocomplete'; } - public set value(value: LookupItem) { - this.control.setValue(value); - super.value = value; - } - - public get empty(): boolean { - return this.input?.empty; - } - public ngOnInit(): void { super.required = this.ngControl.control?.hasValidator(Validators.required); @@ -102,10 +95,22 @@ export class SymbolAutocompleteComponent }); } - public ngOnDestroy(): void { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - super.ngOnDestroy(); + public displayFn(aLookupItem: LookupItem) { + return aLookupItem?.symbol ?? ''; + } + + public get empty(): boolean { + return this.input?.empty; + } + + public focus(): void { + this.input.focus(); + } + + public isValueInOptions(value: string): boolean { + return this.filteredLookupItems.some((item) => { + return item.symbol === value; + }); } public ngDoCheck(): void { @@ -117,14 +122,6 @@ export class SymbolAutocompleteComponent } } - public focus(): void { - this.input.focus(); - } - - public displayFn(aLookupItem: LookupItem) { - return aLookupItem?.symbol ?? ''; - } - public onUpdateSymbol(event: MatAutocompleteSelectedEvent) { super.value = { dataSource: event.option.value.dataSource, @@ -132,8 +129,16 @@ export class SymbolAutocompleteComponent } as LookupItem; } - public isValueInOptions(value: string): boolean { - return this.filteredLookupItems.some((item) => item.symbol === value); + public set value(value: LookupItem) { + this.control.setValue(value); + super.value = value; + } + + public ngOnDestroy(): void { + super.ngOnDestroy(); + + this.unsubscribeSubject.next(); + this.unsubscribeSubject.complete(); } private validateRequired() { diff --git a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.module.ts b/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.module.ts index 4b9244f14..d7b1ed2f8 100644 --- a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.module.ts +++ b/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.module.ts @@ -23,4 +23,4 @@ import { SymbolAutocompleteComponent } from '@ghostfolio/ui/symbol-autocomplete/ ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) -export class GfSymbolAutoCompleteModule {} +export class GfSymbolAutocompleteModule {}