Browse Source

Refactoring

pull/2056/head
Thomas 2 years ago
parent
commit
d85872466b
  1. 5
      apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.module.ts
  2. 32
      libs/ui/src/lib/symbol-autocomplete/abstract-mat-form-field.ts
  3. 3
      libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.scss
  4. 71
      libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts
  5. 2
      libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.module.ts

5
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 { MatInputModule } from '@angular/material/input';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSelectModule } from '@angular/material/select'; 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 { 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 { GfValueModule } from '@ghostfolio/ui/value';
import { CreateOrUpdateActivityDialog } from './create-or-update-activity-dialog.component'; import { CreateOrUpdateActivityDialog } from './create-or-update-activity-dialog.component';
@NgModule({ @NgModule({
@ -21,7 +22,7 @@ import { CreateOrUpdateActivityDialog } from './create-or-update-activity-dialog
imports: [ imports: [
CommonModule, CommonModule,
FormsModule, FormsModule,
GfSymbolAutoCompleteModule, GfSymbolAutocompleteModule,
GfSymbolModule, GfSymbolModule,
GfValueModule, GfValueModule,
MatAutocompleteModule, MatAutocompleteModule,

32
libs/ui/src/lib/abstract-mat-form-field.ts → libs/ui/src/lib/symbol-autocomplete/abstract-mat-form-field.ts

@ -6,7 +6,6 @@ import {
ElementRef, ElementRef,
HostBinding, HostBinding,
HostListener, HostListener,
Injector,
Input, Input,
OnDestroy OnDestroy
} from '@angular/core'; } from '@angular/core';
@ -18,21 +17,24 @@ import { Subject } from 'rxjs';
template: '' template: ''
}) })
export abstract class AbstractMatFormField<T> export abstract class AbstractMatFormField<T>
implements DoCheck, OnDestroy, ControlValueAccessor, MatFormFieldControl<T> implements ControlValueAccessor, DoCheck, MatFormFieldControl<T>, OnDestroy
{ {
private static nextId: number = 0;
@HostBinding() @HostBinding()
public id: string = `${this.controlType}-${AbstractMatFormField.nextId++}`; public id = `${this.controlType}-${AbstractMatFormField.nextId++}`;
@HostBinding('attr.aria-describedBy')
public describedBy: string = ''; @HostBinding('attr.aria-describedBy') public describedBy = '';
public focused = false;
public readonly autofilled: boolean; public readonly autofilled: boolean;
public errorState: boolean; public errorState: boolean;
public focused = false;
public readonly stateChanges = new Subject<void>(); public readonly stateChanges = new Subject<void>();
public readonly userAriaDescribedBy: string; public readonly userAriaDescribedBy: string;
protected onChange?: (value: T) => void; protected onChange?: (value: T) => void;
protected onTouched?: () => void; protected onTouched?: () => void;
private static nextId: number = 0;
protected constructor( protected constructor(
protected _elementRef: ElementRef, protected _elementRef: ElementRef,
protected _focusMonitor: FocusMonitor, protected _focusMonitor: FocusMonitor,
@ -69,6 +71,7 @@ export abstract class AbstractMatFormField<T>
public set value(value: T) { public set value(value: T) {
this._value = value; this._value = value;
if (this.onChange) { if (this.onChange) {
this.onChange(value); this.onChange(value);
} }
@ -108,6 +111,7 @@ export abstract class AbstractMatFormField<T>
if (this.ngControl && this.ngControl.disabled !== null) { if (this.ngControl && this.ngControl.disabled !== null) {
return this.ngControl.disabled; return this.ngControl.disabled;
} }
return this._disabled; return this._disabled;
} }
@ -121,6 +125,8 @@ export abstract class AbstractMatFormField<T>
} }
} }
public abstract focus(): void;
public get shouldLabelFloat(): boolean { public get shouldLabelFloat(): boolean {
return this.focused || !this.empty; return this.focused || !this.empty;
} }
@ -145,22 +151,22 @@ export abstract class AbstractMatFormField<T>
this.onTouched = fn; this.onTouched = fn;
} }
public writeValue(value: T): void {
this.value = value;
}
public setDescribedByIds(ids: string[]): void { public setDescribedByIds(ids: string[]): void {
this.describedBy = ids.join(' '); this.describedBy = ids.join(' ');
} }
public abstract focus(): void; public writeValue(value: T): void {
this.value = value;
}
@HostListener('focusout') @HostListener('focusout')
onBlur() { public onBlur() {
this.focused = false; this.focused = false;
if (this.onTouched) { if (this.onTouched) {
this.onTouched(); this.onTouched();
} }
this.stateChanges.next(); this.stateChanges.next();
} }

