Enable query param routing (#29)
* enable params in url * rename view state
This commit is contained in:
		
							parent
							
								
									3d4d7049a2
								
							
						
					
					
						commit
						911dc64025
					
				@ -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>`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -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: {} };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user