Browse Source

apply feedback

- Move gatherSymbol logic from admin-market-data component to create-asset-profile-dialog onSubmit method
  - Replace hardcoded 'USD' with DEFAULT_CURRENCY constant for better maintainability
  - Extend AdminData interface to include useForExchangeRates flag in dataProviders array
  - Update server-side admin service to populate useForExchangeRates based on exchange rate data source
  - Use proper exchange rate data source instead of hardcoded 'MANUAL' for currency operations
  - Improve currency handling by automatically calling gatherSymbol after currency addition
  - Clean up unused imports and fix TypeScript types
pull/5434/head
Sven Günther 4 months ago
parent
commit
ec032f3a61
  1. 5
      apps/api/src/app/admin/admin.service.ts
  2. 14
      apps/client/src/app/components/admin-market-data/admin-market-data.component.ts
  3. 46
      apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.ts
  4. 5
      libs/common/src/lib/interfaces/admin-data.interface.ts

5
apps/api/src/app/admin/admin.service.ts

@ -159,7 +159,10 @@ export class AdminService {
return {
...dataProviderInfo,
assetProfileCount
assetProfileCount,
useForExchangeRates:
dataSource ===
this.dataProviderService.getDataSourceForExchangeRates()
};
}

14
apps/client/src/app/components/admin-market-data/admin-market-data.component.ts

@ -63,7 +63,7 @@ import {
} from 'ionicons/icons';
import { DeviceDetectorService } from 'ngx-device-detector';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { Subject, of } from 'rxjs';
import { Subject } from 'rxjs';
import { distinctUntilChanged, switchMap, takeUntil } from 'rxjs/operators';
import { AdminMarketDataService } from './admin-market-data.service';
@ -480,21 +480,11 @@ export class GfAdminMarketDataComponent
dialogRef
.afterClosed()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ dataSource, symbol, isCurrency } = {}) => {
.subscribe(({ dataSource, symbol } = {}) => {
if (dataSource && symbol) {
this.adminService
.addAssetProfile({ dataSource, symbol })
.pipe(
switchMap(() => {
// Call gatherSymbol for currencies to collect historical data
if (isCurrency) {
return this.adminService.gatherSymbol({
dataSource,
symbol
});
}
return of(null);
}),
switchMap(() => {
this.isLoading = true;
this.changeDetectorRef.markForCheck();

46
apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.ts

@ -1,6 +1,7 @@
import { AdminService } from '@ghostfolio/client/services/admin.service';
import { DataService } from '@ghostfolio/client/services/data.service';
import {
DEFAULT_CURRENCY,
ghostfolioPrefix,
PROPERTY_CURRENCIES
} from '@ghostfolio/common/config';
@ -29,8 +30,9 @@ import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatRadioModule } from '@angular/material/radio';
import { DataSource } from '@prisma/client';
import { isISO4217CurrencyCode } from 'class-validator';
import { Subject, takeUntil } from 'rxjs';
import { Subject, switchMap, takeUntil } from 'rxjs';
import { CreateAssetProfileDialogMode } from './interfaces/interfaces';
@ -56,6 +58,7 @@ export class GfCreateAssetProfileDialogComponent implements OnInit, OnDestroy {
public mode: CreateAssetProfileDialogMode;
private customCurrencies: string[];
private exchangeRateDataSource: DataSource;
private unsubscribeSubject = new Subject<void>();
public constructor(
@ -68,6 +71,7 @@ export class GfCreateAssetProfileDialogComponent implements OnInit, OnDestroy {
public ngOnInit() {
this.initializeCustomCurrencies();
this.initializeExchangeRateDataSource();
this.createAssetProfileForm = this.formBuilder.group(
{
@ -115,13 +119,25 @@ export class GfCreateAssetProfileDialogComponent implements OnInit, OnDestroy {
.putAdminSetting(PROPERTY_CURRENCIES, {
value: JSON.stringify(currencies)
})
.pipe(takeUntil(this.unsubscribeSubject))
.pipe(
switchMap(() => {
// Add the currency asset profile first
return this.adminService.addAssetProfile({
dataSource: this.exchangeRateDataSource,
symbol: `${currency}${DEFAULT_CURRENCY}`
});
}),
switchMap(() => {
// Then gather historical data for the currency
return this.adminService.gatherSymbol({
dataSource: this.exchangeRateDataSource,
symbol: `${currency}${DEFAULT_CURRENCY}`
});
}),
takeUntil(this.unsubscribeSubject)
)
.subscribe(() => {
this.dialogRef.close({
dataSource: 'MANUAL',
symbol: `${currency}USD`,
isCurrency: true
});
this.dialogRef.close();
});
} else if (this.mode === 'manual') {
this.dialogRef.close({
@ -185,6 +201,22 @@ export class GfCreateAssetProfileDialogComponent implements OnInit, OnDestroy {
});
}
private initializeExchangeRateDataSource() {
this.adminService
.fetchAdminData()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ dataProviders }) => {
const exchangeRateProvider = dataProviders.find(
(provider) => provider.useForExchangeRates
);
this.exchangeRateDataSource =
exchangeRateProvider?.dataSource || DataSource.MANUAL;
this.changeDetectorRef.markForCheck();
});
}
private iso4217CurrencyCodeValidator(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
if (!isISO4217CurrencyCode(control.value?.toUpperCase())) {

5
libs/common/src/lib/interfaces/admin-data.interface.ts

@ -1,7 +1,10 @@
import { DataProviderInfo } from './data-provider-info.interface';
export interface AdminData {
dataProviders: (DataProviderInfo & { assetProfileCount: number })[];
dataProviders: (DataProviderInfo & {
assetProfileCount: number;
useForExchangeRates: boolean;
})[];
settings: { [key: string]: boolean | object | string | string[] };
transactionCount: number;
userCount: number;

Loading…
Cancel
Save