From 77065dac508d06df6a8d37a6b801075a03b7eed6 Mon Sep 17 00:00:00 2001
From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com>
Date: Wed, 29 Dec 2021 18:14:24 +0100
Subject: [PATCH] Feature/add date range selector to holdings tab (#595)

* Add date range selector to holdings tab

* Update changelog
---
 CHANGELOG.md                                           |  4 ++++
 .../home-holdings/home-holdings.component.ts           | 10 ++++++++++
 .../app/components/home-holdings/home-holdings.html    | 10 +++++++++-
 .../components/home-holdings/home-holdings.module.ts   |  2 ++
 .../home-overview/home-overview.component.ts           | 10 ++--------
 .../src/app/components/toggle/toggle.component.ts      |  3 +--
 .../allocations/allocations-page.component.ts          |  2 +-
 .../portfolio/analysis/analysis-page.component.ts      |  2 +-
 libs/common/src/lib/config.ts                          | 10 ++++++++++
 libs/common/src/lib/types/index.ts                     |  4 +++-
 .../common/src/lib/types}/toggle-option.type.ts        |  0
 11 files changed, 43 insertions(+), 14 deletions(-)
 rename {apps/client/src/app/components/toggle/interfaces => libs/common/src/lib/types}/toggle-option.type.ts (100%)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 36f97dbcd..ebbcc8d39 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## Unreleased
 
+### Added
+
+- Added the date range component to the holdings tab
+
 ### Fixed
 
 - Fixed the creation of historical data in the admin control panel (upsert instead of update)
diff --git a/apps/client/src/app/components/home-holdings/home-holdings.component.ts b/apps/client/src/app/components/home-holdings/home-holdings.component.ts
index b5aa0b1b7..13b6ffe0d 100644
--- a/apps/client/src/app/components/home-holdings/home-holdings.component.ts
+++ b/apps/client/src/app/components/home-holdings/home-holdings.component.ts
@@ -8,6 +8,7 @@ import {
   SettingsStorageService
 } from '@ghostfolio/client/services/settings-storage.service';
 import { UserService } from '@ghostfolio/client/services/user/user.service';
+import { defaultDateRangeOptions } from '@ghostfolio/common/config';
 import { Position, User } from '@ghostfolio/common/interfaces';
 import { hasPermission, permissions } from '@ghostfolio/common/permissions';
 import { DateRange } from '@ghostfolio/common/types';
