import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnDestroy, OnInit } from '@angular/core'; import { FormBuilder } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { UpdateAssetProfileDto } from '@ghostfolio/api/app/admin/update-asset-profile.dto'; import { AdminService } from '@ghostfolio/client/services/admin.service'; import { EnhancedSymbolProfile, UniqueAsset } from '@ghostfolio/common/interfaces'; import { MarketData } from '@prisma/client'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { AssetProfileDialogParams } from './interfaces/interfaces'; @Component({ host: { class: 'd-flex flex-column h-100' }, selector: 'gf-asset-profile-dialog', changeDetection: ChangeDetectionStrategy.OnPush, templateUrl: 'asset-profile-dialog.html', styleUrls: ['./asset-profile-dialog.component.scss'] }) export class AssetProfileDialog implements OnDestroy, OnInit { public assetProfile: EnhancedSymbolProfile; public assetProfileForm = this.formBuilder.group({ comment: '', symbolMapping: '' }); public countries: { [code: string]: { name: string; value: number }; }; public marketDataDetails: MarketData[] = []; public sectors: { [name: string]: { name: string; value: number }; }; private unsubscribeSubject = new Subject(); public constructor( private adminService: AdminService, private changeDetectorRef: ChangeDetectorRef, @Inject(MAT_DIALOG_DATA) public data: AssetProfileDialogParams, public dialogRef: MatDialogRef, private formBuilder: FormBuilder ) {} public ngOnInit(): void { this.initialize(); } public initialize() { this.adminService .fetchAdminMarketDataBySymbol({ dataSource: this.data.dataSource, symbol: this.data.symbol }) .pipe(takeUntil(this.unsubscribeSubject)) .subscribe(({ assetProfile, marketData }) => { this.assetProfile = assetProfile; this.countries = {}; this.marketDataDetails = marketData; this.sectors = {}; if (assetProfile?.countries?.length > 0) { for (const country of assetProfile.countries) { this.countries[country.code] = { name: country.name, value: country.weight }; } } if (assetProfile?.sectors?.length > 0) { for (const sector of assetProfile.sectors) { this.sectors[sector.name] = { name: sector.name, value: sector.weight }; } } this.assetProfileForm.setValue({ comment: this.assetProfile?.comment, symbolMapping: JSON.stringify(this.assetProfile?.symbolMapping) }); this.assetProfileForm.markAsPristine(); this.changeDetectorRef.markForCheck(); }); } public onClose(): void { this.dialogRef.close(); } public onGatherProfileDataBySymbol({ dataSource, symbol }: UniqueAsset) { this.adminService .gatherProfileDataBySymbol({ dataSource, symbol }) .pipe(takeUntil(this.unsubscribeSubject)) .subscribe(() => {}); } public onGatherSymbol({ dataSource, symbol }: UniqueAsset) { this.adminService .gatherSymbol({ dataSource, symbol }) .pipe(takeUntil(this.unsubscribeSubject)) .subscribe(() => {}); } public onMarketDataChanged(withRefresh: boolean = false) { if (withRefresh) { this.initialize(); } } public onSubmit() { let symbolMapping = {}; try { symbolMapping = JSON.parse( this.assetProfileForm.controls['symbolMapping'].value ); } catch {} const assetProfileData: UpdateAssetProfileDto = { symbolMapping, comment: this.assetProfileForm.controls['comment'].value ?? null }; this.adminService .patchAssetProfile({ ...assetProfileData, dataSource: this.data.dataSource, symbol: this.data.symbol }) .subscribe(() => { this.initialize(); }); } public ngOnDestroy() { this.unsubscribeSubject.next(); this.unsubscribeSubject.complete(); } }