Skip to content

Commit

Permalink
Fix angular not reusing tab component over multiple routes
Browse files Browse the repository at this point in the history
Use a custom route matcher to only use one single route for all routes using the PluginTabComponent
  • Loading branch information
buehlefs committed Aug 5, 2024
1 parent fc865c6 commit fd15d7e
Showing 1 changed file with 94 additions and 9 deletions.
103 changes: 94 additions & 9 deletions src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { RouterModule, Routes, UrlMatcher, UrlMatchResult, UrlSegment } from '@angular/router';
import { DataDetailComponent } from './components/data-detail/data-detail.component';
import { ExperimentDataComponent } from './components/experiment-data/experiment-data.component';
import { ExperimentTimelineComponent } from './components/experiment-timeline/experiment-timeline.component';
Expand All @@ -26,13 +26,98 @@ import { PluginTabComponent } from './components/plugin-tab/plugin-tab.component
import { SettingsPageComponent } from './components/settings-page/settings-page.component';
import { TimelineStepComponent } from './components/timeline-step/timeline-step.component';

const NUMBER_REGEX = /^[0-9]+$/;

const extraTabsMatcher: UrlMatcher = (segments: UrlSegment[], group, route): UrlMatchResult | null => {
const consumed: UrlSegment[] = [];
const params: { [props: string]: UrlSegment } = {};

let tabId: UrlSegment | null = null;
let pluginId: UrlSegment | null = null;

// match: /experiments/:experimentId
let index = 0;
if (segments[index]?.path === "experiments") {
consumed.push(segments[index]);
index += 1;
if ((segments[index]?.path ?? "").match(NUMBER_REGEX)) {
params.experimentId = segments[index];
consumed.push(segments[index]);
index += 1;
} else {
return null;
}
}

console.log(consumed, params)

// match: ./extra[/:path]/:templateTabId
if (segments[index]?.path !== "extra") {
return null;
}
consumed.push(segments[index]);
index += 1;
if (segments[index + 1]?.path.match(NUMBER_REGEX)) {
// push [/:path]
params.path = segments[index];
consumed.push(segments[index]);
index += 1;
// push /:templateTabId
tabId = segments[index];
consumed.push(segments[index]);
index += 1;
} else if (segments[index]?.path.match(NUMBER_REGEX)) {
// push /:templateTabId
tabId = segments[index];
consumed.push(segments[index]);
index += 1;
}

if (tabId == null) {
// sanity check
return null;
}
params.templateTabId = tabId;

console.log(consumed, params)

// found full match?
if (index === segments.length) {
return {
consumed: consumed,
posParams: params,
}
}

// match: ./plugin/:pluginId
if (segments[index]?.path !== "plugins") {
return null;
}
consumed.push(segments[index]);
index += 1;
if (segments[index]?.path.match(NUMBER_REGEX)) {
pluginId = segments[index];
consumed.push(segments[index]);
index += 1;
}

console.log(consumed, params)

// found full match?
if (index === segments.length && pluginId != null) {
params.pluginId = pluginId;
return {
consumed: consumed,
posParams: params,
}
}

return null;
}

const routes: Routes = [
{ path: '', component: ExperimentsPageComponent },
{ path: 'settings', component: SettingsPageComponent },
{ path: 'extra/:templateTabId', component: PluginTabComponent },
{ path: 'extra/:templateTabId/plugin/:pluginId', component: PluginTabComponent },
{ path: 'extra/:path/:templateTabId', component: PluginTabComponent },
{ path: 'extra/:path/:templateTabId/plugin/:pluginId', component: PluginTabComponent },
{ path: 'experiments', component: ExperimentsPageComponent },
{ path: 'experiments/:experimentId', redirectTo: "info" },
{ path: 'experiments/:experimentId/info', component: ExperimentComponent },
Expand All @@ -43,10 +128,10 @@ const routes: Routes = [
{ path: 'experiments/:experimentId/timeline', component: ExperimentTimelineComponent },
{ path: 'experiments/:experimentId/timeline/:step', component: TimelineStepComponent },
{ path: 'experiments/:experimentId/timeline/:step/:stepTabId', component: TimelineStepComponent },
{ path: 'experiments/:experimentId/extra/:templateTabId', component: PluginTabComponent },
{ path: 'experiments/:experimentId/extra/:templateTabId/plugin/:pluginId', component: PluginTabComponent },
{ path: 'experiments/:experimentId/extra/:path/:templateTabId', component: PluginTabComponent },
{ path: 'experiments/:experimentId/extra/:path/:templateTabId/plugin/:pluginId', component: PluginTabComponent },
{/* path: '[experiments/:experimentId/]extra/[:path/]:templateTabId/[plugins/:pluginId]' */
matcher: extraTabsMatcher,
component: PluginTabComponent,
},
];

@NgModule({
Expand Down

0 comments on commit fd15d7e

Please sign in to comment.