@@ -22,6 +23,7 @@ import { takeUntil } from 'rxjs/operators';
 })
 export class HomeHoldingsComponent implements OnDestroy, OnInit {
   public dateRange: DateRange;
+  public dateRangeOptions = defaultDateRangeOptions;
   public deviceType: string;
   public hasPermissionToCreateOrder: boolean;
   public positions: Position[];
@@ -78,6 +80,12 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit {
     this.update();
   }
 
+  public onChangeDateRange(aDateRange: DateRange) {
+    this.dateRange = aDateRange;
+    this.settingsStorageService.setSetting(RANGE, this.dateRange);
+    this.update();
+  }
+
   public ngOnDestroy() {
     this.unsubscribeSubject.next();
     this.unsubscribeSubject.complete();
@@ -105,6 +113,8 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit {
   }
 
   private update() {
+    this.positions = undefined;
+
     this.dataService
       .fetchPositions({ range: this.dateRange })
       .pipe(takeUntil(this.unsubscribeSubject))
diff --git a/apps/client/src/app/components/home-holdings/home-holdings.html b/apps/client/src/app/components/home-holdings/home-holdings.html
index f17d36355..03232d01a 100644
--- a/apps/client/src/app/components/home-holdings/home-holdings.html
+++ b/apps/client/src/app/components/home-holdings/home-holdings.html
@@ -1,4 +1,12 @@
-<div class="container justify-content-center pb-3 px-3">
+<div class="container justify-content-center p-3">
+  <div class="mb-3 text-center">
+    <gf-toggle
+      [defaultValue]="dateRange"
+      [isLoading]="positions === undefined"
+      [options]="dateRangeOptions"
+      (change)="onChangeDateRange($event.value)"
+    ></gf-toggle>
+  </div>
   <div class="row">
     <div class="align-items-center col-xs-12 col-md-8 offset-md-2">
       <mat-card class="p-0">
diff --git a/apps/client/src/app/components/home-holdings/home-holdings.module.ts b/apps/client/src/app/components/home-holdings/home-holdings.module.ts
index 5d0a13ab9..de9b31eaa 100644
--- a/apps/client/src/app/components/home-holdings/home-holdings.module.ts
+++ b/apps/client/src/app/components/home-holdings/home-holdings.module.ts
@@ -5,6 +5,7 @@ import { MatCardModule } from '@angular/material/card';
 import { RouterModule } from '@angular/router';
 import { GfPositionDetailDialogModule } from '@ghostfolio/client/components/position/position-detail-dialog/position-detail-dialog.module';
 import { GfPositionsModule } from '@ghostfolio/client/components/positions/positions.module';
+import { GfToggleModule } from '@ghostfolio/client/components/toggle/toggle.module';
 
 import { HomeHoldingsComponent } from './home-holdings.component';
 
@@ -15,6 +16,7 @@ import { HomeHoldingsComponent } from './home-holdings.component';
     CommonModule,
     GfPositionDetailDialogModule,
     GfPositionsModule,
+    GfToggleModule,
     MatButtonModule,
     MatCardModule,
     RouterModule
diff --git a/apps/client/src/app/components/home-overview/home-overview.component.ts b/apps/client/src/app/components/home-overview/home-overview.component.ts
index 393de9fe8..8814203c0 100644
--- a/apps/client/src/app/components/home-overview/home-overview.component.ts
+++ b/apps/client/src/app/components/home-overview/home-overview.component.ts
@@ -1,5 +1,4 @@
 import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
-import { ToggleOption } from '@ghostfolio/client/components/toggle/interfaces/toggle-option.type';
 import { DataService } from '@ghostfolio/client/services/data.service';
 import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service';
 import {
@@ -7,6 +6,7 @@ import {
   SettingsStorageService
 } from '@ghostfolio/client/services/settings-storage.service';
 import { UserService } from '@ghostfolio/client/services/user/user.service';
+import { defaultDateRangeOptions } from '@ghostfolio/common/config';
 import { PortfolioPerformance, User } from '@ghostfolio/common/interfaces';
 import { DateRange } from '@ghostfolio/common/types';
 import { LineChartItem } from '@ghostfolio/ui/line-chart/interfaces/line-chart.interface';
@@ -21,13 +21,7 @@ import { takeUntil } from 'rxjs/operators';
 })
 export class HomeOverviewComponent implements OnDestroy, OnInit {
   public dateRange: DateRange;
-  public dateRangeOptions: ToggleOption[] = [
-    { label: 'Today', value: '1d' },
-    { label: 'YTD', value: 'ytd' },
-    { label: '1Y', value: '1y' },
-    { label: '5Y', value: '5y' },
-    { label: 'Max', value: 'max' }
-  ];
+  public dateRangeOptions = defaultDateRangeOptions;
   public deviceType: string;
   public hasError: boolean;
   public hasImpersonationId: boolean;
diff --git a/apps/client/src/app/components/toggle/toggle.component.ts b/apps/client/src/app/components/toggle/toggle.component.ts
index ac95fd925..fda18ea8d 100644
--- a/apps/client/src/app/components/toggle/toggle.component.ts
+++ b/apps/client/src/app/components/toggle/toggle.component.ts
@@ -8,8 +8,7 @@ import {
   Output
 } from '@angular/core';
 import { FormControl } from '@angular/forms';
-
-import { ToggleOption } from './interfaces/toggle-option.type';
+import { ToggleOption } from '@ghostfolio/common/types';
 
 @Component({
   selector: 'gf-toggle',
diff --git a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts
index af3c35c58..482313244 100644
--- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts
+++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts
@@ -1,5 +1,4 @@
 import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
-import { ToggleOption } from '@ghostfolio/client/components/toggle/interfaces/toggle-option.type';
 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';
@@ -10,6 +9,7 @@ import {
   PortfolioPosition,
   User
 } from '@ghostfolio/common/interfaces';
+import { ToggleOption } from '@ghostfolio/common/types';
 import { AssetClass } from '@prisma/client';
 import { DeviceDetectorService } from 'ngx-device-detector';
 import { Subject } from 'rxjs';
diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts
index 7c5158e19..e2ed6065f 100644
--- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts
+++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts
@@ -1,10 +1,10 @@
 import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
-import { ToggleOption } from '@ghostfolio/client/components/toggle/interfaces/toggle-option.type';
 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 { PortfolioPosition, User } from '@ghostfolio/common/interfaces';
 import { InvestmentItem } from '@ghostfolio/common/interfaces/investment-item.interface';
+import { ToggleOption } from '@ghostfolio/common/types';
 import { DeviceDetectorService } from 'ngx-device-detector';
 import { Subject } from 'rxjs';
 import { takeUntil } from 'rxjs/operators';
diff --git a/libs/common/src/lib/config.ts b/libs/common/src/lib/config.ts
index d9acd3e0b..ef57ca9dc 100644
--- a/libs/common/src/lib/config.ts
+++ b/libs/common/src/lib/config.ts
@@ -1,5 +1,15 @@
+import { ToggleOption } from './types';
+
 export const baseCurrency = 'USD';
 
+export const defaultDateRangeOptions: ToggleOption[] = [
+  { label: 'Today', value: '1d' },
+  { label: 'YTD', value: 'ytd' },
+  { label: '1Y', value: '1y' },
+  { label: '5Y', value: '5y' },
+  { label: 'Max', value: 'max' }
+];
+
 export const ghostfolioScraperApiSymbolPrefix = '_GF_';
 export const ghostfolioCashSymbol = `${ghostfolioScraperApiSymbolPrefix}CASH`;
 export const ghostfolioFearAndGreedIndexSymbol = `${ghostfolioScraperApiSymbolPrefix}FEAR_AND_GREED_INDEX`;
diff --git a/libs/common/src/lib/types/index.ts b/libs/common/src/lib/types/index.ts
index cd9408b5d..6953b5863 100644
--- a/libs/common/src/lib/types/index.ts
+++ b/libs/common/src/lib/types/index.ts
@@ -4,6 +4,7 @@ import type { DateRange } from './date-range.type';
 import type { Granularity } from './granularity.type';
 import type { OrderWithAccount } from './order-with-account.type';
 import type { RequestWithUser } from './request-with-user.type';
+import { ToggleOption } from './toggle-option.type';
 
 export type {
   AccessWithGranteeUser,
@@ -11,5 +12,6 @@ export type {
   DateRange,
   Granularity,
   OrderWithAccount,
-  RequestWithUser
+  RequestWithUser,
+  ToggleOption
 };
diff --git a/apps/client/src/app/components/toggle/interfaces/toggle-option.type.ts b/libs/common/src/lib/types/toggle-option.type.ts
similarity index 100%
rename from apps/client/src/app/components/toggle/interfaces/toggle-option.type.ts
rename to libs/common/src/lib/types/toggle-option.type.ts