Browse Source

Refactoring

pull/4281/head
Thomas Kaul 7 months ago
parent
commit
31642740a2
  1. 5
      apps/api/src/app/user/user.service.ts
  2. 71
      apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts
  3. 34
      apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html

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

@ -333,7 +333,10 @@ export class UserService {
currentPermissions, currentPermissions,
permissions.accessHoldingsChart, permissions.accessHoldingsChart,
permissions.createAccess, permissions.createAccess,
permissions.readAiPrompt permissions.createMarketDataOfOwnAssetProfile,
permissions.readAiPrompt,
permissions.readMarketDataOfOwnAssetProfile,
permissions.updateMarketDataOfOwnAssetProfile
); );
// Reset benchmark // Reset benchmark

71
apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts

@ -3,6 +3,7 @@ import { GfAccountsTableModule } from '@ghostfolio/client/components/accounts-ta
import { GfDialogFooterModule } from '@ghostfolio/client/components/dialog-footer/dialog-footer.module'; import { GfDialogFooterModule } from '@ghostfolio/client/components/dialog-footer/dialog-footer.module';
import { GfDialogHeaderModule } from '@ghostfolio/client/components/dialog-header/dialog-header.module'; import { GfDialogHeaderModule } from '@ghostfolio/client/components/dialog-header/dialog-header.module';
import { DataService } from '@ghostfolio/client/services/data.service'; import { DataService } from '@ghostfolio/client/services/data.service';
import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service';
import { UserService } from '@ghostfolio/client/services/user/user.service'; import { UserService } from '@ghostfolio/client/services/user/user.service';
import { NUMERICAL_PRECISION_THRESHOLD } from '@ghostfolio/common/config'; import { NUMERICAL_PRECISION_THRESHOLD } from '@ghostfolio/common/config';
import { DATE_FORMAT, downloadAsFile } from '@ghostfolio/common/helper'; import { DATE_FORMAT, downloadAsFile } from '@ghostfolio/common/helper';
@ -13,6 +14,7 @@ import {
LineChartItem, LineChartItem,
User User
} from '@ghostfolio/common/interfaces'; } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table'; import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table';
import { GfDataProviderCreditsComponent } from '@ghostfolio/ui/data-provider-credits'; import { GfDataProviderCreditsComponent } from '@ghostfolio/ui/data-provider-credits';
import { GfHistoricalMarketDataEditorComponent } from '@ghostfolio/ui/historical-market-data-editor'; import { GfHistoricalMarketDataEditorComponent } from '@ghostfolio/ui/historical-market-data-editor';
@ -97,6 +99,7 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit {
public dividendYieldPercentWithCurrencyEffect: number; public dividendYieldPercentWithCurrencyEffect: number;
public feeInBaseCurrency: number; public feeInBaseCurrency: number;
public firstBuyDate: string; public firstBuyDate: string;
public hasPermissionToReadMarketDataOfOwnAssetProfile: boolean;
public historicalDataItems: LineChartItem[]; public historicalDataItems: LineChartItem[];
public investment: number; public investment: number;
public investmentPrecision = 2; public investmentPrecision = 2;
@ -126,6 +129,7 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit {
public user: User; public user: User;
public value: number; public value: number;
private hasImpersonationId: boolean;
private unsubscribeSubject = new Subject<void>(); private unsubscribeSubject = new Subject<void>();
public constructor( public constructor(
@ -134,6 +138,7 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit {
public dialogRef: MatDialogRef<GfHoldingDetailDialogComponent>, public dialogRef: MatDialogRef<GfHoldingDetailDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: HoldingDetailDialogParams, @Inject(MAT_DIALOG_DATA) public data: HoldingDetailDialogParams,
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
private impersonationStorageService: ImpersonationStorageService,
private router: Router, private router: Router,
private userService: UserService private userService: UserService
) {} ) {}
@ -234,6 +239,15 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit {
this.feeInBaseCurrency = feeInBaseCurrency; this.feeInBaseCurrency = feeInBaseCurrency;
this.firstBuyDate = firstBuyDate; this.firstBuyDate = firstBuyDate;
this.hasPermissionToReadMarketDataOfOwnAssetProfile =
!this.hasImpersonationId &&
hasPermission(
this.user?.permissions,
permissions.readMarketDataOfOwnAssetProfile
) &&
SymbolProfile?.dataSource === 'MANUAL' &&
SymbolProfile?.userId === this.user?.id;
this.historicalDataItems = historicalData.map( this.historicalDataItems = historicalData.map(
({ averagePrice, date, marketPrice }) => { ({ averagePrice, date, marketPrice }) => {
this.benchmarkDataItems.push({ this.benchmarkDataItems.push({
@ -395,11 +409,22 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit {
}; };
} }
); );
this.fetchMarketData();
if (this.hasPermissionToReadMarketDataOfOwnAssetProfile) {
this.fetchMarketData();
}
this.changeDetectorRef.markForCheck(); this.changeDetectorRef.markForCheck();
} }
); );
this.impersonationStorageService
.onChangeHasImpersonation()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((impersonationId) => {
this.hasImpersonationId = !!impersonationId;
});
this.userService.stateChanged this.userService.stateChanged
.pipe(takeUntil(this.unsubscribeSubject)) .pipe(takeUntil(this.unsubscribeSubject))
.subscribe((state) => { .subscribe((state) => {
@ -451,26 +476,7 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit {
}); });
} }
public fetchMarketData() { public onMarketDataChanged(withRefresh = false) {
this.dataService
.fetchMarketDataBySymbol({
dataSource: this.data.dataSource,
symbol: this.data.symbol
})
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ marketData }) => {
this.marketDataItems = marketData;
this.historicalDataItems = marketData.map(({ date, marketPrice }) => {
return {
date: format(date, DATE_FORMAT),
value: marketPrice
};
});
this.changeDetectorRef.markForCheck();
});
}
public onMarketDataChanged(withRefresh: boolean = false) {
if (withRefresh) { if (withRefresh) {
this.fetchMarketData(); this.fetchMarketData();
} }
@ -492,4 +498,27 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit {
this.unsubscribeSubject.next(); this.unsubscribeSubject.next();
this.unsubscribeSubject.complete(); this.unsubscribeSubject.complete();
} }
private fetchMarketData() {
this.dataService
.fetchMarketDataBySymbol({
dataSource: this.data.dataSource,
symbol: this.data.symbol
})
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ marketData }) => {
this.marketDataItems = marketData;
this.historicalDataItems = this.marketDataItems.map(
({ date, marketPrice }) => {
return {
date: format(date, DATE_FORMAT),
value: marketPrice
};
}
);
this.changeDetectorRef.markForCheck();
});
}
} }

