Feature/migrate various pages to standalone components (#3404)
* Migrate to standalone components * Update changelog
This commit is contained in:
parent
5616bc4956
commit
5d9c38663d
@ -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/),
|
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).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Refactored various pages to standalone components
|
||||||
|
|
||||||
## 2.81.0 - 2024-05-12
|
## 2.81.0 - 2024-05-12
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
|
||||||
|
import { paths } from '@ghostfolio/client/core/paths';
|
||||||
import { PageTitleStrategy } from '@ghostfolio/client/services/page-title.strategy';
|
import { PageTitleStrategy } from '@ghostfolio/client/services/page-title.strategy';
|
||||||
|
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
@ -5,18 +7,6 @@ import { RouterModule, Routes, TitleStrategy } from '@angular/router';
|
|||||||
|
|
||||||
import { ModulePreloadService } from './core/module-preload.service';
|
import { ModulePreloadService } from './core/module-preload.service';
|
||||||
|
|
||||||
export const paths = {
|
|
||||||
about: $localize`about`,
|
|
||||||
faq: $localize`faq`,
|
|
||||||
features: $localize`features`,
|
|
||||||
license: $localize`license`,
|
|
||||||
markets: $localize`markets`,
|
|
||||||
pricing: $localize`pricing`,
|
|
||||||
privacyPolicy: $localize`privacy-policy`,
|
|
||||||
register: $localize`register`,
|
|
||||||
resources: $localize`resources`
|
|
||||||
};
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: paths.about,
|
path: paths.about,
|
||||||
@ -53,9 +43,12 @@ const routes: Routes = [
|
|||||||
import('./pages/blog/blog-page.module').then((m) => m.BlogPageModule)
|
import('./pages/blog/blog-page.module').then((m) => m.BlogPageModule)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'demo',
|
canActivate: [AuthGuard],
|
||||||
loadChildren: () =>
|
loadComponent: () =>
|
||||||
import('./pages/demo/demo-page.module').then((m) => m.DemoPageModule)
|
import('./pages/demo/demo-page.component').then(
|
||||||
|
(c) => c.GfDemoPageComponent
|
||||||
|
),
|
||||||
|
path: 'demo'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: paths.faq,
|
path: paths.faq,
|
||||||
@ -63,11 +56,13 @@ const routes: Routes = [
|
|||||||
import('./pages/faq/faq-page.module').then((m) => m.FaqPageModule)
|
import('./pages/faq/faq-page.module').then((m) => m.FaqPageModule)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
canActivate: [AuthGuard],
|
||||||
|
loadComponent: () =>
|
||||||
|
import('./pages/features/features-page.component').then(
|
||||||
|
(c) => c.GfFeaturesPageComponent
|
||||||
|
),
|
||||||
path: paths.features,
|
path: paths.features,
|
||||||
loadChildren: () =>
|
title: $localize`Features`
|
||||||
import('./pages/features/features-page.module').then(
|
|
||||||
(m) => m.FeaturesPageModule
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'home',
|
path: 'home',
|
||||||
@ -75,9 +70,13 @@ const routes: Routes = [
|
|||||||
import('./pages/home/home-page.module').then((m) => m.HomePageModule)
|
import('./pages/home/home-page.module').then((m) => m.HomePageModule)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
canActivate: [AuthGuard],
|
||||||
|
loadComponent: () =>
|
||||||
|
import('./pages/i18n/i18n-page.component').then(
|
||||||
|
(c) => c.GfI18nPageComponent
|
||||||
|
),
|
||||||
path: 'i18n',
|
path: 'i18n',
|
||||||
loadChildren: () =>
|
title: $localize`Internationalization`
|
||||||
import('./pages/i18n/i18n-page.module').then((m) => m.I18nPageModule)
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: paths.markets,
|
path: paths.markets,
|
||||||
@ -134,11 +133,12 @@ const routes: Routes = [
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
loadComponent: () =>
|
||||||
|
import('./pages/webauthn/webauthn-page.component').then(
|
||||||
|
(c) => c.GfWebauthnPageComponent
|
||||||
|
),
|
||||||
path: 'webauthn',
|
path: 'webauthn',
|
||||||
loadChildren: () =>
|
title: $localize`Sign in`
|
||||||
import('./pages/webauthn/webauthn-page.module').then(
|
|
||||||
(m) => m.WebauthnPageModule
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'zen',
|
path: 'zen',
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { paths } from '@ghostfolio/client/app-routing.module';
|
|
||||||
import { DataService } from '@ghostfolio/client/services/data.service';
|
import { DataService } from '@ghostfolio/client/services/data.service';
|
||||||
import { SettingsStorageService } from '@ghostfolio/client/services/settings-storage.service';
|
import { SettingsStorageService } from '@ghostfolio/client/services/settings-storage.service';
|
||||||
import { UserService } from '@ghostfolio/client/services/user/user.service';
|
import { UserService } from '@ghostfolio/client/services/user/user.service';
|
||||||
@ -12,6 +11,8 @@ import {
|
|||||||
import { EMPTY } from 'rxjs';
|
import { EMPTY } from 'rxjs';
|
||||||
import { catchError } from 'rxjs/operators';
|
import { catchError } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { paths } from './paths';
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AuthGuard {
|
export class AuthGuard {
|
||||||
private static PUBLIC_PAGE_ROUTES = [
|
private static PUBLIC_PAGE_ROUTES = [
|
||||||
|
11
apps/client/src/app/core/paths.ts
Normal file
11
apps/client/src/app/core/paths.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export const paths = {
|
||||||
|
about: $localize`about`,
|
||||||
|
faq: $localize`faq`,
|
||||||
|
features: $localize`features`,
|
||||||
|
license: $localize`license`,
|
||||||
|
markets: $localize`markets`,
|
||||||
|
pricing: $localize`pricing`,
|
||||||
|
privacyPolicy: $localize`privacy-policy`,
|
||||||
|
register: $localize`register`,
|
||||||
|
resources: $localize`resources`
|
||||||
|
};
|
@ -1,5 +1,5 @@
|
|||||||
import { paths } from '@ghostfolio/client/app-routing.module';
|
|
||||||
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
|
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
|
||||||
|
import { paths } from '@ghostfolio/client/core/paths';
|
||||||
|
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
|
|
||||||
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
|
||||||
|
|
||||||
import { DemoPageComponent } from './demo-page.component';
|
|
||||||
|
|
||||||
const routes: Routes = [
|
|
||||||
{ path: '', component: DemoPageComponent, canActivate: [AuthGuard] }
|
|
||||||
];
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [RouterModule.forChild(routes)],
|
|
||||||
exports: [RouterModule]
|
|
||||||
})
|
|
||||||
export class DemoPageRoutingModule {}
|
|
@ -2,16 +2,19 @@ import { DataService } from '@ghostfolio/client/services/data.service';
|
|||||||
import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service';
|
import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service';
|
||||||
import { InfoItem } from '@ghostfolio/common/interfaces';
|
import { InfoItem } from '@ghostfolio/common/interfaces';
|
||||||
|
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
import { Component, OnDestroy } from '@angular/core';
|
import { Component, OnDestroy } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
host: { class: 'page' },
|
host: { class: 'page' },
|
||||||
|
imports: [CommonModule],
|
||||||
selector: 'gf-demo-page',
|
selector: 'gf-demo-page',
|
||||||
|
standalone: true,
|
||||||
templateUrl: './demo-page.html'
|
templateUrl: './demo-page.html'
|
||||||
})
|
})
|
||||||
export class DemoPageComponent implements OnDestroy {
|
export class GfDemoPageComponent implements OnDestroy {
|
||||||
public info: InfoItem;
|
public info: InfoItem;
|
||||||
|
|
||||||
private unsubscribeSubject = new Subject<void>();
|
private unsubscribeSubject = new Subject<void>();
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
|
||||||
|
|
||||||
import { DemoPageRoutingModule } from './demo-page-routing.module';
|
|
||||||
import { DemoPageComponent } from './demo-page.component';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [DemoPageComponent],
|
|
||||||
imports: [CommonModule, DemoPageRoutingModule],
|
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
|
||||||
})
|
|
||||||
export class DemoPageModule {}
|
|
@ -1,21 +0,0 @@
|
|||||||
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
|
|
||||||
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
|
||||||
|
|
||||||
import { FeaturesPageComponent } from './features-page.component';
|
|
||||||
|
|
||||||
const routes: Routes = [
|
|
||||||
{
|
|
||||||
canActivate: [AuthGuard],
|
|
||||||
component: FeaturesPageComponent,
|
|
||||||
path: '',
|
|
||||||
title: $localize`Features`
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [RouterModule.forChild(routes)],
|
|
||||||
exports: [RouterModule]
|
|
||||||
})
|
|
||||||
export class FeaturesPageRoutingModule {}
|
|
@ -2,17 +2,30 @@ import { DataService } from '@ghostfolio/client/services/data.service';
|
|||||||
import { UserService } from '@ghostfolio/client/services/user/user.service';
|
import { UserService } from '@ghostfolio/client/services/user/user.service';
|
||||||
import { InfoItem, User } from '@ghostfolio/common/interfaces';
|
import { InfoItem, 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 { ChangeDetectorRef, Component, OnDestroy } from '@angular/core';
|
import { ChangeDetectorRef, Component, OnDestroy } from '@angular/core';
|
||||||
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { MatCardModule } from '@angular/material/card';
|
||||||
|
import { RouterModule } from '@angular/router';
|
||||||
import { Subject, takeUntil } from 'rxjs';
|
import { Subject, takeUntil } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
host: { class: 'page' },
|
host: { class: 'page' },
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
GfPremiumIndicatorComponent,
|
||||||
|
MatButtonModule,
|
||||||
|
MatCardModule,
|
||||||
|
RouterModule
|
||||||
|
],
|
||||||
selector: 'gf-features-page',
|
selector: 'gf-features-page',
|
||||||
|
standalone: true,
|
||||||
styleUrls: ['./features-page.scss'],
|
styleUrls: ['./features-page.scss'],
|
||||||
templateUrl: './features-page.html'
|
templateUrl: './features-page.html'
|
||||||
})
|
})
|
||||||
export class FeaturesPageComponent implements OnDestroy {
|
export class GfFeaturesPageComponent implements OnDestroy {
|
||||||
public hasPermissionForSubscription: boolean;
|
public hasPermissionForSubscription: boolean;
|
||||||
public info: InfoItem;
|
public info: InfoItem;
|
||||||
public routerLinkRegister = ['/' + $localize`register`];
|
public routerLinkRegister = ['/' + $localize`register`];
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
|
|
||||||
|
|
||||||
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 { FeaturesPageRoutingModule } from './features-page-routing.module';
|
|
||||||
import { FeaturesPageComponent } from './features-page.component';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [FeaturesPageComponent],
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
FeaturesPageRoutingModule,
|
|
||||||
GfPremiumIndicatorComponent,
|
|
||||||
MatButtonModule,
|
|
||||||
MatCardModule
|
|
||||||
],
|
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
|
||||||
})
|
|
||||||
export class FeaturesPageModule {}
|
|
@ -1,20 +0,0 @@
|
|||||||
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
|
|
||||||
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
|
||||||
|
|
||||||
import { I18nPageComponent } from './i18n-page.component';
|
|
||||||
|
|
||||||
const routes: Routes = [
|
|
||||||
{
|
|
||||||
canActivate: [AuthGuard],
|
|
||||||
component: I18nPageComponent,
|
|
||||||
path: ''
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [RouterModule.forChild(routes)],
|
|
||||||
exports: [RouterModule]
|
|
||||||
})
|
|
||||||
export class I18nPageRoutingModule {}
|
|
@ -1,13 +1,16 @@
|
|||||||
|
import { CommonModule } from '@angular/common';
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
host: { class: 'page' },
|
host: { class: 'page' },
|
||||||
|
imports: [CommonModule],
|
||||||
selector: 'gf-i18n-page',
|
selector: 'gf-i18n-page',
|
||||||
|
standalone: true,
|
||||||
styleUrls: ['./i18n-page.scss'],
|
styleUrls: ['./i18n-page.scss'],
|
||||||
templateUrl: './i18n-page.html'
|
templateUrl: './i18n-page.html'
|
||||||
})
|
})
|
||||||
export class I18nPageComponent implements OnInit {
|
export class GfI18nPageComponent implements OnInit {
|
||||||
private unsubscribeSubject = new Subject<void>();
|
private unsubscribeSubject = new Subject<void>();
|
||||||
|
|
||||||
public constructor() {}
|
public constructor() {}
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
|
||||||
|
|
||||||
import { I18nPageRoutingModule } from './i18n-page-routing.module';
|
|
||||||
import { I18nPageComponent } from './i18n-page.component';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [I18nPageComponent],
|
|
||||||
imports: [CommonModule, I18nPageRoutingModule],
|
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
|
||||||
})
|
|
||||||
export class I18nPageModule {}
|
|
@ -1,14 +0,0 @@
|
|||||||
import { WebauthnPageComponent } from '@ghostfolio/client/pages/webauthn/webauthn-page.component';
|
|
||||||
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
|
||||||
|
|
||||||
const routes: Routes = [
|
|
||||||
{ component: WebauthnPageComponent, path: '', title: $localize`Sign in` }
|
|
||||||
];
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [RouterModule.forChild(routes)],
|
|
||||||
exports: [RouterModule]
|
|
||||||
})
|
|
||||||
export class WebauthnPageRoutingModule {}
|
|
@ -1,18 +1,29 @@
|
|||||||
import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service';
|
import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service';
|
||||||
import { WebAuthnService } from '@ghostfolio/client/services/web-authn.service';
|
import { WebAuthnService } from '@ghostfolio/client/services/web-authn.service';
|
||||||
|
import { GfLogoComponent } from '@ghostfolio/ui/logo';
|
||||||
|
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
|
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
host: { class: 'page' },
|
host: { class: 'page' },
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
GfLogoComponent,
|
||||||
|
MatButtonModule,
|
||||||
|
MatProgressSpinnerModule
|
||||||
|
],
|
||||||
selector: 'gf-webauthn-page',
|
selector: 'gf-webauthn-page',
|
||||||
|
standalone: true,
|
||||||
styleUrls: ['./webauthn-page.scss'],
|
styleUrls: ['./webauthn-page.scss'],
|
||||||
templateUrl: './webauthn-page.html'
|
templateUrl: './webauthn-page.html'
|
||||||
})
|
})
|
||||||
export class WebauthnPageComponent implements OnDestroy, OnInit {
|
export class GfWebauthnPageComponent implements OnDestroy, OnInit {
|
||||||
public hasError = false;
|
public hasError = false;
|
||||||
|
|
||||||
private unsubscribeSubject = new Subject<void>();
|
private unsubscribeSubject = new Subject<void>();
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
import { WebauthnPageComponent } from '@ghostfolio/client/pages/webauthn/webauthn-page.component';
|
|
||||||
import { GfLogoComponent } from '@ghostfolio/ui/logo';
|
|
||||||
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
||||||
|
|
||||||
import { WebauthnPageRoutingModule } from './webauthn-page-routing.module';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [WebauthnPageComponent],
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
GfLogoComponent,
|
|
||||||
MatButtonModule,
|
|
||||||
MatProgressSpinnerModule,
|
|
||||||
WebauthnPageRoutingModule
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class WebauthnPageModule {}
|
|
Loading…
x
Reference in New Issue
Block a user