Browse Source

Feature/migrate portfolio page components to standalone (#5086)

* Migrate portfolio page components to standalone

* Update changelog
pull/5108/head
csehatt741 2 weeks ago
committed by GitHub
parent
commit
ec1f552dfa
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 4
      apps/client/src/app/app-routing.module.ts
  3. 16
      apps/client/src/app/pages/portfolio/activities/activities-page.component.ts
  4. 32
      apps/client/src/app/pages/portfolio/activities/activities-page.module.ts
  5. 11
      apps/client/src/app/pages/portfolio/activities/activities-page.routes.ts
  6. 46
      apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts
  7. 41
      apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.module.ts
  8. 45
      apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts
  9. 4
      apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html
  10. 43
      apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.module.ts
  11. 21
      apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts
  12. 32
      apps/client/src/app/pages/portfolio/allocations/allocations-page.module.ts
  13. 11
      apps/client/src/app/pages/portfolio/allocations/allocations-page.routes.ts
  14. 28
      apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts
  15. 40
      apps/client/src/app/pages/portfolio/analysis/analysis-page.module.ts
  16. 11
      apps/client/src/app/pages/portfolio/analysis/analysis-page.routes.ts
  17. 21
      apps/client/src/app/pages/portfolio/fire/fire-page-routing.module.ts
  18. 15
      apps/client/src/app/pages/portfolio/fire/fire-page.component.ts
  19. 24
      apps/client/src/app/pages/portfolio/fire/fire-page.module.ts
  20. 14
      apps/client/src/app/pages/portfolio/fire/fire-page.routes.ts
  21. 6
      apps/client/src/app/pages/portfolio/portfolio-page.component.ts
  22. 21
      apps/client/src/app/pages/portfolio/portfolio-page.module.ts
  23. 27
      apps/client/src/app/pages/portfolio/portfolio-page.routes.ts
  24. 21
      apps/client/src/app/pages/portfolio/x-ray/x-ray-page-routing.module.ts
  25. 15
      apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.ts
  26. 24
      apps/client/src/app/pages/portfolio/x-ray/x-ray-page.module.ts
  27. 14
      apps/client/src/app/pages/portfolio/x-ray/x-ray-page.routes.ts

1
CHANGELOG.md

@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Improved the language localization in the users table of the admin control panel
- Refactored the portfolio pages to standalone
- Renamed `Settings` to `settings` in the `User` database schema
- Improved the language localization for Dutch (`nl`)
- Improved the language localization for Español (`es`)

4
apps/client/src/app/app-routing.module.ts

@ -103,9 +103,7 @@ const routes: Routes = [
{
path: internalRoutes.portfolio.path,
loadChildren: () =>
import('./pages/portfolio/portfolio-page.module').then(
(m) => m.PortfolioPageModule
)
import('./pages/portfolio/portfolio-page.routes').then((m) => m.routes)
},
{
path: publicRoutes.pricing.path,

16
apps/client/src/app/pages/portfolio/activities/activities-page.component.ts

@ -9,13 +9,17 @@ import { DEFAULT_PAGE_SIZE } from '@ghostfolio/common/config';
import { downloadAsFile } from '@ghostfolio/common/helper';
import { AssetProfileIdentifier, User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatDialog } from '@angular/material/dialog';
import { PageEvent } from '@angular/material/paginator';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { Sort, SortDirection } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { ActivatedRoute, Router } from '@angular/router';
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
import { format, parseISO } from 'date-fns';
import { addIcons } from 'ionicons';
import { addOutline } from 'ionicons/icons';
@ -29,10 +33,16 @@ import { ImportActivitiesDialogParams } from './import-activities-dialog/interfa
@Component({
host: { class: 'has-fab' },
imports: [
GfActivitiesTableComponent,
IonIcon,
MatButtonModule,
MatSnackBarModule,
RouterModule
],
selector: 'gf-activities-page',
styleUrls: ['./activities-page.scss'],
templateUrl: './activities-page.html',
standalone: false
templateUrl: './activities-page.html'
})
export class ActivitiesPageComponent implements OnDestroy, OnInit {
public dataSource: MatTableDataSource<Activity>;

32
apps/client/src/app/pages/portfolio/activities/activities-page.module.ts

@ -1,32 +0,0 @@
import { ImportActivitiesService } from '@ghostfolio/client/services/import-activities.service';
import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table';
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
import { ActivitiesPageRoutingModule } from './activities-page-routing.module';
import { ActivitiesPageComponent } from './activities-page.component';
import { GfCreateOrUpdateActivityDialogModule } from './create-or-update-activity-dialog/create-or-update-activity-dialog.module';
import { GfImportActivitiesDialogModule } from './import-activities-dialog/import-activities-dialog.module';
@NgModule({
declarations: [ActivitiesPageComponent],
imports: [
ActivitiesPageRoutingModule,
CommonModule,
GfActivitiesTableComponent,
GfCreateOrUpdateActivityDialogModule,
GfImportActivitiesDialogModule,
IonIcon,
MatButtonModule,
MatSnackBarModule,
RouterModule
],
providers: [ImportActivitiesService],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class ActivitiesPageModule {}

11
apps/client/src/app/pages/portfolio/activities/activities-page-routing.module.ts → apps/client/src/app/pages/portfolio/activities/activities-page.routes.ts

@ -1,12 +1,11 @@
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { Routes } from '@angular/router';
import { ActivitiesPageComponent } from './activities-page.component';
const routes: Routes = [
export const routes: Routes = [
{
canActivate: [AuthGuard],
component: ActivitiesPageComponent,
@ -14,9 +13,3 @@ const routes: Routes = [
title: internalRoutes.portfolio.subRoutes.activities.title
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ActivitiesPageRoutingModule {}

46
apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts

@ -4,8 +4,13 @@ import { UserService } from '@ghostfolio/client/services/user/user.service';
import { getDateFormatString } from '@ghostfolio/common/helper';
import { LookupItem } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo';
import { translate } from '@ghostfolio/ui/i18n';
import { GfSymbolAutocompleteComponent } from '@ghostfolio/ui/symbol-autocomplete';
import { GfTagsSelectorComponent } from '@ghostfolio/ui/tags-selector';
import { GfValueComponent } from '@ghostfolio/ui/value';
import { NgClass } from '@angular/common';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
@ -13,9 +18,25 @@ import {
Inject,
OnDestroy
} from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import {
FormBuilder,
FormGroup,
ReactiveFormsModule,
Validators
} from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { DateAdapter, MAT_DATE_LOCALE } from '@angular/material/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { MatDatepickerModule } from '@angular/material/datepicker';
import {
MAT_DIALOG_DATA,
MatDialogModule,
MatDialogRef
} from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { IonIcon } from '@ionic/angular/standalone';
import { AssetClass, AssetSubClass, Tag, Type } from '@prisma/client';
import { isAfter, isToday } from 'date-fns';
import { addIcons } from 'ionicons';
@ -28,12 +49,27 @@ import { validateObjectForForm } from '../../../../util/form.util';
import { CreateOrUpdateActivityDialogParams } from './interfaces/interfaces';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'h-100' },
imports: [
GfEntityLogoComponent,
GfSymbolAutocompleteComponent,
GfTagsSelectorComponent,
GfValueComponent,
IonIcon,
MatButtonModule,
MatCheckboxModule,
MatDatepickerModule,
MatDialogModule,
MatFormFieldModule,
MatInputModule,
MatSelectModule,
NgClass,
ReactiveFormsModule
],
selector: 'gf-create-or-update-activity-dialog',
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrls: ['./create-or-update-activity-dialog.scss'],
templateUrl: 'create-or-update-activity-dialog.html',
standalone: false
templateUrl: 'create-or-update-activity-dialog.html'
})
export class CreateOrUpdateActivityDialog implements OnDestroy {
public activityForm: FormGroup;

41
apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.module.ts

@ -1,41 +0,0 @@
import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo';
import { GfSymbolAutocompleteComponent } from '@ghostfolio/ui/symbol-autocomplete';
import { GfTagsSelectorComponent } from '@ghostfolio/ui/tags-selector';
import { GfValueComponent } from '@ghostfolio/ui/value';
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatDialogModule } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { IonIcon } from '@ionic/angular/standalone';
import { CreateOrUpdateActivityDialog } from './create-or-update-activity-dialog.component';
@NgModule({
declarations: [CreateOrUpdateActivityDialog],
imports: [
CommonModule,
FormsModule,
GfEntityLogoComponent,
GfSymbolAutocompleteComponent,
GfTagsSelectorComponent,
GfValueComponent,
IonIcon,
MatButtonModule,
MatCheckboxModule,
MatDatepickerModule,
MatDialogModule,
MatFormFieldModule,
MatInputModule,
MatSelectModule,
ReactiveFormsModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class GfCreateOrUpdateActivityDialogModule {}

45
apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts

@ -1,8 +1,13 @@
import { CreateAccountDto } from '@ghostfolio/api/app/account/create-account.dto';
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
import { GfDialogFooterModule } from '@ghostfolio/client/components/dialog-footer/dialog-footer.module';
import { GfDialogHeaderModule } from '@ghostfolio/client/components/dialog-header/dialog-header.module';
import { GfFileDropModule } from '@ghostfolio/client/directives/file-drop/file-drop.module';
import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module';
import { DataService } from '@ghostfolio/client/services/data.service';
import { ImportActivitiesService } from '@ghostfolio/client/services/import-activities.service';
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table';
import {
StepperOrientation,
@ -15,12 +20,27 @@ import {
Inject,
OnDestroy
} from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import {
FormBuilder,
FormGroup,
ReactiveFormsModule,
Validators
} from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import {
MAT_DIALOG_DATA,
MatDialogModule,
MatDialogRef
} from '@angular/material/dialog';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSelectModule } from '@angular/material/select';
import { MatSnackBar } from '@angular/material/snack-bar';
import { SortDirection } from '@angular/material/sort';
import { MatStepper } from '@angular/material/stepper';
import { MatStepper, MatStepperModule } from '@angular/material/stepper';
import { MatTableDataSource } from '@angular/material/table';
import { IonIcon } from '@ionic/angular/standalone';
import { AssetClass } from '@prisma/client';
import { addIcons } from 'ionicons';
import { cloudUploadOutline, warningOutline } from 'ionicons/icons';
@ -34,10 +54,25 @@ import { ImportActivitiesDialogParams } from './interfaces/interfaces';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
GfActivitiesTableComponent,
GfDialogFooterModule,
GfDialogHeaderModule,
GfFileDropModule,
GfSymbolModule,
IonIcon,
MatButtonModule,
MatDialogModule,
MatExpansionModule,
MatFormFieldModule,
MatProgressSpinnerModule,
MatSelectModule,
MatStepperModule,
ReactiveFormsModule
],
selector: 'gf-import-activities-dialog',
styleUrls: ['./import-activities-dialog.scss'],
templateUrl: 'import-activities-dialog.html',
standalone: false
templateUrl: 'import-activities-dialog.html'
})
export class ImportActivitiesDialog implements OnDestroy {
public accounts: CreateAccountDto[] = [];

4
apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html

@ -14,7 +14,7 @@
[selectedIndex]="importStep"
(selectionChange)="onImportStepChange($event)"
>
<mat-step [completed]="importStep === 0" [selected]="importStep === 0">
<mat-step [completed]="importStep === 0">
<ng-template matStepLabel>
@if (mode === 'DIVIDEND') {
<ng-container i18n>Select Holding</ng-container>
@ -107,7 +107,7 @@
</div>
</mat-step>
<mat-step [completed]="importStep === 1" [selected]="importStep === 1">
<mat-step [completed]="importStep === 1">
<ng-template matStepLabel>
@if (mode === 'DIVIDEND') {
<ng-container i18n>Select Dividends</ng-container>

43
apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.module.ts

@ -1,43 +0,0 @@
import { GfDialogFooterModule } from '@ghostfolio/client/components/dialog-footer/dialog-footer.module';
import { GfDialogHeaderModule } from '@ghostfolio/client/components/dialog-header/dialog-header.module';
import { GfFileDropModule } from '@ghostfolio/client/directives/file-drop/file-drop.module';
import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module';
import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table';
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule } from '@angular/material/dialog';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSelectModule } from '@angular/material/select';
import { MatStepperModule } from '@angular/material/stepper';
import { IonIcon } from '@ionic/angular/standalone';
import { ImportActivitiesDialog } from './import-activities-dialog.component';
@NgModule({
declarations: [ImportActivitiesDialog],
imports: [
CommonModule,
FormsModule,
GfActivitiesTableComponent,
GfDialogFooterModule,
GfDialogHeaderModule,
GfFileDropModule,
GfSymbolModule,
IonIcon,
MatButtonModule,
MatDialogModule,
MatExpansionModule,
MatFormFieldModule,
MatProgressSpinnerModule,
MatSelectModule,
MatStepperModule,
ReactiveFormsModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class GfImportActivitiesDialogModule {}

21
apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts

@ -1,5 +1,6 @@
import { AccountDetailDialog } from '@ghostfolio/client/components/account-detail-dialog/account-detail-dialog.component';
import { AccountDetailDialogParams } from '@ghostfolio/client/components/account-detail-dialog/interfaces/interfaces';
import { GfWorldMapChartModule } from '@ghostfolio/client/components/world-map-chart/world-map-chart.module';
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';
@ -15,9 +16,16 @@ import {
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { Market, MarketAdvanced } from '@ghostfolio/common/types';
import { translate } from '@ghostfolio/ui/i18n';
import { GfPortfolioProportionChartComponent } from '@ghostfolio/ui/portfolio-proportion-chart';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { GfTopHoldingsComponent } from '@ghostfolio/ui/top-holdings';
import { GfValueComponent } from '@ghostfolio/ui/value';
import { NgClass } from '@angular/common';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { MatCardModule } from '@angular/material/card';
import { MatDialog } from '@angular/material/dialog';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { ActivatedRoute, Router } from '@angular/router';
import { Account, AssetClass, DataSource, Platform } from '@prisma/client';
import { isNumber } from 'lodash';
@ -26,10 +34,19 @@ import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Component({
imports: [
GfPortfolioProportionChartComponent,
GfPremiumIndicatorComponent,
GfTopHoldingsComponent,
GfValueComponent,
GfWorldMapChartModule,
MatCardModule,
MatProgressBarModule,
NgClass
],
selector: 'gf-allocations-page',
styleUrls: ['./allocations-page.scss'],
templateUrl: './allocations-page.html',
standalone: false
templateUrl: './allocations-page.html'
})
export class AllocationsPageComponent implements OnDestroy, OnInit {
public accounts: {

32
apps/client/src/app/pages/portfolio/allocations/allocations-page.module.ts

@ -1,32 +0,0 @@
import { GfWorldMapChartModule } from '@ghostfolio/client/components/world-map-chart/world-map-chart.module';
import { GfPortfolioProportionChartComponent } from '@ghostfolio/ui/portfolio-proportion-chart';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { GfTopHoldingsComponent } from '@ghostfolio/ui/top-holdings';
import { GfValueComponent } from '@ghostfolio/ui/value';
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatCardModule } from '@angular/material/card';
import { MatDialogModule } from '@angular/material/dialog';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { AllocationsPageRoutingModule } from './allocations-page-routing.module';
import { AllocationsPageComponent } from './allocations-page.component';
@NgModule({
declarations: [AllocationsPageComponent],
imports: [
AllocationsPageRoutingModule,
CommonModule,
GfPortfolioProportionChartComponent,
GfPremiumIndicatorComponent,
GfTopHoldingsComponent,
GfValueComponent,
GfWorldMapChartModule,
MatCardModule,
MatDialogModule,
MatProgressBarModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AllocationsPageModule {}

11
apps/client/src/app/pages/portfolio/allocations/allocations-page-routing.module.ts → apps/client/src/app/pages/portfolio/allocations/allocations-page.routes.ts

@ -1,11 +1,10 @@
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { Routes } from '@angular/router';
import { AllocationsPageComponent } from './allocations-page.component';
const routes: Routes = [
export const routes: Routes = [
{
canActivate: [AuthGuard],
component: AllocationsPageComponent,
@ -13,9 +12,3 @@ const routes: Routes = [
title: $localize`Allocations`
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class AllocationsPageRoutingModule {}

28
apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts

@ -1,4 +1,7 @@
import { GfBenchmarkComparatorModule } from '@ghostfolio/client/components/benchmark-comparator/benchmark-comparator.module';
import { GfInvestmentChartModule } from '@ghostfolio/client/components/investment-chart/investment-chart.module';
import { ToggleComponent } from '@ghostfolio/client/components/toggle/toggle.component';
import { GfToggleModule } from '@ghostfolio/client/components/toggle/toggle.module';
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';
@ -14,6 +17,8 @@ import {
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import type { AiPromptMode, GroupBy } from '@ghostfolio/common/types';
import { translate } from '@ghostfolio/ui/i18n';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { GfValueComponent } from '@ghostfolio/ui/value';
import { Clipboard } from '@angular/cdk/clipboard';
import {
@ -23,22 +28,39 @@ import {
OnInit,
ViewChild
} from '@angular/core';
import { MatMenuTrigger } from '@angular/material/menu';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSnackBar } from '@angular/material/snack-bar';
import { IonIcon } from '@ionic/angular/standalone';
import { SymbolProfile } from '@prisma/client';
import { addIcons } from 'ionicons';
import { copyOutline, ellipsisVertical } from 'ionicons/icons';
import { isNumber, sortBy } from 'lodash';
import ms from 'ms';
import { DeviceDetectorService } from 'ngx-device-detector';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Component({
imports: [
GfBenchmarkComparatorModule,
GfInvestmentChartModule,
GfPremiumIndicatorComponent,
GfToggleModule,
GfValueComponent,
IonIcon,
MatButtonModule,
MatCardModule,
MatMenuModule,
MatProgressSpinnerModule,
NgxSkeletonLoaderModule
],
selector: 'gf-analysis-page',
styleUrls: ['./analysis-page.scss'],
templateUrl: './analysis-page.html',
standalone: false
templateUrl: './analysis-page.html'
})
export class AnalysisPageComponent implements OnDestroy, OnInit {
@ViewChild(MatMenuTrigger) actionsMenuButton!: MatMenuTrigger;

40
apps/client/src/app/pages/portfolio/analysis/analysis-page.module.ts

@ -1,40 +0,0 @@
import { GfBenchmarkComparatorModule } from '@ghostfolio/client/components/benchmark-comparator/benchmark-comparator.module';
import { GfInvestmentChartModule } from '@ghostfolio/client/components/investment-chart/investment-chart.module';
import { GfToggleModule } from '@ghostfolio/client/components/toggle/toggle.module';
import { GfActivitiesFilterComponent } from '@ghostfolio/ui/activities-filter';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { GfValueComponent } from '@ghostfolio/ui/value';
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatMenuModule } from '@angular/material/menu';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { IonIcon } from '@ionic/angular/standalone';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { AnalysisPageRoutingModule } from './analysis-page-routing.module';
import { AnalysisPageComponent } from './analysis-page.component';
@NgModule({
declarations: [AnalysisPageComponent],
imports: [
AnalysisPageRoutingModule,
CommonModule,
GfActivitiesFilterComponent,
GfBenchmarkComparatorModule,
GfInvestmentChartModule,
GfPremiumIndicatorComponent,
GfToggleModule,
GfValueComponent,
IonIcon,
MatButtonModule,
MatCardModule,
MatMenuModule,
MatProgressSpinnerModule,
NgxSkeletonLoaderModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AnalysisPageModule {}

11
apps/client/src/app/pages/portfolio/analysis/analysis-page-routing.module.ts → apps/client/src/app/pages/portfolio/analysis/analysis-page.routes.ts

@ -1,12 +1,11 @@
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { Routes } from '@angular/router';
import { AnalysisPageComponent } from './analysis-page.component';
const routes: Routes = [
export const routes: Routes = [
{
canActivate: [AuthGuard],
component: AnalysisPageComponent,
@ -14,9 +13,3 @@ const routes: Routes = [
title: internalRoutes.portfolio.subRoutes.analysis.title
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class AnalysisPageRoutingModule {}

21
apps/client/src/app/pages/portfolio/fire/fire-page-routing.module.ts

@ -1,21 +0,0 @@
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { FirePageComponent } from './fire-page.component';
const routes: Routes = [
{
canActivate: [AuthGuard],
component: FirePageComponent,
path: '',
title: 'FIRE'
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class FirePageRoutingModule {}

15
apps/client/src/app/pages/portfolio/fire/fire-page.component.ts

@ -3,18 +3,29 @@ import { ImpersonationStorageService } from '@ghostfolio/client/services/imperso
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { GfFireCalculatorComponent } from '@ghostfolio/ui/fire-calculator';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { GfValueComponent } from '@ghostfolio/ui/value';
import { NgStyle } from '@angular/common';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { Big } from 'big.js';
import { DeviceDetectorService } from 'ngx-device-detector';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Component({
imports: [
GfFireCalculatorComponent,
GfPremiumIndicatorComponent,
GfValueComponent,
NgStyle,
NgxSkeletonLoaderModule
],
selector: 'gf-fire-page',
styleUrls: ['./fire-page.scss'],
templateUrl: './fire-page.html',
standalone: false
templateUrl: './fire-page.html'
})
export class FirePageComponent implements OnDestroy, OnInit {
public deviceType: string;

24
apps/client/src/app/pages/portfolio/fire/fire-page.module.ts

@ -1,24 +0,0 @@
import { GfFireCalculatorComponent } from '@ghostfolio/ui/fire-calculator';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { GfValueComponent } from '@ghostfolio/ui/value';
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { FirePageRoutingModule } from './fire-page-routing.module';
import { FirePageComponent } from './fire-page.component';
@NgModule({
declarations: [FirePageComponent],
imports: [
CommonModule,
FirePageRoutingModule,
GfFireCalculatorComponent,
GfPremiumIndicatorComponent,
GfValueComponent,
NgxSkeletonLoaderModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class FirePageModule {}

14
apps/client/src/app/pages/portfolio/fire/fire-page.routes.ts

@ -0,0 +1,14 @@
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { Routes } from '@angular/router';
import { FirePageComponent } from './fire-page.component';
export const routes: Routes = [
{
canActivate: [AuthGuard],
component: FirePageComponent,
path: '',
title: 'FIRE'
}
];

6
apps/client/src/app/pages/portfolio/portfolio-page.component.ts

@ -3,6 +3,8 @@ import { TabConfiguration, User } from '@ghostfolio/common/interfaces';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { MatTabsModule } from '@angular/material/tabs';
import { RouterModule } from '@angular/router';
import { addIcons } from 'ionicons';
import {
analyticsOutline,
@ -17,10 +19,10 @@ import { takeUntil } from 'rxjs/operators';
@Component({
host: { class: 'page has-tabs' },
imports: [MatTabsModule, RouterModule],
selector: 'gf-portfolio-page',
styleUrls: ['./portfolio-page.scss'],
templateUrl: './portfolio-page.html',
standalone: false
templateUrl: './portfolio-page.html'
})
export class PortfolioPageComponent implements OnDestroy, OnInit {
public deviceType: string;

21
apps/client/src/app/pages/portfolio/portfolio-page.module.ts

@ -1,21 +0,0 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatTabsModule } from '@angular/material/tabs';
import { RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
import { PortfolioPageRoutingModule } from './portfolio-page-routing.module';
import { PortfolioPageComponent } from './portfolio-page.component';
@NgModule({
declarations: [PortfolioPageComponent],
imports: [
CommonModule,
IonIcon,
MatTabsModule,
PortfolioPageRoutingModule,
RouterModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class PortfolioPageModule {}

27
apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts → apps/client/src/app/pages/portfolio/portfolio-page.routes.ts

@ -1,45 +1,38 @@
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { Routes } from '@angular/router';
import { PortfolioPageComponent } from './portfolio-page.component';
const routes: Routes = [
export const routes: Routes = [
{
canActivate: [AuthGuard],
children: [
{
path: '',
loadChildren: () =>
import('./analysis/analysis-page.module').then(
(m) => m.AnalysisPageModule
)
import('./analysis/analysis-page.routes').then((m) => m.routes)
},
{
path: internalRoutes.portfolio.subRoutes.activities.path,
loadChildren: () =>
import('./activities/activities-page.module').then(
(m) => m.ActivitiesPageModule
)
import('./activities/activities-page.routes').then((m) => m.routes)
},
{
path: internalRoutes.portfolio.subRoutes.allocations.path,
loadChildren: () =>
import('./allocations/allocations-page.module').then(
(m) => m.AllocationsPageModule
)
import('./allocations/allocations-page.routes').then((m) => m.routes)
},
{
path: internalRoutes.portfolio.subRoutes.fire.path,
loadChildren: () =>
import('./fire/fire-page.module').then((m) => m.FirePageModule)
import('./fire/fire-page.routes').then((m) => m.routes)
},
{
path: internalRoutes.portfolio.subRoutes.xRay.path,
loadChildren: () =>
import('./x-ray/x-ray-page.module').then((m) => m.XRayPageModule)
import('./x-ray/x-ray-page.routes').then((m) => m.routes)
}
],
component: PortfolioPageComponent,
@ -47,9 +40,3 @@ const routes: Routes = [
title: internalRoutes.portfolio.title
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class PortfolioPageRoutingModule {}

21
apps/client/src/app/pages/portfolio/x-ray/x-ray-page-routing.module.ts

@ -1,21 +0,0 @@
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { XRayPageComponent } from './x-ray-page.component';
const routes: Routes = [
{
canActivate: [AuthGuard],
component: XRayPageComponent,
path: '',
title: 'X-ray'
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class XRayPageRoutingModule {}

15
apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.ts

@ -1,4 +1,5 @@
import { UpdateUserSettingDto } from '@ghostfolio/api/app/user/update-user-setting.dto';
import { GfRulesModule } from '@ghostfolio/client/components/rules/rules.module';
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';
@ -8,21 +9,31 @@ import {
} from '@ghostfolio/common/interfaces';
import { User } from '@ghostfolio/common/interfaces/user.interface';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { NgClass } from '@angular/common';
import { ChangeDetectorRef, Component } from '@angular/core';
import { IonIcon } from '@ionic/angular/standalone';
import { addIcons } from 'ionicons';
import {
checkmarkCircleOutline,
removeCircleOutline,
warningOutline
} from 'ionicons/icons';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { Subject, takeUntil } from 'rxjs';
@Component({
imports: [
GfPremiumIndicatorComponent,
GfRulesModule,
IonIcon,
NgClass,
NgxSkeletonLoaderModule
],
selector: 'gf-x-ray-page',
styleUrl: './x-ray-page.component.scss',
templateUrl: './x-ray-page.component.html',
standalone: false
templateUrl: './x-ray-page.component.html'
})
export class XRayPageComponent {
public accountClusterRiskRules: PortfolioReportRule[];

24
apps/client/src/app/pages/portfolio/x-ray/x-ray-page.module.ts

@ -1,24 +0,0 @@
import { GfRulesModule } from '@ghostfolio/client/components/rules/rules.module';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { IonIcon } from '@ionic/angular/standalone';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { XRayPageRoutingModule } from './x-ray-page-routing.module';
import { XRayPageComponent } from './x-ray-page.component';
@NgModule({
declarations: [XRayPageComponent],
imports: [
CommonModule,
GfPremiumIndicatorComponent,
GfRulesModule,
IonIcon,
NgxSkeletonLoaderModule,
XRayPageRoutingModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class XRayPageModule {}

14
apps/client/src/app/pages/portfolio/x-ray/x-ray-page.routes.ts

@ -0,0 +1,14 @@
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { Routes } from '@angular/router';
import { XRayPageComponent } from './x-ray-page.component';
export const routes: Routes = [
{
canActivate: [AuthGuard],
component: XRayPageComponent,
path: '',
title: 'X-ray'
}
];
Loading…
Cancel
Save