diff --git a/apps/client/src/app/components/home-watchlist/create-watchlist-item-dialog/create-watchlist-item-dialog.component.ts b/apps/client/src/app/components/home-watchlist/create-watchlist-item-dialog/create-watchlist-item-dialog.component.ts index 4669a827d..847b2d4ab 100644 --- a/apps/client/src/app/components/home-watchlist/create-watchlist-item-dialog/create-watchlist-item-dialog.component.ts +++ b/apps/client/src/app/components/home-watchlist/create-watchlist-item-dialog/create-watchlist-item-dialog.component.ts @@ -1,9 +1,8 @@ +import type { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; import { GfSymbolAutocompleteComponent } from '@ghostfolio/ui/symbol-autocomplete'; -import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; import { - AbstractControl, - FormBuilder, FormControl, FormGroup, FormsModule, @@ -15,6 +14,8 @@ import { MatButtonModule } from '@angular/material/button'; import { MatDialogModule, MatDialogRef } from '@angular/material/dialog'; import { MatFormFieldModule } from '@angular/material/form-field'; +import { CreateWatchlistItemForm } from './interfaces/interfaces'; + @Component({ changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'h-100' }, @@ -30,44 +31,41 @@ import { MatFormFieldModule } from '@angular/material/form-field'; styleUrls: ['./create-watchlist-item-dialog.component.scss'], templateUrl: 'create-watchlist-item-dialog.html' }) -export class GfCreateWatchlistItemDialogComponent implements OnInit { - public createWatchlistItemForm: FormGroup; - - public constructor( - public readonly dialogRef: MatDialogRef, - public readonly formBuilder: FormBuilder - ) {} - - public ngOnInit() { - this.createWatchlistItemForm = this.formBuilder.group( +export class GfCreateWatchlistItemDialogComponent { + protected readonly createWatchlistItemForm: CreateWatchlistItemForm = + new FormGroup( { - searchSymbol: new FormControl(null, [Validators.required]) + searchSymbol: new FormControl(null, [ + Validators.required + ]) }, { validators: this.validator } ); - } - public onCancel() { + private readonly dialogRef = + inject>(MatDialogRef); + + protected onCancel() { this.dialogRef.close(); } - public onSubmit() { + protected onSubmit() { this.dialogRef.close({ dataSource: - this.createWatchlistItemForm.get('searchSymbol').value.dataSource, - symbol: this.createWatchlistItemForm.get('searchSymbol').value.symbol + this.createWatchlistItemForm.controls.searchSymbol.value?.dataSource, + symbol: this.createWatchlistItemForm.controls.searchSymbol.value?.symbol }); } - private validator(control: AbstractControl): ValidationErrors { - const searchSymbolControl = control.get('searchSymbol'); + private validator(control: CreateWatchlistItemForm): ValidationErrors { + const searchSymbolControl = control.controls.searchSymbol; if ( searchSymbolControl.valid && - searchSymbolControl.value.dataSource && - searchSymbolControl.value.symbol + searchSymbolControl.value?.dataSource && + searchSymbolControl.value?.symbol ) { return { incomplete: false }; } diff --git a/apps/client/src/app/components/home-watchlist/create-watchlist-item-dialog/interfaces/interfaces.ts b/apps/client/src/app/components/home-watchlist/create-watchlist-item-dialog/interfaces/interfaces.ts index c0f74d022..965331326 100644 --- a/apps/client/src/app/components/home-watchlist/create-watchlist-item-dialog/interfaces/interfaces.ts +++ b/apps/client/src/app/components/home-watchlist/create-watchlist-item-dialog/interfaces/interfaces.ts @@ -1,4 +1,12 @@ +import type { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; + +import type { FormControl, FormGroup } from '@angular/forms'; + export interface CreateWatchlistItemDialogParams { deviceType: string; locale: string; } + +export type CreateWatchlistItemForm = FormGroup<{ + searchSymbol: FormControl; +}>; diff --git a/apps/client/src/app/components/home-watchlist/home-watchlist.component.ts b/apps/client/src/app/components/home-watchlist/home-watchlist.component.ts index e6f366351..7deace7de 100644 --- a/apps/client/src/app/components/home-watchlist/home-watchlist.component.ts +++ b/apps/client/src/app/components/home-watchlist/home-watchlist.component.ts @@ -1,5 +1,6 @@ import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; +import { locale as defaultLocale } from '@ghostfolio/common/config'; import { AssetProfileIdentifier, Benchmark, @@ -14,8 +15,10 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, + computed, CUSTOM_ELEMENTS_SCHEMA, DestroyRef, + inject, OnInit } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; @@ -45,26 +48,29 @@ import { CreateWatchlistItemDialogParams } from './create-watchlist-item-dialog/ templateUrl: './home-watchlist.html' }) export class GfHomeWatchlistComponent implements OnInit { - public deviceType: string; - public hasImpersonationId: boolean; - public hasPermissionToCreateWatchlistItem: boolean; - public hasPermissionToDeleteWatchlistItem: boolean; - public user: User; - public watchlist: Benchmark[]; - - public constructor( - private changeDetectorRef: ChangeDetectorRef, - private dataService: DataService, - private destroyRef: DestroyRef, - private deviceService: DeviceDetectorService, - private dialog: MatDialog, - private impersonationStorageService: ImpersonationStorageService, - private route: ActivatedRoute, - private router: Router, - private userService: UserService - ) { - this.deviceType = this.deviceService.getDeviceInfo().deviceType; - + protected hasImpersonationId: boolean; + protected hasPermissionToCreateWatchlistItem: boolean; + protected hasPermissionToDeleteWatchlistItem: boolean; + protected user: User; + protected watchlist: Benchmark[]; + + protected readonly deviceType = computed( + () => this.deviceDetectorService.deviceInfo().deviceType + ); + + private readonly changeDetectorRef = inject(ChangeDetectorRef); + private readonly dataService = inject(DataService); + private readonly destroyRef = inject(DestroyRef); + private readonly deviceDetectorService = inject(DeviceDetectorService); + private readonly dialog = inject(MatDialog); + private readonly impersonationStorageService = inject( + ImpersonationStorageService + ); + private readonly route = inject(ActivatedRoute); + private readonly router = inject(Router); + private readonly userService = inject(UserService); + + public constructor() { this.impersonationStorageService .onChangeHasImpersonation() .pipe(takeUntilDestroyed(this.destroyRef)) @@ -110,7 +116,7 @@ export class GfHomeWatchlistComponent implements OnInit { this.loadWatchlistData(); } - public onWatchlistItemDeleted({ + protected onWatchlistItemDeleted({ dataSource, symbol }: AssetProfileIdentifier) { @@ -148,10 +154,10 @@ export class GfHomeWatchlistComponent implements OnInit { >(GfCreateWatchlistItemDialogComponent, { autoFocus: false, data: { - deviceType: this.deviceType, - locale: this.user?.settings?.locale + deviceType: this.deviceType(), + locale: this.user?.settings?.locale ?? defaultLocale }, - width: this.deviceType === 'mobile' ? '100vw' : '50rem' + width: this.deviceType() === 'mobile' ? '100vw' : '50rem' }); dialogRef diff --git a/apps/client/src/app/components/home-watchlist/home-watchlist.html b/apps/client/src/app/components/home-watchlist/home-watchlist.html index 743d86c37..a17259000 100644 --- a/apps/client/src/app/components/home-watchlist/home-watchlist.html +++ b/apps/client/src/app/components/home-watchlist/home-watchlist.html @@ -11,7 +11,7 @@