From 9ecc3176a5615184c97e4b2d46861b8f52fa99d6 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 13 Jul 2024 10:45:10 +0200 Subject: [PATCH] Feature/improve treemap chart for holdings (#3563) * Various improvements * Introduce permission: accessHoldingsChart * Improve style of toggle * Add border radius * Update changelog --- CHANGELOG.md | 6 ++ apps/api/src/app/user/user.service.ts | 1 + .../home-holdings/home-holdings.component.ts | 56 ++++++++++--------- .../home-holdings/home-holdings.html | 4 +- .../home-holdings/home-holdings.scss | 6 ++ libs/common/src/lib/permissions.ts | 9 ++- .../treemap-chart/treemap-chart.component.ts | 2 +- 7 files changed, 55 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df89cb128..9557701c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- Improved the chart of the holdings tab on the home page (experimental) + ## 2.95.0 - 2024-07-12 ### Added diff --git a/apps/api/src/app/user/user.service.ts b/apps/api/src/app/user/user.service.ts index ce0ec5524..02a65b6a0 100644 --- a/apps/api/src/app/user/user.service.ts +++ b/apps/api/src/app/user/user.service.ts @@ -237,6 +237,7 @@ export class UserService { currentPermissions = without( currentPermissions, + permissions.accessHoldingsChart, permissions.createAccess ); 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 86fd0ce0c..3b99adb06 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 @@ -28,6 +28,7 @@ import { takeUntil } from 'rxjs/operators'; export class HomeHoldingsComponent implements OnDestroy, OnInit { public deviceType: string; public hasImpersonationId: boolean; + public hasPermissionToAccessHoldingsChart: boolean; public hasPermissionToCreateOrder: boolean; public holdings: PortfolioPosition[]; public holdingType: HoldingType = 'ACTIVE'; @@ -65,20 +66,17 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit { if (state?.user) { this.user = state.user; + this.hasPermissionToAccessHoldingsChart = hasPermission( + this.user.permissions, + permissions.accessHoldingsChart + ); + this.hasPermissionToCreateOrder = hasPermission( this.user.permissions, permissions.createOrder ); - this.holdings = undefined; - - this.fetchHoldings() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(({ holdings }) => { - this.holdings = holdings; - - this.changeDetectorRef.markForCheck(); - }); + this.initialize(); this.changeDetectorRef.markForCheck(); } @@ -88,22 +86,7 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit { public onChangeHoldingType(aHoldingType: HoldingType) { this.holdingType = aHoldingType; - if (this.holdingType === 'ACTIVE') { - this.viewModeFormControl.enable(); - } else if (this.holdingType === 'CLOSED') { - this.viewModeFormControl.disable(); - this.viewModeFormControl.setValue('TABLE'); - } - - this.holdings = undefined; - - this.fetchHoldings() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(({ holdings }) => { - this.holdings = holdings; - - this.changeDetectorRef.markForCheck(); - }); + this.initialize(); } public onSymbolClicked({ dataSource, symbol }: UniqueAsset) { @@ -131,4 +114,27 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit { range: this.user?.settings?.dateRange }); } + + private initialize() { + this.viewModeFormControl.disable(); + + if ( + this.hasPermissionToAccessHoldingsChart && + this.holdingType === 'ACTIVE' + ) { + this.viewModeFormControl.enable(); + } else if (this.holdingType === 'CLOSED') { + this.viewModeFormControl.setValue('TABLE'); + } + + this.holdings = undefined; + + this.fetchHoldings() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(({ holdings }) => { + this.holdings = holdings; + + this.changeDetectorRef.markForCheck(); + }); + } } 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 be053415f..a2ea30a69 100644 --- a/apps/client/src/app/components/home-holdings/home-holdings.html +++ b/apps/client/src/app/components/home-holdings/home-holdings.html @@ -14,10 +14,10 @@ [formControl]="viewModeFormControl" [hideSingleSelectionIndicator]="true" > - + - + diff --git a/apps/client/src/app/components/home-holdings/home-holdings.scss b/apps/client/src/app/components/home-holdings/home-holdings.scss index 5d4e87f30..d6d129a39 100644 --- a/apps/client/src/app/components/home-holdings/home-holdings.scss +++ b/apps/client/src/app/components/home-holdings/home-holdings.scss @@ -1,3 +1,9 @@ :host { display: block; + + .mat-button-toggle-group { + .mat-button-toggle-appearance-standard { + --mat-standard-button-toggle-height: 1.5rem; + } + } } diff --git a/libs/common/src/lib/permissions.ts b/libs/common/src/lib/permissions.ts index 304c8ba24..1a235f1a9 100644 --- a/libs/common/src/lib/permissions.ts +++ b/libs/common/src/lib/permissions.ts @@ -5,6 +5,7 @@ import { Role } from '@prisma/client'; export const permissions = { accessAdminControl: 'accessAdminControl', accessAssistant: 'accessAssistant', + accessHoldingsChart: 'accessHoldingsChart', createAccess: 'createAccess', createAccount: 'createAccount', createAccountBalance: 'createAccountBalance', @@ -47,6 +48,7 @@ export function getPermissions(aRole: Role): string[] { return [ permissions.accessAdminControl, permissions.accessAssistant, + permissions.accessHoldingsChart, permissions.createAccess, permissions.createAccount, permissions.createAccountBalance, @@ -72,11 +74,16 @@ export function getPermissions(aRole: Role): string[] { ]; case 'DEMO': - return [permissions.accessAssistant, permissions.createUserAccount]; + return [ + permissions.accessAssistant, + permissions.accessHoldingsChart, + permissions.createUserAccount + ]; case 'USER': return [ permissions.accessAssistant, + permissions.accessHoldingsChart, permissions.createAccess, permissions.createAccount, permissions.createAccountBalance, diff --git a/libs/ui/src/lib/treemap-chart/treemap-chart.component.ts b/libs/ui/src/lib/treemap-chart/treemap-chart.component.ts index 557bdc2ae..9ee6a7aeb 100644 --- a/libs/ui/src/lib/treemap-chart/treemap-chart.component.ts +++ b/libs/ui/src/lib/treemap-chart/treemap-chart.component.ts @@ -1,4 +1,3 @@ -import { getLocale } from '@ghostfolio/common/helper'; import { PortfolioPosition, UniqueAsset } from '@ghostfolio/common/interfaces'; import { CommonModule } from '@angular/common'; @@ -95,6 +94,7 @@ export class GfTreemapChartComponent return red[9]; } }, + borderRadius: 4, key: 'allocationInPercentage', labels: { align: 'left',