From 911dc64025932ed01a64c311faef7f9e63fc0803 Mon Sep 17 00:00:00 2001 From: sua yoo Date: Thu, 25 Nov 2021 12:00:24 -0800 Subject: [PATCH] Enable query param routing (#29) * enable params in url * rename view state --- frontend/src/index.ts | 42 +++++++++++++++++---------------- frontend/src/utils/APIRouter.ts | 21 +++++++++-------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/frontend/src/index.ts b/frontend/src/index.ts index 9d939806..0866df0b 100644 --- a/frontend/src/index.ts +++ b/frontend/src/index.ts @@ -33,7 +33,7 @@ export class App extends LiteElement { authState: AuthState | null = null; @state() - viewState: ViewState & { + viewState!: ViewState & { aid?: string; // TODO common tab type tab?: "running" | "finished" | "configs"; @@ -48,35 +48,37 @@ export class App extends LiteElement { } this.router = new APIRouter(ROUTES); - - this.viewState = this.router.match(window.location.pathname); + this.syncViewState(); } - firstUpdated() { + private syncViewState() { + this.viewState = this.router.match( + `${window.location.pathname}${window.location.search}` + ); + } + + connectedCallback() { + super.connectedCallback(); + window.addEventListener("popstate", (event) => { - // if (event.state.view) { - // this.view = event.state.view; - // } - this.viewState = this.router.match(window.location.pathname); + this.syncViewState(); }); - - this.viewState = this.router.match(window.location.pathname); } - navigate(newView: string) { - if (newView.startsWith("http")) { - newView = new URL(newView).pathname; + navigate(newViewPath: string) { + if (newViewPath.startsWith("http")) { + const url = new URL(newViewPath); + newViewPath = `${url.pathname}${url.search}`; } - if (newView === "/log-in" && this.authState) { + if (newViewPath === "/log-in" && this.authState) { // Redirect to logged in home page this.viewState = this.router.match(ROUTES.myAccount); } else { - this.viewState = this.router.match(newView); + this.viewState = this.router.match(newViewPath); } - //console.log(this.view._route, window.location.href); - window.history.pushState(this.viewState, "", this.viewState._path); + window.history.pushState(this.viewState, "", this.viewState.pathname); } navLink(event: Event) { @@ -140,7 +142,7 @@ export class App extends LiteElement { const navLink = ({ href, label }: { href: string; label: string }) => html`
  • `; - switch (this.viewState._route) { + switch (this.viewState.route) { case "login": return html``); diff --git a/frontend/src/utils/APIRouter.ts b/frontend/src/utils/APIRouter.ts index f87300bc..4b15b7d4 100644 --- a/frontend/src/utils/APIRouter.ts +++ b/frontend/src/utils/APIRouter.ts @@ -4,8 +4,14 @@ type Routes = { [key: string]: Path }; type Paths = { [key: string]: string }; export type ViewState = { - _route: string | null; - _path: string; + // route name, e.g. "home" + route: string | null; + // path name, e.g. "/dashboard" + pathname: string; + // params from URL (:) or query (?) + // e.g. "/users/:id" + // e.g. "/redirect?url" + params: { [key: string]: string }; }; export type NavigateEvent = { detail: string; @@ -24,18 +30,13 @@ export default class APIRouter { match(path: string): ViewState { for (const [name, route] of Object.entries(this.routes)) { - const parts = path.split("?", 2); - const matchUrl = parts[0]; + const res = route.test(path); - const res = route.test(matchUrl); if (res) { - res._route = name; - res._path = path; - //res._query = new URLSearchParams(parts.length === 2 ? parts[1] : ""); - return res as ViewState; + return { route: name, pathname: path, params: res }; } } - return { _route: null, _path: path }; + return { route: null, pathname: path, params: {} }; } }