Add expand/collapse for Top/Bottom secion off portfolio analysis page #1
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,7 @@
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
sync.sh
|
||||
|
||||
# compiled output
|
||||
/out-tsc
|
||||
/tmp
|
||||
|
@ -2,6 +2,7 @@ import { ToggleComponent } from '@ghostfolio/client/components/toggle/toggle.com
|
||||
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 { MatPaginator, PageEvent } from '@angular/material/paginator';
|
||||
import {
|
||||
HistoricalDataItem,
|
||||
PortfolioInvestments,
|
||||
@ -31,6 +32,7 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
|
||||
public benchmarkDataItems: HistoricalDataItem[] = [];
|
||||
public benchmarks: Partial<SymbolProfile>[];
|
||||
public bottom3: PortfolioPosition[];
|
||||
public bottomx: PortfolioPosition[];
|
||||
public dateRangeOptions = ToggleComponent.DEFAULT_DATE_RANGE_OPTIONS;
|
||||
public daysInMarket: number;
|
||||
public deviceType: string;
|
||||
@ -56,9 +58,17 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
|
||||
public portfolioEvolutionDataLabel = $localize`Investment`;
|
||||
public streaks: PortfolioInvestments['streaks'];
|
||||
public top3: PortfolioPosition[];
|
||||
public topx: PortfolioPosition[];
|
||||
public positions: PortfolioPosition[];
|
||||
public positionsReversed: PortfolioPosition[];
|
||||
public unitCurrentStreak: string;
|
||||
public unitLongestStreak: string;
|
||||
public user: User;
|
||||
public showAllTop: boolean = false;
|
||||
public showAllBottom: boolean = false;
|
||||
public pageSize: number = 10;
|
||||
public pageIndexTop: number = 0;
|
||||
public pageIndexBottom: number = 0;
|
||||
|
||||
private unsubscribeSubject = new Subject<void>();
|
||||
|
||||
@ -73,6 +83,25 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
|
||||
this.benchmarks = benchmarks;
|
||||
}
|
||||
|
||||
public pageChanged(event: PageEvent, section: 'top' | 'bottom') {
|
||||
const newPageIndex = event.pageIndex;
|
||||
if (section === 'top') {
|
||||
this.pageIndexTop = newPageIndex;
|
||||
} else if (section === 'bottom') {
|
||||
this.pageIndexBottom = newPageIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public toggleList(l: string) {
|
||||
if (l === 'top') {
|
||||
this.showAllTop = !this.showAllTop;
|
||||
this.pageIndexTop = 0;
|
||||
} else if (l === 'bottom') {
|
||||
this.showAllBottom = !this.showAllBottom;
|
||||
this.pageIndexBottom = 0;
|
||||
}
|
||||
}
|
||||
|
||||
get savingsRate() {
|
||||
const savingsRatePerMonth =
|
||||
this.hasImpersonationId || this.user.settings.isRestrictedView
|
||||
@ -257,14 +286,17 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
|
||||
'netPerformancePercentWithCurrencyEffect'
|
||||
).reverse();
|
||||
|
||||
this.top3 = holdingsSorted.slice(0, 3);
|
||||
this.topx = holdingsSorted.slice(0, 5);
|
||||
|
||||
if (holdings?.length > 3) {
|
||||
this.bottom3 = holdingsSorted.slice(-3).reverse();
|
||||
if (holdings?.length > 5) {
|
||||
this.bottomx = holdingsSorted.slice(-5).reverse();
|
||||
} else {
|
||||
this.bottom3 = [];
|
||||
this.bottomx = [];
|
||||
}
|
||||
|
||||
this.positions = [...holdingsSorted]
|
||||
this.positionsReversed = [...holdingsSorted].reverse();
|
||||
|
||||
this.changeDetectorRef.markForCheck();
|
||||
});
|
||||
|
||||
|
@ -168,7 +168,7 @@
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<ol class="mb-0 ml-1 pl-3">
|
||||
@for (holding of top3; track holding) {
|
||||
<div *ngFor="let holding of (showAllTop ? positions.slice(pageIndexTop * pageSize, (pageIndexTop + 1) * pageSize) : positions | slice:0:5); track holding">
|
||||
<li class="py-1">
|
||||
<a
|
||||
class="d-flex"
|
||||
@ -192,10 +192,10 @@
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</div>
|
||||
</ol>
|
||||
<div>
|
||||
@if (!top3) {
|
||||
@if (!topx) {
|
||||
<ngx-skeleton-loader
|
||||
animation="pulse"
|
||||
[theme]="{
|
||||
@ -206,7 +206,23 @@
|
||||
}
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<mat-paginator
|
||||
*ngIf="showAllTop && positions.length > 10"
|
||||
[length]="positions.length"
|
||||
[pageSize]="pageSize"
|
||||
[pageSizeOptions]="[10, 20, 30, 40]"
|
||||
(page)="pageChanged($event, 'top')"
|
||||
>
|
||||
</mat-paginator>
|
||||
</mat-card>
|
||||
<button
|
||||
class="toggle-performance-list"
|
||||
color="{{showAllTop ? 'accent' : 'primary'}}"
|
||||
mat-button
|
||||
(click)="toggleList('top')"
|
||||
>
|
||||
{{ showAllTop ? 'Collapse' : 'Expand' }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<mat-card appearance="outlined" class="mb-3">
|
||||
@ -217,7 +233,7 @@
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<ol class="mb-0 ml-1 pl-3">
|
||||
@for (holding of bottom3; track holding) {
|
||||
<div *ngFor="let holding of (showAllBottom ? positionsReversed.slice(pageIndexBottom * pageSize, (pageIndexBottom + 1) * pageSize) : positionsReversed | slice:0:5); track holding">
|
||||
<li class="py-1">
|
||||
<a
|
||||
class="d-flex"
|
||||
@ -241,10 +257,10 @@
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</div>
|
||||
</ol>
|
||||
<div>
|
||||
@if (!bottom3) {
|
||||
@if (!bottomx) {
|
||||
<ngx-skeleton-loader
|
||||
animation="pulse"
|
||||
[theme]="{
|
||||
@ -255,7 +271,23 @@
|
||||
}
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<mat-paginator
|
||||
*ngIf="showAllBottom && positionsReversed.length > 10"
|
||||
[length]="positions.length"
|
||||
[pageSize]="pageSize"
|
||||
[pageSizeOptions]="[10, 20, 30, 40]"
|
||||
(page)="pageChanged($event, 'bottom')"
|
||||
>
|
||||
</mat-paginator>
|
||||
</mat-card>
|
||||
<button
|
||||
class="toggle-performance-list"
|
||||
color="{{showAllBottom ? 'accent' : 'primary'}}"
|
||||
mat-button
|
||||
(click)="toggleList('bottom')"
|
||||
>
|
||||
{{ showAllBottom ? 'Collapse' : 'Expand' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -4,6 +4,8 @@ import { GfToggleModule } from '@ghostfolio/client/components/toggle/toggle.modu
|
||||
import { GfActivitiesFilterComponent } from '@ghostfolio/ui/activities-filter';
|
||||
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
|
||||
import { GfValueComponent } from '@ghostfolio/ui/value';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
@ -25,6 +27,8 @@ import { AnalysisPageComponent } from './analysis-page.component';
|
||||
GfToggleModule,
|
||||
GfValueComponent,
|
||||
MatCardModule,
|
||||
MatButtonModule,
|
||||
MatPaginatorModule,
|
||||
NgxSkeletonLoaderModule
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
|
@ -4,4 +4,8 @@
|
||||
.chart-container {
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
|
||||
.toggle-performance-list {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user