34
apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html

@ -364,22 +364,24 @@
[showValueInBaseCurrency]="false" [showValueInBaseCurrency]="false"
/> />
</mat-tab> </mat-tab>
<mat-tab> @if (hasPermissionToReadMarketDataOfOwnAssetProfile) {
<ng-template mat-tab-label> <mat-tab>
<ion-icon name="server-outline" /> <ng-template mat-tab-label>
<div class="d-none d-sm-block ml-2" i18n>Market Data</div> <ion-icon name="server-outline" />
</ng-template> <div class="d-none d-sm-block ml-2" i18n>Market Data</div>
<gf-historical-market-data-editor </ng-template>
[currency]="SymbolProfile?.currency" <gf-historical-market-data-editor
[dataSource]="SymbolProfile?.dataSource" [currency]="SymbolProfile?.currency"
[dateOfFirstActivity]="firstBuyDate" [dataSource]="SymbolProfile?.dataSource"
[locale]="data.locale" [dateOfFirstActivity]="firstBuyDate"
[marketData]="marketDataItems" [locale]="data.locale"
[symbol]="SymbolProfile?.symbol" [marketData]="marketDataItems"
[user]="user" [symbol]="SymbolProfile?.symbol"
(marketDataChanged)="onMarketDataChanged($event)" [user]="user"
/> (marketDataChanged)="onMarketDataChanged($event)"
</mat-tab> />
</mat-tab>
}
</mat-tab-group> </mat-tab-group>
<gf-tags-selector <gf-tags-selector

Loading…
Cancel
Save