Compare commits

...

2 Commits

Author SHA1 Message Date
Kenrick Tandrian 69740db292
Task/improve type safety in currency selector (#6402) 3 days ago
Thomas Kaul 4cf16b8c58
Task/remove unused OnDestroy hook in license page component (#6380) 3 days ago
  1. 12
      apps/client/src/app/pages/about/license/license-page.component.ts
  2. 90
      libs/ui/src/lib/currency-selector/currency-selector.component.ts

12
apps/client/src/app/pages/about/license/license-page.component.ts

@ -1,6 +1,5 @@
import { Component, OnDestroy } from '@angular/core'; import { Component } from '@angular/core';
import { MarkdownModule } from 'ngx-markdown'; import { MarkdownModule } from 'ngx-markdown';
import { Subject } from 'rxjs';
@Component({ @Component({
imports: [MarkdownModule], imports: [MarkdownModule],
@ -8,11 +7,4 @@ import { Subject } from 'rxjs';
styleUrls: ['./license-page.scss'], styleUrls: ['./license-page.scss'],
templateUrl: './license-page.html' templateUrl: './license-page.html'
}) })
export class GfLicensePageComponent implements OnDestroy { export class GfLicensePageComponent {}
private unsubscribeSubject = new Subject<void>();
public ngOnDestroy() {
this.unsubscribeSubject.next();
this.unsubscribeSubject.complete();
}
}

90
libs/ui/src/lib/currency-selector/currency-selector.component.ts

@ -4,13 +4,16 @@ import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
DestroyRef,
DoCheck, DoCheck,
ElementRef, ElementRef,
Input,
OnDestroy,
OnInit, OnInit,
ViewChild ViewChild,
inject,
input,
viewChild
} from '@angular/core'; } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { import {
FormControl, FormControl,
FormGroupDirective, FormGroupDirective,
@ -21,15 +24,14 @@ import {
import { import {
MatAutocomplete, MatAutocomplete,
MatAutocompleteModule, MatAutocompleteModule,
MatAutocompleteSelectedEvent MatOption
} from '@angular/material/autocomplete'; } from '@angular/material/autocomplete';
import { import {
MatFormFieldControl, MatFormFieldControl,
MatFormFieldModule MatFormFieldModule
} from '@angular/material/form-field'; } from '@angular/material/form-field';
import { MatInput, MatInputModule } from '@angular/material/input'; import { MatInput, MatInputModule } from '@angular/material/input';
import { Subject } from 'rxjs'; import { map, startWith } from 'rxjs/operators';
import { map, startWith, takeUntil } from 'rxjs/operators';
import { AbstractMatFormField } from '../shared/abstract-mat-form-field'; import { AbstractMatFormField } from '../shared/abstract-mat-form-field';
@ -58,21 +60,19 @@ import { AbstractMatFormField } from '../shared/abstract-mat-form-field';
templateUrl: 'currency-selector.component.html' templateUrl: 'currency-selector.component.html'
}) })
export class GfCurrencySelectorComponent export class GfCurrencySelectorComponent
extends AbstractMatFormField<string> extends AbstractMatFormField<string | null>
implements DoCheck, OnDestroy, OnInit implements DoCheck, OnInit
{ {
@Input() private currencies: string[] = [];
@Input() private formControlName: string;
@ViewChild(MatInput) private input: MatInput;
@ViewChild('currencyAutocomplete') @ViewChild('currencyAutocomplete')
public currencyAutocomplete: MatAutocomplete; public currencyAutocomplete: MatAutocomplete;
public control = new FormControl(); public readonly control = new FormControl<string | null>(null);
public readonly currencies = input.required<string[]>();
public filteredCurrencies: string[] = []; public filteredCurrencies: string[] = [];
public readonly formControlName = input.required<string>();
private unsubscribeSubject = new Subject<void>(); private readonly destroyRef = inject(DestroyRef);
private readonly input = viewChild.required(MatInput);
public constructor( public constructor(
public readonly _elementRef: ElementRef, public readonly _elementRef: ElementRef,
@ -86,6 +86,19 @@ export class GfCurrencySelectorComponent
this.controlType = 'currency-selector'; this.controlType = 'currency-selector';
} }
public get empty() {
return this.input().empty;
}
public set value(value: string | null) {
this.control.setValue(value);
super.value = value;
}
public focus() {
this.input().focus();
}
public ngOnInit() { public ngOnInit() {
if (this.disabled) { if (this.disabled) {
this.control.disable(); this.control.disable();
@ -94,17 +107,18 @@ export class GfCurrencySelectorComponent
const formGroup = this.formGroupDirective.form; const formGroup = this.formGroupDirective.form;
if (formGroup) { if (formGroup) {
const control = formGroup.get(this.formControlName); const control = formGroup.get(this.formControlName());
if (control) { if (control) {
this.value = this.currencies.find((value) => { this.value =
return value === control.value; this.currencies().find((value) => {
}); return value === control.value;
}) ?? null;
} }
} }
this.control.valueChanges this.control.valueChanges
.pipe(takeUntil(this.unsubscribeSubject)) .pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(() => { .subscribe(() => {
if (super.value) { if (super.value) {
super.value = null; super.value = null;
@ -113,10 +127,10 @@ export class GfCurrencySelectorComponent
this.control.valueChanges this.control.valueChanges
.pipe( .pipe(
takeUntil(this.unsubscribeSubject), takeUntilDestroyed(this.destroyRef),
startWith(''), startWith(''),
map((value) => { map((value) => {
return value ? this.filter(value) : this.currencies.slice(); return value ? this.filter(value) : this.currencies().slice();
}) })
) )
.subscribe((values) => { .subscribe((values) => {
@ -124,42 +138,22 @@ export class GfCurrencySelectorComponent
}); });
} }
public get empty() {
return this.input?.empty;
}
public focus() {
this.input.focus();
}
public ngDoCheck() { public ngDoCheck() {
if (this.ngControl) { if (this.ngControl) {
this.validateRequired(); this.validateRequired();
this.errorState = this.ngControl.invalid && this.ngControl.touched; this.errorState = !!(this.ngControl.invalid && this.ngControl.touched);
this.stateChanges.next(); this.stateChanges.next();
} }
} }
public onUpdateCurrency(event: MatAutocompleteSelectedEvent) { public onUpdateCurrency({ option }: { option: MatOption<string> }) {
super.value = event.option.value; super.value = option.value;
}
public set value(value: string) {
this.control.setValue(value);
super.value = value;
}
public ngOnDestroy() {
super.ngOnDestroy();
this.unsubscribeSubject.next();
this.unsubscribeSubject.complete();
} }
private filter(value: string) { private filter(value: string) {
const filterValue = value?.toLowerCase(); const filterValue = value.toLowerCase();
return this.currencies.filter((currency) => { return this.currencies().filter((currency) => {
return currency.toLowerCase().startsWith(filterValue); return currency.toLowerCase().startsWith(filterValue);
}); });
} }
@ -168,7 +162,7 @@ export class GfCurrencySelectorComponent
const requiredCheck = super.required ? !super.value : false; const requiredCheck = super.required ? !super.value : false;
if (requiredCheck) { if (requiredCheck) {
this.ngControl.control.setErrors({ invalidData: true }); this.ngControl.control?.setErrors({ invalidData: true });
} }
} }
} }

Loading…
Cancel
Save