final-hill / cathedral

Requirements Engineering
https://cathedral.final-hill.com/
GNU Affero General Public License v3.0
0 stars 0 forks source link

Refactor Routing be a feature of pages #67

Closed mlhaufe closed 9 months ago

mlhaufe commented 9 months ago

Currently routing requires a standalone table initialized in Application._initRouter():

this.#router = new Router([
    ['/', (await import('./pages/Home.mjs')).Home],
    ['/not-found', (await import('./pages/NotFound.mjs')).NotFound],
    ['/projects', (await import('./pages/projects/Projects.mjs')).Projects],
    ['/environments', (await import('./pages/environments/Environments.mjs')).Environments],
    ['/environments/new-entry', (await import('./pages/environments/NewEnvironment.mjs')).NewEnvironment],
    ['/environments/:slug', (await import('./pages/environments/Environment.mjs')).Environment],
    ['/environments/:slug/glossary', (await import('./pages/environments/Glossary.mjs')).Glossary],
    ['/goals', (await import('./pages/goals/Goals.mjs')).Goals],
    ['/goals/new-entry', (await import('./pages/goals/NewGoals.mjs')).NewGoals],
    ['/goals/:slug', (await import('./pages/goals/Goal.mjs')).Goal],
    ['/goals/:slug/rationale', (await import('./pages/goals/Rationale.mjs')).Rationale],
    ['/goals/:slug/functionality', (await import('./pages/goals/Functionality.mjs')).Functionality],
    ['/goals/:slug/stakeholders', (await import('./pages/goals/Stakeholders.mjs')).Stakeholders],
    ['/goals/:slug/use-cases', (await import('./pages/goals/UseCases.mjs')).UseCases],
    ['/goals/:slug/limitations', (await import('./pages/goals/Limitations.mjs')).Limitations],
]);
this.#router.addEventListener('route', this);

Navigating to a page is accomplished via self.navigation.navigate(pathname)

A problem is that if a route changes, there is no error or warning of usage sites needing to change (Stringly typed)

Additionally, the parameters of the routes currently have to be parsed by subtypes of Page such as in SlugPage:

class SlugPage extends Page {
    // /parent/:slug/foo
    #slug = new URL(location.href, document.location.origin).pathname.split('/')[2];

    constructor(properties: Properties<SlugPage>, children: (string | Element)[]) {
        super(properties, children);

        // ...
    }

    get slug() {
        return this.#slug;
    }
}

Routing should be integrated into the Page class and initiating a route should accomplished via a method call on the page object itself instead of via self.navigate. Additionally, route parameters should be automatically available.