web: allow for non-path elements in hash, store current tab page in hash

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-04-04 23:19:08 +02:00
parent 1a0a62975c
commit 2c4239d79a
5 changed files with 46 additions and 11 deletions

View file

@ -10,3 +10,4 @@ export const EVENT_NOTIFICATION_TOGGLE = "ak-notification-toggle";
export const EVENT_SIDEBAR_TOGGLE = "ak-sidebar-toggle"; export const EVENT_SIDEBAR_TOGGLE = "ak-sidebar-toggle";
export const EVENT_API_DRAWER_REFRESH = "ak-api-drawer-refresh"; export const EVENT_API_DRAWER_REFRESH = "ak-api-drawer-refresh";
export const TITLE_SUFFIX = "authentik"; export const TITLE_SUFFIX = "authentik";
export const ROUTE_SEPARATOR = ";";

View file

@ -3,7 +3,7 @@ import { ifDefined } from "lit-html/directives/if-defined";
import PFTabs from "@patternfly/patternfly/components/Tabs/tabs.css"; import PFTabs from "@patternfly/patternfly/components/Tabs/tabs.css";
import PFGlobal from "@patternfly/patternfly/patternfly-base.css"; import PFGlobal from "@patternfly/patternfly/patternfly-base.css";
import AKGlobal from "../authentik.css"; import AKGlobal from "../authentik.css";
import { CURRENT_CLASS } from "../constants"; import { CURRENT_CLASS, ROUTE_SEPARATOR } from "../constants";
import { t } from "@lingui/macro"; import { t } from "@lingui/macro";
@customElement("ak-tabs") @customElement("ak-tabs")
@ -50,10 +50,17 @@ export class Tabs extends LitElement {
super.disconnectedCallback(); super.disconnectedCallback();
} }
onClick(slot?: string): void {
this.currentPage = slot;
const currentUrl = window.location.hash.slice(1, Infinity).split(ROUTE_SEPARATOR)[0];
const newUrl = `#${currentUrl};${slot}`;
window.location.hash = newUrl;
}
renderTab(page: Element): TemplateResult { renderTab(page: Element): TemplateResult {
const slot = page.attributes.getNamedItem("slot")?.value; const slot = page.attributes.getNamedItem("slot")?.value;
return html` <li class="pf-c-tabs__item ${slot === this.currentPage ? CURRENT_CLASS : ""}"> return html` <li class="pf-c-tabs__item ${slot === this.currentPage ? CURRENT_CLASS : ""}">
<button class="pf-c-tabs__link" @click=${() => { this.currentPage = slot; }}> <button class="pf-c-tabs__link" @click=${() => this.onClick(slot)}>
<span class="pf-c-tabs__item-text"> <span class="pf-c-tabs__item-text">
${page.getAttribute("data-tab-title")} ${page.getAttribute("data-tab-title")}
</span> </span>
@ -67,7 +74,15 @@ export class Tabs extends LitElement {
if (pages.length < 1) { if (pages.length < 1) {
return html`<h1>${t`no tabs defined`}</h1>`; return html`<h1>${t`no tabs defined`}</h1>`;
} }
this.currentPage = pages[0].attributes.getNamedItem("slot")?.value; let wantedPage = pages[0].attributes.getNamedItem("slot")?.value;
if (window.location.hash.includes(ROUTE_SEPARATOR)) {
const urlParts = window.location.hash.slice(1, Infinity).split(ROUTE_SEPARATOR);
if (this.querySelector(`[slot='${urlParts[1]}']`) !== null) {
// To update the URL to match with the current slot
wantedPage = urlParts[1];
}
}
this.onClick(wantedPage);
} }
return html`<div class="pf-c-tabs ${this.vertical ? "pf-m-vertical pf-m-box" : ""}"> return html`<div class="pf-c-tabs ${this.vertical ? "pf-m-vertical pf-m-box" : ""}">
<ul class="pf-c-tabs__list"> <ul class="pf-c-tabs__list">

View file

@ -6,7 +6,20 @@ import AKGlobal from "../../authentik.css";
import "./Router404"; import "./Router404";
import { Page } from "../Page"; import { Page } from "../Page";
import { TITLE_SUFFIX } from "../../constants"; import { ROUTE_SEPARATOR, TITLE_SUFFIX } from "../../constants";
// Poliyfill for hashchange.newURL,
// https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onhashchange
window.addEventListener("load", () => {
if (!window.HashChangeEvent) (function () {
let lastURL = document.URL;
window.addEventListener("hashchange", function (event) {
Object.defineProperty(event, "oldURL", { enumerable: true, configurable: true, value: lastURL });
Object.defineProperty(event, "newURL", { enumerable: true, configurable: true, value: document.URL });
lastURL = document.URL;
});
}());
});
@customElement("ak-router-outlet") @customElement("ak-router-outlet")
export class RouterOutlet extends LitElement { export class RouterOutlet extends LitElement {
@ -34,7 +47,7 @@ export class RouterOutlet extends LitElement {
constructor() { constructor() {
super(); super();
window.addEventListener("hashchange", () => this.navigate()); window.addEventListener("hashchange", (ev: HashChangeEvent) => this.navigate(ev));
} }
firstUpdated(): void { firstUpdated(): void {
@ -53,8 +66,13 @@ export class RouterOutlet extends LitElement {
}); });
} }
navigate(): void { navigate(ev?: HashChangeEvent): void {
let activeUrl = window.location.hash.slice(1, Infinity); let activeUrl = window.location.hash.slice(1, Infinity).split(ROUTE_SEPARATOR)[0];
if (ev) {
// Check if we've actually changed paths
const oldPath = new URL(ev.oldURL).hash.slice(1, Infinity).split(ROUTE_SEPARATOR)[0];
if (oldPath === activeUrl) return;
}
if (activeUrl === "") { if (activeUrl === "") {
activeUrl = this.defaultUrl || "/"; activeUrl = this.defaultUrl || "/";
window.location.hash = `#${activeUrl}`; window.location.hash = `#${activeUrl}`;

View file

@ -8,6 +8,7 @@ import { until } from "lit-html/directives/until";
import "./SidebarBrand"; import "./SidebarBrand";
import "./SidebarUser"; import "./SidebarUser";
import { ROUTE_SEPARATOR } from "../../constants";
export class SidebarItem { export class SidebarItem {
name: string; name: string;
@ -145,9 +146,9 @@ export class Sidebar extends LitElement {
constructor() { constructor() {
super(); super();
this.activePath = window.location.hash.slice(1, Infinity); this.activePath = window.location.hash.slice(1, Infinity).split(ROUTE_SEPARATOR)[0];
window.addEventListener("hashchange", () => { window.addEventListener("hashchange", () => {
this.activePath = window.location.hash.slice(1, Infinity); this.activePath = window.location.hash.slice(1, Infinity).split(ROUTE_SEPARATOR)[0];
}); });
} }

View file

@ -13,7 +13,7 @@ import PFContent from "@patternfly/patternfly/components/Content/content.css";
enum target { enum target {
policy, group, user policy, group, user
}; }
@customElement("ak-policy-binding-form") @customElement("ak-policy-binding-form")
export class PolicyBindingForm extends Form<PolicyBinding> { export class PolicyBindingForm extends Form<PolicyBinding> {
@ -41,7 +41,7 @@ export class PolicyBindingForm extends Form<PolicyBinding> {
@property() @property()
targetPk?: string; targetPk?: string;
@property() @property({type: Number})
policyGroupUser?: target; policyGroupUser?: target;
getSuccessMessage(): string { getSuccessMessage(): string {