Browse Source

MR Feedback

pull/4370/head
Dan 4 months ago
parent
commit
eb83ffcb56
  1. 10
      apps/api/src/app/portfolio/portfolio.controller.ts
  2. 5
      apps/client/src/app/components/home-holdings/home-holdings.component.ts
  3. 1
      apps/client/src/app/components/home-holdings/home-holdings.html
  4. 6
      libs/common/src/lib/interfaces/responses/portfolio-holdings-response.interface.ts
  5. 14
      libs/ui/src/lib/holdings-table/holdings-table.component.html
  6. 18
      libs/ui/src/lib/holdings-table/holdings-table.component.ts

10
apps/api/src/app/portfolio/portfolio.controller.ts

@ -389,6 +389,14 @@ export class PortfolioController {
filterByTags
});
const { performance } = await this.portfolioService.getPerformance({
dateRange,
filters,
impersonationId,
userId: this.request.user.id,
withExcludedAccounts: false
});
const { holdings } = await this.portfolioService.getDetails({
dateRange,
filters,
@ -396,7 +404,7 @@ export class PortfolioController {
userId: this.request.user.id
});
return { holdings: Object.values(holdings) };
return { holdings: Object.values(holdings), performance };
}
@Get('investments')

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

@ -3,6 +3,7 @@ import { ImpersonationStorageService } from '@ghostfolio/client/services/imperso
import { UserService } from '@ghostfolio/client/services/user/user.service';
import {
AssetProfileIdentifier,
PortfolioPerformance,
PortfolioPosition,
ToggleOption,
User
@ -36,6 +37,7 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit {
{ label: $localize`Active`, value: 'ACTIVE' },
{ label: $localize`Closed`, value: 'CLOSED' }
];
public performance: PortfolioPerformance;
public user: User;
public viewModeFormControl = new FormControl<HoldingsViewMode>(
HomeHoldingsComponent.DEFAULT_HOLDINGS_VIEW_MODE
@ -162,8 +164,9 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit {
this.fetchHoldings()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ holdings }) => {
.subscribe(({ holdings, performance }) => {
this.holdings = holdings;
this.performance = performance;
this.changeDetectorRef.markForCheck();
});

1
apps/client/src/app/components/home-holdings/home-holdings.html

@ -51,6 +51,7 @@
[hasPermissionToCreateActivity]="hasPermissionToCreateOrder"
[holdings]="holdings"
[locale]="user?.settings?.locale"
[performance]="performance"
(holdingClicked)="onHoldingClicked($event)"
/>
@if (hasPermissionToCreateOrder && holdings?.length > 0) {

6
libs/common/src/lib/interfaces/responses/portfolio-holdings-response.interface.ts

@ -1,5 +1,9 @@
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
import {
PortfolioPerformance,
PortfolioPosition
} from '@ghostfolio/common/interfaces';
export interface PortfolioHoldingsResponse {
holdings: PortfolioPosition[];
performance: PortfolioPerformance;
}

14
libs/ui/src/lib/holdings-table/holdings-table.component.html

@ -39,7 +39,7 @@
<small class="text-muted">{{ element.symbol }}</small>
</div>
</td>
<td *matFooterCellDef class="px-1" mat-footer-cell>Total</td>
<td *matFooterCellDef class="px-1" i18n mat-footer-cell>Total</td>
</ng-container>
<ng-container matColumnDef="dateOfFirstActivity">
@ -95,11 +95,7 @@
</td>
<td *matFooterCellDef class="d-none d-lg-table-cell px-1" mat-footer-cell>
<gf-value
[isCurrency]="true"
[locale]="locale"
[value]="totalValue"
></gf-value>
<gf-value [isCurrency]="true" [locale]="locale" [value]="totalValue" />
</td>
</ng-container>
@ -153,7 +149,7 @@
[isCurrency]="true"
[locale]="locale"
[value]="totalChange"
></gf-value>
/>
</div>
</td>
</ng-container>
@ -189,7 +185,7 @@
[isPercent]="true"
[locale]="locale"
[value]="totalChangePercentage"
></gf-value>
/>
</div>
</td>
</ng-container>
@ -214,7 +210,7 @@
<tr
*matFooterRowDef="displayedColumns"
mat-footer-row
[ngClass]="{ hidden: isLoading }"
[ngClass]="{ 'd-none': isLoading }"
></tr>
</table>
</div>

18
libs/ui/src/lib/holdings-table/holdings-table.component.ts

@ -3,6 +3,7 @@ import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module';
import { getLocale } from '@ghostfolio/common/helper';
import {
AssetProfileIdentifier,
PortfolioPerformance,
PortfolioPosition
} from '@ghostfolio/common/interfaces';
import { GfNoTransactionsInfoComponent } from '@ghostfolio/ui/no-transactions-info';
@ -58,6 +59,7 @@ export class GfHoldingsTableComponent implements OnChanges, OnDestroy {
@Input() holdings: PortfolioPosition[];
@Input() locale = getLocale();
@Input() pageSize = Number.MAX_SAFE_INTEGER;
@Input() performance: PortfolioPerformance;
@Output() holdingClicked = new EventEmitter<AssetProfileIdentifier>();
@ -70,9 +72,9 @@ export class GfHoldingsTableComponent implements OnChanges, OnDestroy {
public isLoading = true;
public routeQueryParams: Subscription;
protected totalValue = 0;
protected totalChange = 0;
protected totalChangePercentage = 0;
protected totalValue = 0;
private unsubscribeSubject = new Subject<void>();
@ -96,16 +98,12 @@ export class GfHoldingsTableComponent implements OnChanges, OnDestroy {
this.dataSource = new MatTableDataSource(this.holdings);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
this.totalValue = this.dataSource.data.reduce(
(sum, current) => (sum += current.valueInBaseCurrency),
0
);
this.totalChange = this.dataSource.data.reduce(
(sum, current) => (sum += current.netPerformanceWithCurrencyEffect),
0
);
this.totalChange =
this.performance.netPerformancePercentageWithCurrencyEffect;
this.totalChangePercentage =
this.totalChange / (this.totalValue - this.totalChange);
this.performance.netPerformancePercentageWithCurrencyEffect;
this.totalValue = this.performance.currentValueInBaseCurrency;
if (this.holdings) {
this.isLoading = false;

Loading…
Cancel
Save