Browse Source

Task/improve type safety for home market component (#6921)

* feat(client): resolve error

* feat(client): enforce encapsulation

* feat(client): enforce immutability

* feat(client): replace constructor based DI with inject function

* feat(client): replace deprecated getDeviceInfo

* feat(client): convert benchmarks to signal

* feat(client): convert historicalDataItems to signal

* feat(client): convert fearAndGreedIndex to signal
pull/6917/head
Kenrick Tandrian 3 days ago
committed by GitHub
parent
commit
7e8593e27f
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 60
      apps/client/src/app/components/home-market/home-market.component.ts
  2. 10
      apps/client/src/app/components/home-market/home-market.html

60
apps/client/src/app/components/home-market/home-market.component.ts

@ -16,9 +16,12 @@ import { DataService } from '@ghostfolio/ui/services';
import { import {
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
computed,
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
DestroyRef, DestroyRef,
OnInit inject,
OnInit,
signal
} from '@angular/core'; } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { DeviceDetectorService } from 'ngx-device-detector'; import { DeviceDetectorService } from 'ngx-device-detector';
@ -35,25 +38,27 @@ import { DeviceDetectorService } from 'ngx-device-detector';
templateUrl: './home-market.html' templateUrl: './home-market.html'
}) })
export class GfHomeMarketComponent implements OnInit { export class GfHomeMarketComponent implements OnInit {
public benchmarks: Benchmark[]; protected readonly benchmarks = signal<Benchmark[]>([]);
public deviceType: string; protected readonly deviceType = computed(
public fearAndGreedIndex: number; () => this.deviceDetectorService.deviceInfo().deviceType
public fearLabel = $localize`Fear`; );
public greedLabel = $localize`Greed`; protected readonly fearAndGreedIndex = signal<number | undefined>(undefined);
public hasPermissionToAccessFearAndGreedIndex: boolean; protected readonly fearLabel = $localize`Fear`;
public historicalDataItems: HistoricalDataItem[]; protected readonly greedLabel = $localize`Greed`;
public info: InfoItem; protected hasPermissionToAccessFearAndGreedIndex: boolean;
public readonly numberOfDays = 365; protected readonly historicalDataItems = signal<HistoricalDataItem[]>([]);
public user: User; protected readonly numberOfDays = 365;
protected user: User;
public constructor( private readonly info: InfoItem;
private changeDetectorRef: ChangeDetectorRef,
private dataService: DataService, private readonly changeDetectorRef = inject(ChangeDetectorRef);
private destroyRef: DestroyRef, private readonly dataService = inject(DataService);
private deviceDetectorService: DeviceDetectorService, private readonly destroyRef = inject(DestroyRef);
private userService: UserService private readonly deviceDetectorService = inject(DeviceDetectorService);
) { private readonly userService = inject(UserService);
this.deviceType = this.deviceDetectorService.getDeviceInfo().deviceType;
public constructor() {
this.info = this.dataService.fetchInfo(); this.info = this.dataService.fetchInfo();
this.userService.stateChanged this.userService.stateChanged
@ -73,7 +78,10 @@ export class GfHomeMarketComponent implements OnInit {
permissions.enableFearAndGreedIndex permissions.enableFearAndGreedIndex
); );
if (this.hasPermissionToAccessFearAndGreedIndex) { if (
this.hasPermissionToAccessFearAndGreedIndex &&
this.info.fearAndGreedDataSource
) {
this.dataService this.dataService
.fetchSymbolItem({ .fetchSymbolItem({
dataSource: this.info.fearAndGreedDataSource, dataSource: this.info.fearAndGreedDataSource,
@ -82,16 +90,14 @@ export class GfHomeMarketComponent implements OnInit {
}) })
.pipe(takeUntilDestroyed(this.destroyRef)) .pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(({ historicalData, marketPrice }) => { .subscribe(({ historicalData, marketPrice }) => {
this.fearAndGreedIndex = marketPrice; this.fearAndGreedIndex.set(marketPrice);
this.historicalDataItems = [ this.historicalDataItems.set([
...historicalData, ...historicalData,
{ {
date: resetHours(new Date()).toISOString(), date: resetHours(new Date()).toISOString(),
value: marketPrice value: marketPrice
} }
]; ]);
this.changeDetectorRef.markForCheck();
}); });
} }
@ -99,9 +105,7 @@ export class GfHomeMarketComponent implements OnInit {
.fetchBenchmarks() .fetchBenchmarks()
.pipe(takeUntilDestroyed(this.destroyRef)) .pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(({ benchmarks }) => { .subscribe(({ benchmarks }) => {
this.benchmarks = benchmarks; this.benchmarks.set(benchmarks);
this.changeDetectorRef.markForCheck();
}); });
} }
} }

10
apps/client/src/app/components/home-market/home-market.html

@ -10,7 +10,7 @@
class="mb-3" class="mb-3"
label="Fear & Greed Index" label="Fear & Greed Index"
[colorScheme]="user?.settings?.colorScheme" [colorScheme]="user?.settings?.colorScheme"
[historicalDataItems]="historicalDataItems" [historicalDataItems]="historicalDataItems()"
[isAnimated]="true" [isAnimated]="true"
[locale]="user?.settings?.locale || undefined" [locale]="user?.settings?.locale || undefined"
[showXAxis]="true" [showXAxis]="true"
@ -22,7 +22,7 @@
/> />
<gf-fear-and-greed-index <gf-fear-and-greed-index
class="d-flex justify-content-center" class="d-flex justify-content-center"
[fearAndGreedIndex]="fearAndGreedIndex" [fearAndGreedIndex]="fearAndGreedIndex()"
/> />
</div> </div>
</div> </div>
@ -31,13 +31,13 @@
<div class="mb-3 row"> <div class="mb-3 row">
<div class="col-xs-12 col-md-10 offset-md-1"> <div class="col-xs-12 col-md-10 offset-md-1">
<gf-benchmark <gf-benchmark
[benchmarks]="benchmarks" [benchmarks]="benchmarks()"
[deviceType]="deviceType" [deviceType]="deviceType()"
[locale]="user?.settings?.locale || undefined" [locale]="user?.settings?.locale || undefined"
[showSymbol]="false" [showSymbol]="false"
[user]="user" [user]="user"
/> />
@if (benchmarks?.length > 0) { @if (benchmarks()?.length > 0) {
<div <div
class="gf-text-wrap-balance line-height-1 mt-3 text-center text-muted" class="gf-text-wrap-balance line-height-1 mt-3 text-center text-muted"
> >

Loading…
Cancel
Save