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