3
libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.scss

@ -0,0 +1,3 @@
:host {
display: block;
}

71
libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts

@ -17,6 +17,7 @@ import {
import { MatFormFieldControl } from '@angular/material/form-field'; import { MatFormFieldControl } from '@angular/material/form-field';
import { MatInput } from '@angular/material/input'; import { MatInput } from '@angular/material/input';
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
import { DataService } from '@ghostfolio/client/services/data.service';
import { isString } from 'lodash'; import { isString } from 'lodash';
import { Observable, Subject, of, tap } from 'rxjs'; import { Observable, Subject, of, tap } from 'rxjs';
import { import {
@ -26,16 +27,15 @@ import {
switchMap switchMap
} from 'rxjs/operators'; } 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({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { host: {
'[attr.aria-describedBy]': 'describedBy', '[attr.aria-describedBy]': 'describedBy',
'[id]': 'id' '[id]': 'id'
}, },
selector: 'gf-symbol-autocomplete', selector: 'gf-symbol-autocomplete',
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrls: ['./symbol-autocomplete.component.scss'], styleUrls: ['./symbol-autocomplete.component.scss'],
templateUrl: 'symbol-autocomplete.component.html', templateUrl: 'symbol-autocomplete.component.html',
providers: [ providers: [
@ -49,17 +49,19 @@ export class SymbolAutocompleteComponent
extends AbstractMatFormField<LookupItem> extends AbstractMatFormField<LookupItem>
implements OnInit, OnDestroy implements OnInit, OnDestroy
{ {
@Input() public isLoading = false;
@ViewChild(MatInput, { static: false }) private input: MatInput;
@ViewChild('symbolAutocomplete') public symbolAutocomplete: MatAutocomplete;
public control = new FormControl(); public control = new FormControl();
filteredLookupItemsObservable: Observable<LookupItem[]> = of([]);
public filteredLookupItems: LookupItem[] = []; public filteredLookupItems: LookupItem[] = [];
@Input() public filteredLookupItemsObservable: Observable<LookupItem[]> = of([]);
public isLoading: boolean = false;
@ViewChild('symbolAutocomplete') symbolAutocomplete: MatAutocomplete;
@ViewChild(MatInput, { static: false })
private input: MatInput;
private unsubscribeSubject = new Subject<void>(); private unsubscribeSubject = new Subject<void>();
constructor( public constructor(
public readonly _elementRef: ElementRef, public readonly _elementRef: ElementRef,
public readonly _focusMonitor: FocusMonitor, public readonly _focusMonitor: FocusMonitor,
public readonly changeDetectorRef: ChangeDetectorRef, public readonly changeDetectorRef: ChangeDetectorRef,
@ -71,15 +73,6 @@ export class SymbolAutocompleteComponent
this.controlType = 'symbol-autocomplete'; 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 { public ngOnInit(): void {
super.required = this.ngControl.control?.hasValidator(Validators.required); super.required = this.ngControl.control?.hasValidator(Validators.required);
@ -102,10 +95,22 @@ export class SymbolAutocompleteComponent
}); });
} }
public ngOnDestroy(): void { public displayFn(aLookupItem: LookupItem) {
this.unsubscribeSubject.next(); return aLookupItem?.symbol ?? '';
this.unsubscribeSubject.complete(); }
super.ngOnDestroy();
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 { 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) { public onUpdateSymbol(event: MatAutocompleteSelectedEvent) {
super.value = { super.value = {
dataSource: event.option.value.dataSource, dataSource: event.option.value.dataSource,
@ -132,8 +129,16 @@ export class SymbolAutocompleteComponent
} as LookupItem; } as LookupItem;
} }
public isValueInOptions(value: string): boolean { public set value(value: LookupItem) {
return this.filteredLookupItems.some((item) => item.symbol === value); this.control.setValue(value);
super.value = value;
}
public ngOnDestroy(): void {
super.ngOnDestroy();
this.unsubscribeSubject.next();
this.unsubscribeSubject.complete();
} }
private validateRequired() { private validateRequired() {

2
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] schemas: [CUSTOM_ELEMENTS_SCHEMA]
}) })
export class GfSymbolAutoCompleteModule {} export class GfSymbolAutocompleteModule {}

Loading…
Cancel
Save