feat(sharedTaskList): prevent invalid tags and projects from being triggered

This commit is contained in:
Johannes Millan 2020-03-26 19:45:29 +01:00
parent b9522ddc1e
commit 42ea124bbc
3 changed files with 122 additions and 19 deletions

View file

@ -2,21 +2,24 @@ import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from '@angular/router';
import {WorkContextService} from './features/work-context/work-context.service';
import {Observable, of} from 'rxjs';
import {switchMap, take} from 'rxjs/operators';
import {concatMap, map, switchMap, take, tap} from 'rxjs/operators';
import {WorkContextType} from './features/work-context/work-context.model';
import {TagService} from './features/tag/tag.service';
import {ProjectService} from './features/project/project.service';
import {DataInitService} from './core/data-init/data-init.service';
@Injectable({
providedIn: 'root'
})
export class ActiveWorkContextGuard implements CanActivate {
constructor(
private workContextService: WorkContextService,
private router: Router,
private _workContextService: WorkContextService,
private _router: Router,
) {
}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
return this.workContextService.activeWorkContextTypeAndId$.pipe(
return this._workContextService.activeWorkContextTypeAndId$.pipe(
take(1),
switchMap(({activeType, activeId}) => {
const {subPageType, param} = next.params;
@ -24,8 +27,50 @@ export class ActiveWorkContextGuard implements CanActivate {
? 'tag'
: 'project';
const url = `/${base}/${activeId}/${subPageType}${param ? '/' + param : ''}`;
return of(this.router.parseUrl(url));
return of(this._router.parseUrl(url));
})
);
}
}
@Injectable({
providedIn: 'root'
})
export class ValidTagIdGuard implements CanActivate {
constructor(
private _router: Router,
private _tagService: TagService,
private _dataInitService: DataInitService,
) {
}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
const {id} = next.params;
return this._dataInitService.isAllDataLoadedInitially$.pipe(
concatMap(() => this._tagService.getTagById$(id)),
take(1),
map(tag => !!tag),
);
}
}
@Injectable({
providedIn: 'root'
})
export class ValidProjectIdGuard implements CanActivate {
constructor(
private _router: Router,
private _projectService: ProjectService,
private _dataInitService: DataInitService,
) {
}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
const {id} = next.params;
return this._dataInitService.isAllDataLoadedInitially$.pipe(
concatMap(() => this._projectService.getByIdOnce$(id)),
map(project => !!project),
);
}
}

View file

@ -9,7 +9,7 @@ import {ProcrastinationComponent} from './features/procrastination/procrastinati
import {SchedulePageComponent} from './pages/schedule-page/schedule-page.component';
import {ProjectSettingsPageComponent} from './pages/project-settings-page/project-settings-page.component';
import {TagTaskPageComponent} from './pages/tag-task-page/tag-task-page.component';
import {ActiveWorkContextGuard} from './app.guard';
import {ActiveWorkContextGuard, ValidProjectIdGuard, ValidTagIdGuard} from './app.guard';
import {TagSettingsPageComponent} from './pages/tag-settings-page/tag-settings-page.component';
export const APP_ROUTES: Routes = [
@ -17,19 +17,74 @@ export const APP_ROUTES: Routes = [
{path: 'schedule', component: SchedulePageComponent, data: {page: 'schedule'}},
{path: 'procrastination', component: ProcrastinationComponent, data: {page: 'procrastination'}},
{path: 'tag/:id/tasks', component: TagTaskPageComponent, data: {page: 'tag-tasks'}},
{path: 'tag/:id/settings', component: TagSettingsPageComponent, data: {page: 'tag-settings'}},
{path: 'tag/:id/worklog', component: WorklogComponent, data: {page: 'worklog'}},
// {path: 'tag/:id/metrics', component: MetricPageComponent, data: {page: 'metrics'}},
{path: 'tag/:id/daily-summary', component: DailySummaryComponent, data: {page: 'daily-summary'}},
{path: 'tag/:id/daily-summary/:dayStr', component: DailySummaryComponent, data: {page: 'daily-summary'}},
{
path: 'tag/:id/tasks',
component: TagTaskPageComponent,
data: {page: 'tag-tasks'},
canActivate: [ValidTagIdGuard]
},
{
path: 'tag/:id/settings',
component: TagSettingsPageComponent,
data: {page: 'tag-settings'},
canActivate: [ValidTagIdGuard]
},
{
path: 'tag/:id/worklog',
component: WorklogComponent,
data: {page: 'worklog'},
canActivate: [ValidTagIdGuard]
},
// {path: 'tag/:id/metrics', component: MetricPageComponent, data: {page: 'metrics'}, canActivate: [ValidContextIdGuard]},
{
path: 'tag/:id/daily-summary',
component: DailySummaryComponent,
data: {page: 'daily-summary'},
canActivate: [ValidTagIdGuard]
},
{
path: 'tag/:id/daily-summary/:dayStr',
component: DailySummaryComponent,
data: {page: 'daily-summary'},
canActivate: [ValidTagIdGuard]
},
{path: 'project/:id/tasks', component: ProjectTaskPageComponent, data: {page: 'project-tasks'}},
{path: 'project/:id/settings', component: ProjectSettingsPageComponent, data: {page: 'project-settings'}},
{path: 'project/:id/worklog', component: WorklogComponent, data: {page: 'worklog'}},
{path: 'project/:id/metrics', component: MetricPageComponent, data: {page: 'metrics'}},
{path: 'project/:id/daily-summary', component: DailySummaryComponent, data: {page: 'daily-summary'}},
{path: 'project/:id/daily-summary/:dayStr', component: DailySummaryComponent, data: {page: 'daily-summary'}},
{
path: 'project/:id/tasks',
component: ProjectTaskPageComponent,
data: {page: 'project-tasks'},
canActivate: [ValidProjectIdGuard]
},
{
path: 'project/:id/settings',
component: ProjectSettingsPageComponent,
data: {page: 'project-settings'},
canActivate: [ValidProjectIdGuard]
},
{
path: 'project/:id/worklog',
component: WorklogComponent,
data: {page: 'worklog'},
canActivate: [ValidProjectIdGuard]
},
{
path: 'project/:id/metrics',
component: MetricPageComponent,
data: {page: 'metrics'},
canActivate: [ValidProjectIdGuard]
},
{
path: 'project/:id/daily-summary',
component: DailySummaryComponent,
data: {page: 'daily-summary'},
canActivate: [ValidProjectIdGuard]
},
{
path: 'project/:id/daily-summary/:dayStr',
component: DailySummaryComponent,
data: {page: 'daily-summary'},
canActivate: [ValidProjectIdGuard]
},
{path: 'project-overview', component: ProjectOverviewPageComponent, data: {page: 'project-overview'}},

View file

@ -457,8 +457,11 @@ export class WorkContextService {
}
// NOTE: NEVER call this from some place other than the route change stuff
private _setActiveContext(activeId: string, activeType: WorkContextType) {
private async _setActiveContext(activeId: string, activeType: WorkContextType) {
this._store$.dispatch(setActiveWorkContext({activeId, activeType}));
}
private async _isValidContextId(id: string): Promise<boolean> {
}
}