Browse Source

Feature/migrate user account page components to standalone (#5110)

* Migrate user account page components to standalone

* Update changelog
pull/5123/head
Thomas Kaul 2 weeks ago
committed by GitHub
parent
commit
f444237e50
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. 34
      apps/client/src/app/components/user-account-access/user-account-access.component.ts
  4. 35
      apps/client/src/app/components/user-account-access/user-account-access.module.ts
  5. 19
      apps/client/src/app/components/user-account-membership/user-account-membership.component.ts
  6. 26
      apps/client/src/app/components/user-account-membership/user-account-membership.module.ts
  7. 40
      apps/client/src/app/components/user-account-settings/user-account-settings.component.ts
  8. 36
      apps/client/src/app/components/user-account-settings/user-account-settings.module.ts
  9. 42
      apps/client/src/app/pages/user-account/user-account-page-routing.module.ts
  10. 19
      apps/client/src/app/pages/user-account/user-account-page.component.ts
  11. 26
      apps/client/src/app/pages/user-account/user-account-page.module.ts
  12. 35
      apps/client/src/app/pages/user-account/user-account-page.routes.ts

1
CHANGELOG.md

@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Improved the language localization in the users table of the admin control panel - Improved the language localization in the users table of the admin control panel
- Refactored the accounts pages to standalone - Refactored the accounts pages to standalone
- Refactored the portfolio pages to standalone - Refactored the portfolio pages to standalone
- Refactored the user account pages to standalone
- Renamed `Settings` to `settings` in the `User` database schema - Renamed `Settings` to `settings` in the `User` database schema
- Improved the language localization for Catalan (`ca`) - Improved the language localization for Catalan (`ca`)
- Improved the language localization for Dutch (`nl`) - Improved the language localization for Dutch (`nl`)

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

@ -16,8 +16,8 @@ const routes: Routes = [
{ {
path: internalRoutes.account.path, path: internalRoutes.account.path,
loadChildren: () => loadChildren: () =>
import('./pages/user-account/user-account-page.module').then( import('./pages/user-account/user-account-page.routes').then(
(m) => m.UserAccountPageModule (m) => m.routes
) )
}, },
{ {

34
apps/client/src/app/components/user-account-access/user-account-access.component.ts

@ -1,4 +1,5 @@
import { CreateAccessDto } from '@ghostfolio/api/app/access/create-access.dto'; import { CreateAccessDto } from '@ghostfolio/api/app/access/create-access.dto';
import { GfPortfolioAccessTableModule } from '@ghostfolio/client/components/access-table/access-table.module';
import { ConfirmationDialogType } from '@ghostfolio/client/core/notification/confirmation-dialog/confirmation-dialog.type'; import { ConfirmationDialogType } from '@ghostfolio/client/core/notification/confirmation-dialog/confirmation-dialog.type';
import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { NotificationService } from '@ghostfolio/client/core/notification/notification.service';
import { DataService } from '@ghostfolio/client/services/data.service'; import { DataService } from '@ghostfolio/client/services/data.service';
@ -6,17 +7,24 @@ import { TokenStorageService } from '@ghostfolio/client/services/token-storage.s
import { UserService } from '@ghostfolio/client/services/user/user.service'; import { UserService } from '@ghostfolio/client/services/user/user.service';
import { Access, User } from '@ghostfolio/common/interfaces'; import { Access, User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
CUSTOM_ELEMENTS_SCHEMA,
OnDestroy, OnDestroy,
OnInit OnInit
} from '@angular/core'; } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms'; import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog'; import { MatButtonModule } from '@angular/material/button';
import { ActivatedRoute, Router } from '@angular/router'; import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
import { addIcons } from 'ionicons'; import { addIcons } from 'ionicons';
import { addOutline, eyeOffOutline, eyeOutline } from 'ionicons/icons'; import { addOutline, eyeOffOutline, eyeOutline } from 'ionicons/icons';
import { DeviceDetectorService } from 'ngx-device-detector'; import { DeviceDetectorService } from 'ngx-device-detector';
@ -24,16 +32,30 @@ import { EMPTY, Subject } from 'rxjs';
import { catchError, takeUntil } from 'rxjs/operators'; import { catchError, takeUntil } from 'rxjs/operators';
import { CreateOrUpdateAccessDialog } from './create-or-update-access-dialog/create-or-update-access-dialog.component'; import { CreateOrUpdateAccessDialog } from './create-or-update-access-dialog/create-or-update-access-dialog.component';
import { GfCreateOrUpdateAccessDialogModule } from './create-or-update-access-dialog/create-or-update-access-dialog.module';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'has-fab' }, host: { class: 'has-fab' },
imports: [
CommonModule,
GfCreateOrUpdateAccessDialogModule,
GfPortfolioAccessTableModule,
GfPremiumIndicatorComponent,
IonIcon,
MatButtonModule,
MatDialogModule,
MatFormFieldModule,
MatInputModule,
ReactiveFormsModule,
RouterModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
selector: 'gf-user-account-access', selector: 'gf-user-account-access',
styleUrls: ['./user-account-access.scss'], styleUrls: ['./user-account-access.scss'],
templateUrl: './user-account-access.html', templateUrl: './user-account-access.html'
standalone: false
}) })
export class UserAccountAccessComponent implements OnDestroy, OnInit { export class GfUserAccountAccessComponent implements OnDestroy, OnInit {
public accessesGet: Access[]; public accessesGet: Access[];
public accessesGive: Access[]; public accessesGive: Access[];
public deviceType: string; public deviceType: string;

35
apps/client/src/app/components/user-account-access/user-account-access.module.ts

@ -1,35 +0,0 @@
import { GfPortfolioAccessTableModule } from '@ghostfolio/client/components/access-table/access-table.module';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
import { GfCreateOrUpdateAccessDialogModule } from './create-or-update-access-dialog/create-or-update-access-dialog.module';
import { UserAccountAccessComponent } from './user-account-access.component';
@NgModule({
declarations: [UserAccountAccessComponent],
exports: [UserAccountAccessComponent],
imports: [
CommonModule,
GfCreateOrUpdateAccessDialogModule,
GfPortfolioAccessTableModule,
GfPremiumIndicatorComponent,
IonIcon,
MatButtonModule,
MatDialogModule,
MatFormFieldModule,
MatInputModule,
ReactiveFormsModule,
RouterModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class GfUserAccountAccessModule {}

19
apps/client/src/app/components/user-account-membership/user-account-membership.component.ts

@ -6,14 +6,20 @@ import { getDateFormatString } from '@ghostfolio/common/helper';
import { User } from '@ghostfolio/common/interfaces'; import { User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { publicRoutes } from '@ghostfolio/common/routes/routes'; import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { GfMembershipCardComponent } from '@ghostfolio/ui/membership-card';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
OnDestroy OnDestroy
} from '@angular/core'; } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatSnackBar } from '@angular/material/snack-bar'; import { MatSnackBar } from '@angular/material/snack-bar';
import { RouterModule } from '@angular/router';
import ms, { StringValue } from 'ms'; import ms, { StringValue } from 'ms';
import { StripeService } from 'ngx-stripe'; import { StripeService } from 'ngx-stripe';
import { EMPTY, Subject } from 'rxjs'; import { EMPTY, Subject } from 'rxjs';
@ -21,12 +27,19 @@ import { catchError, switchMap, takeUntil } from 'rxjs/operators';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
CommonModule,
GfMembershipCardComponent,
GfPremiumIndicatorComponent,
MatButtonModule,
MatCardModule,
RouterModule
],
selector: 'gf-user-account-membership', selector: 'gf-user-account-membership',
styleUrls: ['./user-account-membership.scss'], styleUrls: ['./user-account-membership.scss'],
templateUrl: './user-account-membership.html', templateUrl: './user-account-membership.html'
standalone: false
}) })
export class UserAccountMembershipComponent implements OnDestroy { export class GfUserAccountMembershipComponent implements OnDestroy {
public baseCurrency: string; public baseCurrency: string;
public coupon: number; public coupon: number;
public couponId: string; public couponId: string;

26
apps/client/src/app/components/user-account-membership/user-account-membership.module.ts

@ -1,26 +0,0 @@
import { GfMembershipCardComponent } from '@ghostfolio/ui/membership-card';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { GfValueComponent } from '@ghostfolio/ui/value';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { RouterModule } from '@angular/router';
import { UserAccountMembershipComponent } from './user-account-membership.component';
@NgModule({
declarations: [UserAccountMembershipComponent],
exports: [UserAccountMembershipComponent],
imports: [
CommonModule,
GfMembershipCardComponent,
GfPremiumIndicatorComponent,
GfValueComponent,
MatButtonModule,
MatCardModule,
RouterModule
]
})
export class GfUserAccountMembershipModule {}

40
apps/client/src/app/components/user-account-settings/user-account-settings.component.ts

@ -13,16 +13,33 @@ import { downloadAsFile } from '@ghostfolio/common/helper';
import { User } from '@ghostfolio/common/interfaces'; import { User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
CUSTOM_ELEMENTS_SCHEMA,
OnDestroy, OnDestroy,
OnInit OnInit
} from '@angular/core'; } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms'; import {
import { MatSlideToggleChange } from '@angular/material/slide-toggle'; FormBuilder,
FormsModule,
ReactiveFormsModule,
Validators
} from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import {
MatSlideToggleChange,
MatSlideToggleModule
} from '@angular/material/slide-toggle';
import { MatSnackBar } from '@angular/material/snack-bar'; import { MatSnackBar } from '@angular/material/snack-bar';
import { RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
import { format, parseISO } from 'date-fns'; import { format, parseISO } from 'date-fns';
import { addIcons } from 'ionicons'; import { addIcons } from 'ionicons';
import { eyeOffOutline, eyeOutline } from 'ionicons/icons'; import { eyeOffOutline, eyeOutline } from 'ionicons/icons';
@ -32,12 +49,25 @@ import { catchError, takeUntil } from 'rxjs/operators';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
CommonModule,
FormsModule,
IonIcon,
MatButtonModule,
MatCardModule,
MatFormFieldModule,
MatInputModule,
MatSelectModule,
MatSlideToggleModule,
ReactiveFormsModule,
RouterModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
selector: 'gf-user-account-settings', selector: 'gf-user-account-settings',
styleUrls: ['./user-account-settings.scss'], styleUrls: ['./user-account-settings.scss'],
templateUrl: './user-account-settings.html', templateUrl: './user-account-settings.html'
standalone: false
}) })
export class UserAccountSettingsComponent implements OnDestroy, OnInit { export class GfUserAccountSettingsComponent implements OnDestroy, OnInit {
public appearancePlaceholder = $localize`Auto`; public appearancePlaceholder = $localize`Auto`;
public baseCurrency: string; public baseCurrency: string;
public currencies: string[] = []; public currencies: string[] = [];

36
apps/client/src/app/components/user-account-settings/user-account-settings.module.ts

@ -1,36 +0,0 @@
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 { MatCardModule } from '@angular/material/card';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
import { UserAccountSettingsComponent } from './user-account-settings.component';
@NgModule({
declarations: [UserAccountSettingsComponent],
exports: [UserAccountSettingsComponent],
imports: [
CommonModule,
FormsModule,
GfValueComponent,
IonIcon,
MatButtonModule,
MatCardModule,
MatFormFieldModule,
MatInputModule,
MatSelectModule,
MatSlideToggleModule,
ReactiveFormsModule,
RouterModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class GfUserAccountSettingsModule {}

42
apps/client/src/app/pages/user-account/user-account-page-routing.module.ts

@ -1,42 +0,0 @@
import { UserAccountAccessComponent } from '@ghostfolio/client/components/user-account-access/user-account-access.component';
import { UserAccountMembershipComponent } from '@ghostfolio/client/components/user-account-membership/user-account-membership.component';
import { UserAccountSettingsComponent } from '@ghostfolio/client/components/user-account-settings/user-account-settings.component';
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 { UserAccountPageComponent } from './user-account-page.component';
const routes: Routes = [
{
canActivate: [AuthGuard],
children: [
{
path: '',
component: UserAccountSettingsComponent,
title: internalRoutes.account.title
},
{
path: internalRoutes.account.subRoutes.membership.path,
component: UserAccountMembershipComponent,
title: internalRoutes.account.subRoutes.membership.title
},
{
path: internalRoutes.account.subRoutes.access.path,
component: UserAccountAccessComponent,
title: internalRoutes.account.subRoutes.access.title
}
],
component: UserAccountPageComponent,
path: '',
title: $localize`My Ghostfolio`
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class UserAccountPageRoutingModule {}

19
apps/client/src/app/pages/user-account/user-account-page.component.ts

@ -2,7 +2,17 @@ import { UserService } from '@ghostfolio/client/services/user/user.service';
import { TabConfiguration, User } from '@ghostfolio/common/interfaces'; import { TabConfiguration, User } from '@ghostfolio/common/interfaces';
import { internalRoutes } from '@ghostfolio/common/routes/routes'; import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import { CommonModule } from '@angular/common';
import {
ChangeDetectorRef,
Component,
CUSTOM_ELEMENTS_SCHEMA,
OnDestroy,
OnInit
} from '@angular/core';
import { MatTabsModule } from '@angular/material/tabs';
import { RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
import { addIcons } from 'ionicons'; import { addIcons } from 'ionicons';
import { diamondOutline, keyOutline, settingsOutline } from 'ionicons/icons'; import { diamondOutline, keyOutline, settingsOutline } from 'ionicons/icons';
import { DeviceDetectorService } from 'ngx-device-detector'; import { DeviceDetectorService } from 'ngx-device-detector';
@ -10,12 +20,13 @@ import { Subject, takeUntil } from 'rxjs';
@Component({ @Component({
host: { class: 'page has-tabs' }, host: { class: 'page has-tabs' },
imports: [CommonModule, IonIcon, MatTabsModule, RouterModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
selector: 'gf-user-account-page', selector: 'gf-user-account-page',
styleUrls: ['./user-account-page.scss'], styleUrls: ['./user-account-page.scss'],
templateUrl: './user-account-page.html', templateUrl: './user-account-page.html'
standalone: false
}) })
export class UserAccountPageComponent implements OnDestroy, OnInit { export class GfUserAccountPageComponent implements OnDestroy, OnInit {
public deviceType: string; public deviceType: string;
public tabs: TabConfiguration[] = []; public tabs: TabConfiguration[] = [];
public user: User; public user: User;

26
apps/client/src/app/pages/user-account/user-account-page.module.ts

@ -1,26 +0,0 @@
import { GfUserAccountAccessModule } from '@ghostfolio/client/components/user-account-access/user-account-access.module';
import { GfUserAccountMembershipModule } from '@ghostfolio/client/components/user-account-membership/user-account-membership.module';
import { GfUserAccountSettingsModule } from '@ghostfolio/client/components/user-account-settings/user-account-settings.module';
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatTabsModule } from '@angular/material/tabs';
import { IonIcon } from '@ionic/angular/standalone';
import { UserAccountPageRoutingModule } from './user-account-page-routing.module';
import { UserAccountPageComponent } from './user-account-page.component';
@NgModule({
declarations: [UserAccountPageComponent],
imports: [
CommonModule,
GfUserAccountAccessModule,
GfUserAccountMembershipModule,
GfUserAccountSettingsModule,
IonIcon,
MatTabsModule,
UserAccountPageRoutingModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class UserAccountPageModule {}

35
apps/client/src/app/pages/user-account/user-account-page.routes.ts

@ -0,0 +1,35 @@
import { GfUserAccountAccessComponent } from '@ghostfolio/client/components/user-account-access/user-account-access.component';
import { GfUserAccountMembershipComponent } from '@ghostfolio/client/components/user-account-membership/user-account-membership.component';
import { GfUserAccountSettingsComponent } from '@ghostfolio/client/components/user-account-settings/user-account-settings.component';
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { Routes } from '@angular/router';
import { GfUserAccountPageComponent } from './user-account-page.component';
export const routes: Routes = [
{
canActivate: [AuthGuard],
children: [
{
path: '',
component: GfUserAccountSettingsComponent,
title: internalRoutes.account.title
},
{
path: internalRoutes.account.subRoutes.membership.path,
component: GfUserAccountMembershipComponent,
title: internalRoutes.account.subRoutes.membership.title
},
{
path: internalRoutes.account.subRoutes.access.path,
component: GfUserAccountAccessComponent,
title: internalRoutes.account.subRoutes.access.title
}
],
component: GfUserAccountPageComponent,
path: '',
title: $localize`My Ghostfolio`
}
];
Loading…
Cancel
Save