Browse Source

Task/improve type safety in multiple client components (#7302)

Improve type safety
pull/6947/merge
Kenrick Tandrian 2 days ago
committed by GitHub
parent
commit
6c74aeb436
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 51
      apps/client/src/app/components/home-holdings/home-holdings.component.ts
  2. 79
      apps/client/src/app/components/user-account-settings/user-account-settings.component.ts
  3. 4
      apps/client/src/app/components/user-detail-dialog/user-detail-dialog.component.ts

51
apps/client/src/app/components/home-holdings/home-holdings.component.ts

@ -20,6 +20,7 @@ import {
Component, Component,
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
DestroyRef, DestroyRef,
inject,
OnInit OnInit
} from '@angular/core'; } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@ -53,32 +54,34 @@ import { DeviceDetectorService } from 'ngx-device-detector';
export class GfHomeHoldingsComponent implements OnInit { export class GfHomeHoldingsComponent implements OnInit {
public static DEFAULT_HOLDINGS_VIEW_MODE: HoldingsViewMode = 'TABLE'; public static DEFAULT_HOLDINGS_VIEW_MODE: HoldingsViewMode = 'TABLE';
public deviceType: string; protected deviceType: string;
public hasImpersonationId: boolean; protected hasImpersonationId: boolean;
public hasPermissionToAccessHoldingsChart: boolean; protected hasPermissionToAccessHoldingsChart: boolean;
public hasPermissionToCreateActivity: boolean; protected hasPermissionToCreateActivity: boolean;
public holdings: PortfolioPosition[]; protected holdings: PortfolioPosition[];
public holdingType: HoldingType = 'ACTIVE'; protected holdingType: HoldingType = 'ACTIVE';
public holdingTypeOptions: ToggleOption[] = [ protected readonly holdingTypeOptions: ToggleOption[] = [
{ label: $localize`Active`, value: 'ACTIVE' }, { label: $localize`Active`, value: 'ACTIVE' },
{ label: $localize`Closed`, value: 'CLOSED' } { label: $localize`Closed`, value: 'CLOSED' }
]; ];
public routerLinkPortfolioActivities = protected readonly routerLinkPortfolioActivities =
internalRoutes.portfolio.subRoutes.activities.routerLink; internalRoutes.portfolio.subRoutes.activities.routerLink;
public user: User; protected user: User;
public viewModeFormControl = new FormControl<HoldingsViewMode>( protected readonly viewModeFormControl = new FormControl<HoldingsViewMode>(
GfHomeHoldingsComponent.DEFAULT_HOLDINGS_VIEW_MODE GfHomeHoldingsComponent.DEFAULT_HOLDINGS_VIEW_MODE
); );
public constructor( private readonly changeDetectorRef = inject(ChangeDetectorRef);
private changeDetectorRef: ChangeDetectorRef, private readonly dataService = inject(DataService);
private dataService: DataService, private readonly destroyRef = inject(DestroyRef);
private destroyRef: DestroyRef, private readonly deviceDetectorService = inject(DeviceDetectorService);
private deviceDetectorService: DeviceDetectorService, private readonly impersonationStorageService = inject(
private impersonationStorageService: ImpersonationStorageService, ImpersonationStorageService
private router: Router, );
private userService: UserService private readonly router = inject(Router);
) { private readonly userService = inject(UserService);
public constructor() {
addIcons({ gridOutline, reorderFourOutline }); addIcons({ gridOutline, reorderFourOutline });
} }
@ -119,6 +122,10 @@ export class GfHomeHoldingsComponent implements OnInit {
this.viewModeFormControl.valueChanges this.viewModeFormControl.valueChanges
.pipe(takeUntilDestroyed(this.destroyRef)) .pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((holdingsViewMode) => { .subscribe((holdingsViewMode) => {
if (!holdingsViewMode) {
return;
}
this.dataService this.dataService
.putUserSetting({ holdingsViewMode }) .putUserSetting({ holdingsViewMode })
.pipe(takeUntilDestroyed(this.destroyRef)) .pipe(takeUntilDestroyed(this.destroyRef))
@ -135,13 +142,13 @@ export class GfHomeHoldingsComponent implements OnInit {
}); });
} }
public onChangeHoldingType(aHoldingType: HoldingType) { protected onChangeHoldingType(aHoldingType: HoldingType) {
this.holdingType = aHoldingType; this.holdingType = aHoldingType;
this.initialize(); this.initialize();
} }
public onHoldingClicked({ dataSource, symbol }: AssetProfileIdentifier) { protected onHoldingClicked({ dataSource, symbol }: AssetProfileIdentifier) {
if (dataSource && symbol) { if (dataSource && symbol) {
this.router.navigate([], { this.router.navigate([], {
queryParams: { dataSource, symbol, holdingDetailDialog: true } queryParams: { dataSource, symbol, holdingDetailDialog: true }
@ -185,7 +192,7 @@ export class GfHomeHoldingsComponent implements OnInit {
); );
} }
this.holdings = undefined; this.holdings = [];
this.fetchHoldings() this.fetchHoldings()
.pipe(takeUntilDestroyed(this.destroyRef)) .pipe(takeUntilDestroyed(this.destroyRef))

79
apps/client/src/app/components/user-account-settings/user-account-settings.component.ts

@ -20,11 +20,12 @@ import {
Component, Component,
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
DestroyRef, DestroyRef,
inject,
OnInit OnInit
} from '@angular/core'; } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { import {
FormBuilder, NonNullableFormBuilder,
FormsModule, FormsModule,
ReactiveFormsModule, ReactiveFormsModule,
Validators Validators
@ -69,22 +70,22 @@ import { catchError } from 'rxjs/operators';
templateUrl: './user-account-settings.html' templateUrl: './user-account-settings.html'
}) })
export class GfUserAccountSettingsComponent implements OnInit { export class GfUserAccountSettingsComponent implements OnInit {
public appearancePlaceholder = $localize`Auto`; protected readonly appearancePlaceholder = $localize`Auto`;
public baseCurrency: string; protected readonly baseCurrency: string;
public closeUserAccountMail: string; protected closeUserAccountMail: string;
public currencies: string[] = []; protected readonly currencies: string[] = [];
public deleteOwnUserForm = this.formBuilder.group({ protected readonly deleteOwnUserForm = inject(NonNullableFormBuilder).group({
accessToken: ['', Validators.required] accessToken: ['', Validators.required]
}); });
public hasPermissionToDeleteOwnUser: boolean; protected hasPermissionToDeleteOwnUser: boolean;
public hasPermissionToRequestOwnUserDeletion: boolean; protected hasPermissionToRequestOwnUserDeletion: boolean;
public hasPermissionToUpdateViewMode: boolean; protected hasPermissionToUpdateViewMode: boolean;
public hasPermissionToUpdateUserSettings: boolean; protected hasPermissionToUpdateUserSettings: boolean;
public isAccessTokenHidden = true; protected isAccessTokenHidden = true;
public isFingerprintSupported = this.doesBrowserSupportAuthn(); protected readonly isFingerprintSupported = this.doesBrowserSupportAuthn();
public isWebAuthnEnabled: boolean; protected isWebAuthnEnabled: boolean;
public language = document.documentElement.lang; protected readonly language = document.documentElement.lang;
public locales = [ protected locales = [
'ca', 'ca',
'de', 'de',
'de-CH', 'de-CH',
@ -102,19 +103,18 @@ export class GfUserAccountSettingsComponent implements OnInit {
'uk', 'uk',
'zh' 'zh'
]; ];
public user: User; protected user: User;
public constructor( private readonly changeDetectorRef = inject(ChangeDetectorRef);
private changeDetectorRef: ChangeDetectorRef, private readonly dataService = inject(DataService);
private dataService: DataService, private readonly destroyRef = inject(DestroyRef);
private destroyRef: DestroyRef, private readonly notificationService = inject(NotificationService);
private formBuilder: FormBuilder, private readonly settingsStorageService = inject(SettingsStorageService);
private notificationService: NotificationService, private readonly snackBar = inject(MatSnackBar);
private settingsStorageService: SettingsStorageService, private readonly userService = inject(UserService);
private snackBar: MatSnackBar, private readonly webAuthnService = inject(WebAuthnService);
private userService: UserService,
public webAuthnService: WebAuthnService public constructor() {
) {
const { baseCurrency, currencies } = this.dataService.fetchInfo(); const { baseCurrency, currencies } = this.dataService.fetchInfo();
this.baseCurrency = baseCurrency; this.baseCurrency = baseCurrency;
@ -148,7 +148,10 @@ export class GfUserAccountSettingsComponent implements OnInit {
permissions.updateViewMode permissions.updateViewMode
); );
if (this.user.settings.locale) {
this.locales.push(this.user.settings.locale); this.locales.push(this.user.settings.locale);
}
this.locales = Array.from(new Set(this.locales)).sort(); this.locales = Array.from(new Set(this.locales)).sort();
this.changeDetectorRef.markForCheck(); this.changeDetectorRef.markForCheck();
@ -162,11 +165,11 @@ export class GfUserAccountSettingsComponent implements OnInit {
this.update(); this.update();
} }
public isCommunityLanguage() { protected isCommunityLanguage() {
return !['de', 'en'].includes(this.language); return !['de', 'en'].includes(this.language);
} }
public onChangeUserSetting(aKey: string, aValue: string) { protected onChangeUserSetting(aKey: string, aValue: string) {
this.dataService this.dataService
.putUserSetting({ [aKey]: aValue }) .putUserSetting({ [aKey]: aValue })
.pipe(takeUntilDestroyed(this.destroyRef)) .pipe(takeUntilDestroyed(this.destroyRef))
@ -190,12 +193,12 @@ export class GfUserAccountSettingsComponent implements OnInit {
}); });
} }
public onCloseAccount() { protected onCloseAccount() {
this.notificationService.confirm({ this.notificationService.confirm({
confirmFn: () => { confirmFn: () => {
this.dataService this.dataService
.deleteOwnUser({ .deleteOwnUser({
accessToken: this.deleteOwnUserForm.get('accessToken').value accessToken: this.deleteOwnUserForm.controls.accessToken.value
}) })
.pipe( .pipe(
catchError(() => { catchError(() => {
@ -218,7 +221,7 @@ export class GfUserAccountSettingsComponent implements OnInit {
}); });
} }
public onExperimentalFeaturesChange(aEvent: MatSlideToggleChange) { protected onExperimentalFeaturesChange(aEvent: MatSlideToggleChange) {
this.dataService this.dataService
.putUserSetting({ isExperimentalFeatures: aEvent.checked }) .putUserSetting({ isExperimentalFeatures: aEvent.checked })
.pipe(takeUntilDestroyed(this.destroyRef)) .pipe(takeUntilDestroyed(this.destroyRef))
@ -234,13 +237,13 @@ export class GfUserAccountSettingsComponent implements OnInit {
}); });
} }
public onExport() { protected onExport() {
this.dataService this.dataService
.fetchExport() .fetchExport()
.pipe(takeUntilDestroyed(this.destroyRef)) .pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((data) => { .subscribe((data) => {
for (const activity of data.activities) { for (const activity of data.activities) {
delete activity.id; delete (activity as Omit<typeof activity, 'id'> & { id?: string }).id;
} }
downloadAsFile({ downloadAsFile({
@ -254,7 +257,7 @@ export class GfUserAccountSettingsComponent implements OnInit {
}); });
} }
public onRestrictedViewChange(aEvent: MatSlideToggleChange) { protected onRestrictedViewChange(aEvent: MatSlideToggleChange) {
this.dataService this.dataService
.putUserSetting({ isRestrictedView: aEvent.checked }) .putUserSetting({ isRestrictedView: aEvent.checked })
.pipe(takeUntilDestroyed(this.destroyRef)) .pipe(takeUntilDestroyed(this.destroyRef))
@ -270,7 +273,7 @@ export class GfUserAccountSettingsComponent implements OnInit {
}); });
} }
public async onSignInWithFingerprintChange(aEvent: MatSlideToggleChange) { protected async onSignInWithFingerprintChange(aEvent: MatSlideToggleChange) {
if (aEvent.checked) { if (aEvent.checked) {
try { try {
await this.registerDevice(); await this.registerDevice();
@ -293,7 +296,7 @@ export class GfUserAccountSettingsComponent implements OnInit {
} }
} }
public onViewModeChange(aEvent: MatSlideToggleChange) { protected onViewModeChange(aEvent: MatSlideToggleChange) {
this.dataService this.dataService
.putUserSetting({ viewMode: aEvent.checked === true ? 'ZEN' : 'DEFAULT' }) .putUserSetting({ viewMode: aEvent.checked === true ? 'ZEN' : 'DEFAULT' })
.pipe(takeUntilDestroyed(this.destroyRef)) .pipe(takeUntilDestroyed(this.destroyRef))

4
apps/client/src/app/components/user-detail-dialog/user-detail-dialog.component.ts

@ -49,7 +49,7 @@ import {
templateUrl: './user-detail-dialog.html' templateUrl: './user-detail-dialog.html'
}) })
export class GfUserDetailDialogComponent implements OnInit { export class GfUserDetailDialogComponent implements OnInit {
protected baseCurrency: string; protected readonly baseCurrency: string;
protected readonly getCountryName = getCountryName; protected readonly getCountryName = getCountryName;
protected readonly subscriptionsDataSource = protected readonly subscriptionsDataSource =
new MatTableDataSource<Subscription>(); new MatTableDataSource<Subscription>();
@ -114,7 +114,7 @@ export class GfUserDetailDialogComponent implements OnInit {
return price !== null; return price !== null;
}) })
.map(({ price }) => { .map(({ price }) => {
return new Big(price); return new Big(price ?? 0);
}) })
).toNumber(); ).toNumber();
} }

Loading…
Cancel
Save