change child route behaviour

This commit is contained in:
rubikscraft 2022-03-16 22:27:03 +01:00
parent f2663ee76b
commit 5f1cf2911f
No known key found for this signature in database
GPG key ID: 1463EBE9200A5CD4
30 changed files with 204 additions and 88 deletions

View file

@ -34,7 +34,19 @@ export class AppComponent implements OnInit {
) {} ) {}
private get routeData(): PRouteData { private get routeData(): PRouteData {
return this.activatedRoute.firstChild?.snapshot.data ?? {}; let currentRoute: ActivatedRoute | null = this.activatedRoute;
let accumulate: PRouteData = {};
while (currentRoute !== null) {
const data = currentRoute.snapshot.data;
if (data !== undefined) {
accumulate = {
...accumulate,
...data,
};
}
currentRoute = currentRoute.firstChild;
}
return accumulate;
} }
ngOnInit() { ngOnInit() {
@ -67,13 +79,15 @@ export class AppComponent implements OnInit {
private async onNavigationError(event: NavigationError) { private async onNavigationError(event: NavigationError) {
const error: Error = event.error; const error: Error = event.error;
if (error.message.startsWith('Cannot match any routes')) if (error.message.startsWith('Cannot match any routes'))
this.router.navigate(['/pagenotfound']); this.router.navigate(['/error/404'], { replaceUrl: true });
} }
private async onNavigationEnd(event: NavigationEnd) { private async onNavigationEnd(event: NavigationEnd) {
const data = this.routeData; const data = this.routeData;
this.containerWrap = !data.noContainer; this.containerWrap = !data.noContainer;
console.log(data);
if (data.sidebar !== undefined) { if (data.sidebar !== undefined) {
this.sidebarPortal?.detach(); this.sidebarPortal?.detach();
this.sidebarPortal = new ComponentPortal(data.sidebar); this.sidebarPortal = new ComponentPortal(data.sidebar);

View file

@ -8,7 +8,6 @@ import { AppRoutingModule } from './app.routing.module';
import { FooterModule } from './components/footer/footer.module'; import { FooterModule } from './components/footer/footer.module';
import { HeaderModule } from './components/header/header.module'; import { HeaderModule } from './components/header/header.module';
import { GuardsModule } from './guards/guards.module'; import { GuardsModule } from './guards/guards.module';
import { routes } from './routes/routes';
@NgModule({ @NgModule({
declarations: [AppComponent], declarations: [AppComponent],
@ -23,8 +22,6 @@ import { routes } from './routes/routes';
HeaderModule, HeaderModule,
FooterModule, FooterModule,
...routes,
], ],
providers: [], providers: [],
bootstrap: [AppComponent], bootstrap: [AppComponent],

View file

@ -1,8 +1,44 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { PRoutes } from './models/picsur-routes'; import { PRoutes } from './models/picsur-routes';
import { ErrorsRouteModule } from './routes/errors/errors.module';
const routes: PRoutes = []; import { ProcessingRouteModule } from './routes/processing/processing.module';
import { SettingsRouteModule } from './routes/settings/settings.module';
import { UploadRouteModule } from './routes/upload/upload.module';
import { UserRouteModule } from './routes/user/user.module';
import { ViewRouteModule } from './routes/view/view.module';
// PageNotFoundRouteModule,
// UploadRouteModule,
// ProcessingRouteModule,
// ViewRouteModule,
// UserRouteModule,
// SettingsRouteModule,
const routes: PRoutes = [
{
path: '',
loadChildren: () => UploadRouteModule,
},
{
path: 'processing',
loadChildren: () => ProcessingRouteModule,
},
{
path: 'view',
loadChildren: () => ViewRouteModule,
},
{
path: 'user',
loadChildren: () => UserRouteModule,
},
{
path: 'settings',
loadChildren: () => SettingsRouteModule,
},
{
path: 'error',
loadChildren: () => ErrorsRouteModule,
},
];
@NgModule({ @NgModule({
imports: [ imports: [

View file

@ -2,7 +2,7 @@
<p> <p>
Made with 🤍 by Made with 🤍 by
<a class="link-unstyled" href="https://rubikscraft.nl" target="_blank" <a class="link-unstyled" href="https://rubikscraft.nl" target="_blank"
>RubiksCraft</a >Rubikscraft</a
> >
- -
<a class="link-unstyled" href="https://github.com/rubikscraft/picsur" <a class="link-unstyled" href="https://github.com/rubikscraft/picsur"

View file

@ -66,7 +66,7 @@ export class HeaderComponent implements OnInit {
} }
doLogin() { doLogin() {
this.router.navigate(['/login']); this.router.navigate(['/user/login']);
} }
doLogout() { doLogout() {

View file

@ -33,7 +33,7 @@ export class PermissionGuard implements CanActivate {
); );
if (!isOk) { if (!isOk) {
this.router.navigate(['/']); this.router.navigate(['/error/401'], { replaceUrl: true });
} }
return isOk; return isOk;
} }

View file

@ -3,6 +3,7 @@ import { Route } from '@angular/router';
import { Permissions } from 'picsur-shared/dist/dto/permissions'; import { Permissions } from 'picsur-shared/dist/dto/permissions';
export type PRouteData = { export type PRouteData = {
title?: string;
permissions?: Permissions; permissions?: Permissions;
noContainer?: boolean; noContainer?: boolean;
sidebar?: ComponentType<unknown>; sidebar?: ComponentType<unknown>;

View file

@ -0,0 +1,9 @@
import { Component } from '@angular/core';
@Component({
template: `
<h1>401 - Permission Denied</h1>
<p>You do not have access to this page</p>
`,
})
export class E401Component {}

View file

@ -0,0 +1,9 @@
import { Component } from '@angular/core';
@Component({
template: `
<h1>404 - Page not found</h1>
<p>The page you are looking for does not exist.</p>
`,
})
export class E404Component {}

View file

@ -0,0 +1,11 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { E401Component } from './401.component';
import { E404Component } from './404.component';
import { ErrorsRoutingModule } from './errors.routing.module';
@NgModule({
declarations: [E404Component, E401Component],
imports: [CommonModule, ErrorsRoutingModule],
})
export class ErrorsRouteModule {}

View file

@ -0,0 +1,22 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { PRoutes } from 'src/app/models/picsur-routes';
import { E401Component } from './401.component';
import { E404Component } from './404.component';
const routes: PRoutes = [
{
path: '404',
component: E404Component,
},
{
path: '401',
component: E401Component,
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class ErrorsRoutingModule {}

View file

@ -1,2 +0,0 @@
<h1>404 - Page not found</h1>
<p>The page you are looking for does not exist.</p>

View file

@ -1,8 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-pagenotfound',
templateUrl: './pagenotfound.component.html',
styleUrls: ['./pagenotfound.component.scss'],
})
export class PageNotFoundComponent {}

View file

@ -1,10 +0,0 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { PageNotFoundComponent } from './pagenotfound.component';
import { PageNotFoundRoutingModule } from './processing.routing.module';
@NgModule({
declarations: [PageNotFoundComponent],
imports: [CommonModule, PageNotFoundRoutingModule],
})
export class PageNotFoundRouteModule {}

View file

@ -5,7 +5,7 @@ import { ProcessingComponent } from './processing.component';
const routes: PRoutes = [ const routes: PRoutes = [
{ {
path: 'processing', path: '',
component: ProcessingComponent, component: ProcessingComponent,
}, },
]; ];

View file

@ -1,15 +0,0 @@
import { PageNotFoundRouteModule } from './pagenotfound/pagenotfound.module';
import { ProcessingRouteModule } from './processing/processing.module';
import { SettingsRouteModule } from './settings/settings.module';
import { UploadRouteModule } from './upload/upload.module';
import { UserRouteModule } from './user/user.module';
import { ViewRouteModule } from './view/view.module';
export const routes = [
PageNotFoundRouteModule,
UploadRouteModule,
ProcessingRouteModule,
ViewRouteModule,
UserRouteModule,
SettingsRouteModule,
];

View file

@ -0,0 +1,10 @@
import { Component, OnInit } from '@angular/core';
@Component({
templateUrl: './settings-general.component.html',
})
export class SettingsGeneralComponent implements OnInit {
constructor() {}
ngOnInit(): void {}
}

View file

@ -0,0 +1,13 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { SettingsGeneralComponent } from './settings-general.component';
import { SettingsGeneralRoutingModule } from './settings-home.routing.module';
@NgModule({
declarations: [SettingsGeneralComponent],
imports: [
CommonModule,
SettingsGeneralRoutingModule,
],
})
export class SettingsGeneralRouteModule {}

View file

@ -1,12 +1,12 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { PRoutes } from 'src/app/models/picsur-routes'; import { PRoutes } from 'src/app/models/picsur-routes';
import { PageNotFoundComponent } from './pagenotfound.component'; import { SettingsGeneralComponent } from './settings-general.component';
const routes: PRoutes = [ const routes: PRoutes = [
{ {
path: 'pagenotfound', path: '',
component: PageNotFoundComponent, component: SettingsGeneralComponent,
}, },
]; ];
@ -14,4 +14,4 @@ const routes: PRoutes = [
imports: [RouterModule.forChild(routes)], imports: [RouterModule.forChild(routes)],
exports: [RouterModule], exports: [RouterModule],
}) })
export class PageNotFoundRoutingModule {} export class SettingsGeneralRoutingModule {}

View file

@ -1,18 +0,0 @@
import {
Component,
OnInit
} from '@angular/core';
@Component({
templateUrl: './settings-home.component.html',
styleUrls: ['./settings-home.component.scss'],
})
export class SettingsHomeComponent implements OnInit {
constructor(
) {}
ngOnInit(): void {
console.log('AdminComponent');
}
}

View file

@ -1,6 +1,30 @@
<mat-nav-list> <mat-nav-list>
<a mat-list-item routerLink="/settings" routerLinkActive="active"> <ng-container *ngIf="personalRoutes.length > 0">
<mat-icon mat-list-icon>settings</mat-icon> <span mat-subheader>Personal</span>
<span mat-line>General</span> <a
</a> *ngFor="let route of personalRoutes"
mat-list-item
[routerLink]="route.path"
routerLinkActive="active"
>
<mat-icon mat-list-icon>{{ route.icon }}</mat-icon>
<span mat-line>{{ route.name }}</span>
</a>
</ng-container>
<mat-divider *ngIf="systemRoutes.length > 0 && personalRoutes.length > 0">
</mat-divider>
<ng-container *ngIf="systemRoutes.length > 0">
<span mat-subheader>System</span>
<a
*ngFor="let route of systemRoutes"
mat-list-item
[routerLink]="route.path"
routerLinkActive="active"
>
<mat-icon mat-list-icon>{{ route.icon }}</mat-icon>
<span mat-line>{{ route.name }}</span>
</a>
</ng-container>
</mat-nav-list> </mat-nav-list>

View file

@ -1,14 +1,40 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
type SideBarRoute = {
type: 'personal' | 'system';
path: string;
name: string;
icon: string;
};
const SideBarRoutes: SideBarRoute[] = [
{
type: 'personal',
path: '',
name: 'General',
icon: 'settings',
},
];
@Component({ @Component({
templateUrl: './settings-sidebar.component.html', templateUrl: './settings-sidebar.component.html',
styleUrls: ['./settings-sidebar.component.scss'] styleUrls: ['./settings-sidebar.component.scss'],
}) })
export class SettingsSidebarComponent implements OnInit { export class SettingsSidebarComponent implements OnInit {
personalRoutes: SideBarRoute[] = [];
systemRoutes: SideBarRoute[] = [];
constructor() { } constructor() {}
ngOnInit(): void { ngOnInit() {
const routes = SideBarRoutes.map((route) => {
return {
...route,
path: `/settings/${route.path}`,
};
});
this.personalRoutes = routes.filter((route) => route.type === 'personal');
this.systemRoutes = routes.filter((route) => route.type === 'system');
} }
} }

View file

@ -2,17 +2,14 @@ import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { MatIconModule } from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon';
import { MatListModule } from '@angular/material/list'; import { MatListModule } from '@angular/material/list';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { SettingsHomeComponent } from './settings-home/settings-home.component';
import { SettingsSidebarComponent } from './settings-sidebar/settings-sidebar.component'; import { SettingsSidebarComponent } from './settings-sidebar/settings-sidebar.component';
import { SettingsRoutingModule } from './settings.routing.module'; import { SettingsRoutingModule } from './settings.routing.module';
@NgModule({ @NgModule({
declarations: [SettingsHomeComponent, SettingsSidebarComponent], declarations: [SettingsSidebarComponent],
imports: [ imports: [
CommonModule, CommonModule,
SettingsRoutingModule, SettingsRoutingModule,
MatProgressSpinnerModule,
MatListModule, MatListModule,
MatIconModule, MatIconModule,

View file

@ -1,13 +1,13 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { PRoutes } from 'src/app/models/picsur-routes'; import { PRoutes } from 'src/app/models/picsur-routes';
import { SettingsHomeComponent } from './settings-home/settings-home.component'; import { SettingsGeneralRouteModule } from './settings-general/settings-home.module';
import { SettingsSidebarComponent } from './settings-sidebar/settings-sidebar.component'; import { SettingsSidebarComponent } from './settings-sidebar/settings-sidebar.component';
const routes: PRoutes = [ const SettingsRoutes: PRoutes = [
{ {
path: 'settings', path: '',
component: SettingsHomeComponent, loadChildren: () => SettingsGeneralRouteModule,
data: { data: {
sidebar: SettingsSidebarComponent, sidebar: SettingsSidebarComponent,
}, },
@ -15,7 +15,7 @@ const routes: PRoutes = [
]; ];
@NgModule({ @NgModule({
imports: [RouterModule.forChild(routes)], imports: [RouterModule.forChild(SettingsRoutes)],
exports: [RouterModule], exports: [RouterModule],
}) })
export class SettingsRoutingModule {} export class SettingsRoutingModule {}

View file

@ -67,7 +67,7 @@ export class LoginComponent implements OnInit {
} }
async onRegister() { async onRegister() {
this.router.navigate(['/register'], { this.router.navigate(['/user/register'], {
state: this.model.getRawData(), state: this.model.getRawData(),
}); });
} }

View file

@ -76,7 +76,7 @@ export class RegisterComponent implements OnInit {
} }
async onLogin() { async onLogin() {
this.router.navigate(['/login'], { this.router.navigate(['/user/login'], {
state: this.model.getRawData(), state: this.model.getRawData(),
}); });
} }

View file

@ -7,7 +7,7 @@ import { ViewComponent } from './view.component';
const routes: PRoutes = [ const routes: PRoutes = [
{ {
path: 'view/:hash', path: ':hash',
component: ViewComponent, component: ViewComponent,
canActivate: [PermissionGuard], canActivate: [PermissionGuard],
data: { permissions: [Permission.ImageView] }, data: { permissions: [Permission.ImageView] },