Enable query param routing (#29)

* enable params in url

* rename view state
This commit is contained in:
sua yoo 2021-11-25 12:00:24 -08:00 committed by GitHub
parent 3d4d7049a2
commit 911dc64025
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 30 deletions

View File

@ -33,7 +33,7 @@ export class App extends LiteElement {
authState: AuthState | null = null; authState: AuthState | null = null;
@state() @state()
viewState: ViewState & { viewState!: ViewState & {
aid?: string; aid?: string;
// TODO common tab type // TODO common tab type
tab?: "running" | "finished" | "configs"; tab?: "running" | "finished" | "configs";
@ -48,35 +48,37 @@ export class App extends LiteElement {
} }
this.router = new APIRouter(ROUTES); this.router = new APIRouter(ROUTES);
this.syncViewState();
this.viewState = this.router.match(window.location.pathname);
} }
firstUpdated() { private syncViewState() {
this.viewState = this.router.match(
`${window.location.pathname}${window.location.search}`
);
}
connectedCallback() {
super.connectedCallback();
window.addEventListener("popstate", (event) => { window.addEventListener("popstate", (event) => {
// if (event.state.view) { this.syncViewState();
// this.view = event.state.view;
// }
this.viewState = this.router.match(window.location.pathname);
}); });
this.viewState = this.router.match(window.location.pathname);
} }
navigate(newView: string) { navigate(newViewPath: string) {
if (newView.startsWith("http")) { if (newViewPath.startsWith("http")) {
newView = new URL(newView).pathname; 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 // Redirect to logged in home page
this.viewState = this.router.match(ROUTES.myAccount); this.viewState = this.router.match(ROUTES.myAccount);
} else { } 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.pathname);
window.history.pushState(this.viewState, "", this.viewState._path);
} }
navLink(event: Event) { navLink(event: Event) {
@ -140,7 +142,7 @@ export class App extends LiteElement {
const navLink = ({ href, label }: { href: string; label: string }) => html` const navLink = ({ href, label }: { href: string; label: string }) => html`
<li> <li>
<a <a
class="block p-2 ${href === this.viewState._path class="block p-2 ${href === this.viewState.pathname
? "text-primary" ? "text-primary"
: ""}" : ""}"
href="${href}" href="${href}"
@ -161,7 +163,7 @@ export class App extends LiteElement {
</div> </div>
`; `;
switch (this.viewState._route) { switch (this.viewState.route) {
case "login": case "login":
return html`<log-in return html`<log-in
class="w-full md:bg-gray-100 flex items-center justify-center" class="w-full md:bg-gray-100 flex items-center justify-center"
@ -204,7 +206,7 @@ export class App extends LiteElement {
@navigate="${this.onNavigateTo}" @navigate="${this.onNavigateTo}"
.authState="${this.authState}" .authState="${this.authState}"
.viewState="${this.viewState}" .viewState="${this.viewState}"
aid="${this.viewState.aid!}" aid="${this.viewState.params.aid}"
tab="${this.viewState.tab || "running"}" tab="${this.viewState.tab || "running"}"
></btrix-archive>`); ></btrix-archive>`);

View File

@ -4,8 +4,14 @@ type Routes = { [key: string]: Path };
type Paths = { [key: string]: string }; type Paths = { [key: string]: string };
export type ViewState = { export type ViewState = {
_route: string | null; // route name, e.g. "home"
_path: string; 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 = { export type NavigateEvent = {
detail: string; detail: string;
@ -24,18 +30,13 @@ export default class APIRouter {
match(path: string): ViewState { match(path: string): ViewState {
for (const [name, route] of Object.entries(this.routes)) { for (const [name, route] of Object.entries(this.routes)) {
const parts = path.split("?", 2); const res = route.test(path);
const matchUrl = parts[0];
const res = route.test(matchUrl);
if (res) { if (res) {
res._route = name; return { route: name, pathname: path, params: res };
res._path = path;
//res._query = new URLSearchParams(parts.length === 2 ? parts[1] : "");
return res as ViewState;
} }
} }
return { _route: null, _path: path }; return { route: null, pathname: path, params: {} };
} }
} }