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;
@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`
<li>
<a
class="block p-2 ${href === this.viewState._path
class="block p-2 ${href === this.viewState.pathname
? "text-primary"
: ""}"
href="${href}"
@ -161,7 +163,7 @@ export class App extends LiteElement {
</div>
`;
switch (this.viewState._route) {
switch (this.viewState.route) {
case "login":
return html`<log-in
class="w-full md:bg-gray-100 flex items-center justify-center"
@ -204,7 +206,7 @@ export class App extends LiteElement {
@navigate="${this.onNavigateTo}"
.authState="${this.authState}"
.viewState="${this.viewState}"
aid="${this.viewState.aid!}"
aid="${this.viewState.params.aid}"
tab="${this.viewState.tab || "running"}"
></btrix-archive>`);

View File

@ -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: {} };
}
}