From ae57a188f5365a9f9c13223d6467e2c1c4bab8f0 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 3 Jun 2023 07:44:59 +0200 Subject: [PATCH] Feature/improve tab navigations (#2031) * Improve tab navigations * Update changelog --- CHANGELOG.md | 1 + .../pages/about/about-page-routing.module.ts | 3 +- .../app/pages/about/about-page.component.ts | 15 +++---- .../src/app/pages/about/about-page.html | 1 + .../pages/admin/admin-page-routing.module.ts | 11 +++-- .../app/pages/admin/admin-page.component.ts | 26 ++++++----- .../src/app/pages/admin/admin-page.html | 1 + .../pages/home/home-page-routing.module.ts | 3 +- .../src/app/pages/home/home-page.component.ts | 44 ++++++++----------- apps/client/src/app/pages/home/home-page.html | 1 + .../portfolio-page-routing.module.ts | 3 +- .../portfolio/portfolio-page.component.ts | 23 +++++----- .../app/pages/portfolio/portfolio-page.html | 1 + .../app/pages/zen/zen-page-routing.module.ts | 3 +- .../src/app/pages/zen/zen-page.component.ts | 13 ++---- apps/client/src/app/pages/zen/zen-page.html | 1 + libs/common/src/lib/interfaces/index.ts | 2 + .../interfaces/tab-configuration.interface.ts | 6 +++ 18 files changed, 76 insertions(+), 82 deletions(-) create mode 100644 libs/common/src/lib/interfaces/tab-configuration.interface.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 84edba3b8..636c97073 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Improved the routes of the tabs - Removed the _Ghostfolio in Numbers_ section from the about page ## 1.275.0 - 2023-05-30 diff --git a/apps/client/src/app/pages/about/about-page-routing.module.ts b/apps/client/src/app/pages/about/about-page-routing.module.ts index 63faf7396..0b7a83db6 100644 --- a/apps/client/src/app/pages/about/about-page-routing.module.ts +++ b/apps/client/src/app/pages/about/about-page-routing.module.ts @@ -8,9 +8,8 @@ const routes: Routes = [ { canActivate: [AuthGuard], children: [ - { path: '', redirectTo: 'overview', pathMatch: 'full' }, { - path: 'overview', + path: '', loadChildren: () => import('./overview/about-overview-page.module').then( (m) => m.AboutOverviewPageModule diff --git a/apps/client/src/app/pages/about/about-page.component.ts b/apps/client/src/app/pages/about/about-page.component.ts index ff2b0c532..3953aa00e 100644 --- a/apps/client/src/app/pages/about/about-page.component.ts +++ b/apps/client/src/app/pages/about/about-page.component.ts @@ -7,7 +7,7 @@ import { } from '@angular/core'; import { DataService } from '@ghostfolio/client/services/data.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; -import { User } from '@ghostfolio/common/interfaces'; +import { TabConfiguration, User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; @@ -24,12 +24,7 @@ export class AboutPageComponent implements OnDestroy, OnInit { public hasMessage: boolean; public hasPermissionForSubscription: boolean; - public tabs: { - iconName: string; - label: string; - path: string; - showCondition?: boolean; - }[] = []; + public tabs: TabConfiguration[] = []; public user: User; private unsubscribeSubject = new Subject(); @@ -54,17 +49,17 @@ export class AboutPageComponent implements OnDestroy, OnInit { { iconName: 'reader-outline', label: $localize`About`, - path: 'overview' + path: ['/about'] }, { iconName: 'sparkles-outline', label: $localize`Changelog & License`, - path: 'changelog' + path: ['/about', 'changelog'] }, { iconName: 'shield-checkmark-outline', label: $localize`Privacy Policy`, - path: 'privacy-policy', + path: ['/about', 'privacy-policy'], showCondition: this.hasPermissionForSubscription } ]; diff --git a/apps/client/src/app/pages/about/about-page.html b/apps/client/src/app/pages/about/about-page.html index b5c6af58b..ce1d84851 100644 --- a/apps/client/src/app/pages/about/about-page.html +++ b/apps/client/src/app/pages/about/about-page.html @@ -12,6 +12,7 @@ routerLinkActive [active]="rla.isActive" [routerLink]="tab.path" + [routerLinkActiveOptions]="{ exact: true }" >
{{ tab.label }}
diff --git a/apps/client/src/app/pages/admin/admin-page-routing.module.ts b/apps/client/src/app/pages/admin/admin-page-routing.module.ts index 5ebd69b42..23aa2f7d4 100644 --- a/apps/client/src/app/pages/admin/admin-page-routing.module.ts +++ b/apps/client/src/app/pages/admin/admin-page-routing.module.ts @@ -13,18 +13,17 @@ const routes: Routes = [ { canActivate: [AuthGuard], children: [ - { path: '', redirectTo: 'overview', pathMatch: 'full' }, + { + path: '', + component: AdminOverviewComponent, + title: $localize`Admin Control` + }, { path: 'jobs', component: AdminJobsComponent, title: $localize`Jobs` }, { path: 'market-data', component: AdminMarketDataComponent, title: $localize`Market Data` }, - { - path: 'overview', - component: AdminOverviewComponent, - title: $localize`Admin Control` - }, { path: 'settings', component: AdminSettingsComponent, diff --git a/apps/client/src/app/pages/admin/admin-page.component.ts b/apps/client/src/app/pages/admin/admin-page.component.ts index 8847301d4..c95630726 100644 --- a/apps/client/src/app/pages/admin/admin-page.component.ts +++ b/apps/client/src/app/pages/admin/admin-page.component.ts @@ -1,5 +1,6 @@ import { Component, HostBinding, OnDestroy, OnInit } from '@angular/core'; import { DataService } from '@ghostfolio/client/services/data.service'; +import { TabConfiguration } from '@ghostfolio/common/interfaces'; import { Subject } from 'rxjs'; @Component({ @@ -13,12 +14,7 @@ export class AdminPageComponent implements OnDestroy, OnInit { } public hasMessage: boolean; - public tabs: { - iconName: string; - label: string; - path: string; - showCondition?: boolean; - }[] = []; + public tabs: TabConfiguration[] = []; private unsubscribeSubject = new Subject(); @@ -33,20 +29,28 @@ export class AdminPageComponent implements OnDestroy, OnInit { { iconName: 'reader-outline', label: $localize`Overview`, - path: 'overview' + path: ['/admin'] }, { iconName: 'settings-outline', label: $localize`Settings`, - path: 'settings' + path: ['/admin', 'settings'] }, { iconName: 'server-outline', label: $localize`Market Data`, - path: 'market-data' + path: ['/admin', 'market-data'] }, - { iconName: 'flash-outline', label: $localize`Jobs`, path: 'jobs' }, - { iconName: 'people-outline', label: $localize`Users`, path: 'users' } + { + iconName: 'flash-outline', + label: $localize`Jobs`, + path: ['/admin', 'jobs'] + }, + { + iconName: 'people-outline', + label: $localize`Users`, + path: ['/admin', 'users'] + } ]; } diff --git a/apps/client/src/app/pages/admin/admin-page.html b/apps/client/src/app/pages/admin/admin-page.html index b5c6af58b..ce1d84851 100644 --- a/apps/client/src/app/pages/admin/admin-page.html +++ b/apps/client/src/app/pages/admin/admin-page.html @@ -12,6 +12,7 @@ routerLinkActive [active]="rla.isActive" [routerLink]="tab.path" + [routerLinkActiveOptions]="{ exact: true }" >
{{ tab.label }}
diff --git a/apps/client/src/app/pages/home/home-page-routing.module.ts b/apps/client/src/app/pages/home/home-page-routing.module.ts index 5463f0777..347bfc567 100644 --- a/apps/client/src/app/pages/home/home-page-routing.module.ts +++ b/apps/client/src/app/pages/home/home-page-routing.module.ts @@ -12,9 +12,8 @@ const routes: Routes = [ { canActivate: [AuthGuard], children: [ - { path: '', redirectTo: 'overview', pathMatch: 'full' }, { - path: 'overview', + path: '', component: HomeOverviewComponent }, { diff --git a/apps/client/src/app/pages/home/home-page.component.ts b/apps/client/src/app/pages/home/home-page.component.ts index 734e7e4f4..77c318395 100644 --- a/apps/client/src/app/pages/home/home-page.component.ts +++ b/apps/client/src/app/pages/home/home-page.component.ts @@ -7,7 +7,7 @@ import { } from '@angular/core'; import { DataService } from '@ghostfolio/client/services/data.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; -import { InfoItem, User } from '@ghostfolio/common/interfaces'; +import { TabConfiguration, User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; @@ -24,13 +24,7 @@ export class HomePageComponent implements OnDestroy, OnInit { public hasMessage: boolean; public hasPermissionToAccessFearAndGreedIndex: boolean; - public info: InfoItem; - public tabs: { - iconName: string; - label: string; - path: string; - showCondition?: boolean; - }[] = []; + public tabs: TabConfiguration[] = []; public user: User; private unsubscribeSubject = new Subject(); @@ -40,7 +34,12 @@ export class HomePageComponent implements OnDestroy, OnInit { private dataService: DataService, private userService: UserService ) { - this.info = this.dataService.fetchInfo(); + const { globalPermissions, systemMessage } = this.dataService.fetchInfo(); + + this.hasPermissionToAccessFearAndGreedIndex = hasPermission( + globalPermissions, + permissions.enableFearAndGreedIndex + ); this.userService.stateChanged .pipe(takeUntil(this.unsubscribeSubject)) @@ -50,17 +49,23 @@ export class HomePageComponent implements OnDestroy, OnInit { { iconName: 'analytics-outline', label: $localize`Overview`, - path: 'overview' + path: ['/home'] }, { iconName: 'wallet-outline', label: $localize`Holdings`, - path: 'holdings' + path: ['/home', 'holdings'] }, { iconName: 'reader-outline', label: $localize`Summary`, - path: 'summary' + path: ['/home', 'summary'] + }, + { + iconName: 'newspaper-outline', + label: $localize`Markets`, + path: ['/home', 'market'], + showCondition: this.hasPermissionToAccessFearAndGreedIndex } ]; this.user = state.user; @@ -69,20 +74,7 @@ export class HomePageComponent implements OnDestroy, OnInit { hasPermission( this.user?.permissions, permissions.createUserAccount - ) || !!this.info.systemMessage; - - this.hasPermissionToAccessFearAndGreedIndex = hasPermission( - this.info?.globalPermissions, - permissions.enableFearAndGreedIndex - ); - - if (this.hasPermissionToAccessFearAndGreedIndex) { - this.tabs.push({ - iconName: 'newspaper-outline', - label: $localize`Markets`, - path: 'market' - }); - } + ) || !!systemMessage; this.changeDetectorRef.markForCheck(); } diff --git a/apps/client/src/app/pages/home/home-page.html b/apps/client/src/app/pages/home/home-page.html index b5c6af58b..ce1d84851 100644 --- a/apps/client/src/app/pages/home/home-page.html +++ b/apps/client/src/app/pages/home/home-page.html @@ -12,6 +12,7 @@ routerLinkActive [active]="rla.isActive" [routerLink]="tab.path" + [routerLinkActiveOptions]="{ exact: true }" >
{{ tab.label }}
diff --git a/apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts b/apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts index 4fc013ee5..6ca831e9c 100644 --- a/apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts +++ b/apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -8,9 +8,8 @@ const routes: Routes = [ { canActivate: [AuthGuard], children: [ - { path: '', redirectTo: 'analysis', pathMatch: 'full' }, { - path: 'analysis', + path: '', loadChildren: () => import('./analysis/analysis-page.module').then( (m) => m.AnalysisPageModule diff --git a/apps/client/src/app/pages/portfolio/portfolio-page.component.ts b/apps/client/src/app/pages/portfolio/portfolio-page.component.ts index 8e5f87647..2244e7af9 100644 --- a/apps/client/src/app/pages/portfolio/portfolio-page.component.ts +++ b/apps/client/src/app/pages/portfolio/portfolio-page.component.ts @@ -7,7 +7,11 @@ import { } from '@angular/core'; import { DataService } from '@ghostfolio/client/services/data.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; -import { InfoItem, User } from '@ghostfolio/common/interfaces'; +import { + InfoItem, + TabConfiguration, + User +} from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; @@ -24,12 +28,7 @@ export class PortfolioPageComponent implements OnDestroy, OnInit { public hasMessage: boolean; public info: InfoItem; - public tabs: { - iconName: string; - label: string; - path: string; - showCondition?: boolean; - }[] = []; + public tabs: TabConfiguration[] = []; public user: User; private unsubscribeSubject = new Subject(); @@ -49,27 +48,27 @@ export class PortfolioPageComponent implements OnDestroy, OnInit { { iconName: 'analytics-outline', label: $localize`Analysis`, - path: 'analysis' + path: ['/portfolio'] }, { iconName: 'wallet-outline', label: $localize`Holdings`, - path: 'holdings' + path: ['/portfolio', 'holdings'] }, { iconName: 'swap-vertical-outline', label: $localize`Activities`, - path: 'activities' + path: ['/portfolio', 'activities'] }, { iconName: 'pie-chart-outline', label: $localize`Allocations`, - path: 'allocations' + path: ['/portfolio', 'allocations'] }, { iconName: 'calculator-outline', label: 'FIRE / X-ray', - path: 'fire' + path: ['/portfolio', 'fire'] } ]; this.user = state.user; diff --git a/apps/client/src/app/pages/portfolio/portfolio-page.html b/apps/client/src/app/pages/portfolio/portfolio-page.html index b5c6af58b..ce1d84851 100644 --- a/apps/client/src/app/pages/portfolio/portfolio-page.html +++ b/apps/client/src/app/pages/portfolio/portfolio-page.html @@ -12,6 +12,7 @@ routerLinkActive [active]="rla.isActive" [routerLink]="tab.path" + [routerLinkActiveOptions]="{ exact: true }" >
{{ tab.label }}
diff --git a/apps/client/src/app/pages/zen/zen-page-routing.module.ts b/apps/client/src/app/pages/zen/zen-page-routing.module.ts index 70cf4e84d..26b468aef 100644 --- a/apps/client/src/app/pages/zen/zen-page-routing.module.ts +++ b/apps/client/src/app/pages/zen/zen-page-routing.module.ts @@ -10,8 +10,7 @@ const routes: Routes = [ { canActivate: [AuthGuard], children: [ - { path: '', redirectTo: 'overview', pathMatch: 'full' }, - { path: 'overview', component: HomeOverviewComponent }, + { path: '', component: HomeOverviewComponent }, { path: 'holdings', component: HomeHoldingsComponent } ], component: ZenPageComponent, diff --git a/apps/client/src/app/pages/zen/zen-page.component.ts b/apps/client/src/app/pages/zen/zen-page.component.ts index 544e32f82..9f769e281 100644 --- a/apps/client/src/app/pages/zen/zen-page.component.ts +++ b/apps/client/src/app/pages/zen/zen-page.component.ts @@ -8,7 +8,7 @@ import { } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { UserService } from '@ghostfolio/client/services/user/user.service'; -import { User } from '@ghostfolio/common/interfaces'; +import { TabConfiguration, User } from '@ghostfolio/common/interfaces'; import { Subject } from 'rxjs'; import { first, takeUntil } from 'rxjs/operators'; @@ -18,12 +18,7 @@ import { first, takeUntil } from 'rxjs/operators'; styleUrls: ['./zen-page.scss'] }) export class ZenPageComponent implements AfterViewInit, OnDestroy, OnInit { - public tabs: { - iconName: string; - label: string; - path: string; - showCondition?: boolean; - }[] = []; + public tabs: TabConfiguration[] = []; public user: User; private unsubscribeSubject = new Subject(); @@ -42,12 +37,12 @@ export class ZenPageComponent implements AfterViewInit, OnDestroy, OnInit { { iconName: 'analytics-outline', label: $localize`Overview`, - path: 'overview' + path: ['/zen'] }, { iconName: 'wallet-outline', label: $localize`Holdings`, - path: 'holdings' + path: ['/zen', 'holdings'] } ]; this.user = state.user; diff --git a/apps/client/src/app/pages/zen/zen-page.html b/apps/client/src/app/pages/zen/zen-page.html index b5c6af58b..ce1d84851 100644 --- a/apps/client/src/app/pages/zen/zen-page.html +++ b/apps/client/src/app/pages/zen/zen-page.html @@ -12,6 +12,7 @@ routerLinkActive [active]="rla.isActive" [routerLink]="tab.path" + [routerLinkActiveOptions]="{ exact: true }" >
{{ tab.label }}
diff --git a/libs/common/src/lib/interfaces/index.ts b/libs/common/src/lib/interfaces/index.ts index 93268153b..6eebc0de2 100644 --- a/libs/common/src/lib/interfaces/index.ts +++ b/libs/common/src/lib/interfaces/index.ts @@ -40,6 +40,7 @@ import type { PortfolioPerformanceResponse } from './responses/portfolio-perform import type { ScraperConfiguration } from './scraper-configuration.interface'; import type { Statistics } from './statistics.interface'; import type { Subscription } from './subscription.interface'; +import { TabConfiguration } from './tab-configuration.interface'; import type { TimelinePosition } from './timeline-position.interface'; import type { UniqueAsset } from './unique-asset.interface'; import type { UserSettings } from './user-settings.interface'; @@ -86,6 +87,7 @@ export { ScraperConfiguration, Statistics, Subscription, + TabConfiguration, TimelinePosition, UniqueAsset, User, diff --git a/libs/common/src/lib/interfaces/tab-configuration.interface.ts b/libs/common/src/lib/interfaces/tab-configuration.interface.ts new file mode 100644 index 000000000..e475e3efc --- /dev/null +++ b/libs/common/src/lib/interfaces/tab-configuration.interface.ts @@ -0,0 +1,6 @@ +export interface TabConfiguration { + iconName: string; + label: string; + path: string[]; + showCondition?: boolean; +}