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:
parent
1a0a62975c
commit
2c4239d79a
|
@ -10,3 +10,4 @@ export const EVENT_NOTIFICATION_TOGGLE = "ak-notification-toggle";
|
|||
export const EVENT_SIDEBAR_TOGGLE = "ak-sidebar-toggle";
|
||||
export const EVENT_API_DRAWER_REFRESH = "ak-api-drawer-refresh";
|
||||
export const TITLE_SUFFIX = "authentik";
|
||||
export const ROUTE_SEPARATOR = ";";
|
||||
|
|
|
@ -3,7 +3,7 @@ import { ifDefined } from "lit-html/directives/if-defined";
|
|||
import PFTabs from "@patternfly/patternfly/components/Tabs/tabs.css";
|
||||
import PFGlobal from "@patternfly/patternfly/patternfly-base.css";
|
||||
import AKGlobal from "../authentik.css";
|
||||
import { CURRENT_CLASS } from "../constants";
|
||||
import { CURRENT_CLASS, ROUTE_SEPARATOR } from "../constants";
|
||||
import { t } from "@lingui/macro";
|
||||
|
||||
@customElement("ak-tabs")
|
||||
|
@ -50,10 +50,17 @@ export class Tabs extends LitElement {
|
|||
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 {
|
||||
const slot = page.attributes.getNamedItem("slot")?.value;
|
||||
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">
|
||||
${page.getAttribute("data-tab-title")}
|
||||
</span>
|
||||
|
@ -67,7 +74,15 @@ export class Tabs extends LitElement {
|
|||
if (pages.length < 1) {
|
||||
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" : ""}">
|
||||
<ul class="pf-c-tabs__list">
|
||||
|
|
|
@ -6,7 +6,20 @@ import AKGlobal from "../../authentik.css";
|
|||
|
||||
import "./Router404";
|
||||
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")
|
||||
export class RouterOutlet extends LitElement {
|
||||
|
@ -34,7 +47,7 @@ export class RouterOutlet extends LitElement {
|
|||
|
||||
constructor() {
|
||||
super();
|
||||
window.addEventListener("hashchange", () => this.navigate());
|
||||
window.addEventListener("hashchange", (ev: HashChangeEvent) => this.navigate(ev));
|
||||
}
|
||||
|
||||
firstUpdated(): void {
|
||||
|
@ -53,8 +66,13 @@ export class RouterOutlet extends LitElement {
|
|||
});
|
||||
}
|
||||
|
||||
navigate(): void {
|
||||
let activeUrl = window.location.hash.slice(1, Infinity);
|
||||
navigate(ev?: HashChangeEvent): void {
|
||||
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 === "") {
|
||||
activeUrl = this.defaultUrl || "/";
|
||||
window.location.hash = `#${activeUrl}`;
|
||||
|
|
|
@ -8,6 +8,7 @@ import { until } from "lit-html/directives/until";
|
|||
|
||||
import "./SidebarBrand";
|
||||
import "./SidebarUser";
|
||||
import { ROUTE_SEPARATOR } from "../../constants";
|
||||
|
||||
export class SidebarItem {
|
||||
name: string;
|
||||
|
@ -145,9 +146,9 @@ export class Sidebar extends LitElement {
|
|||
|
||||
constructor() {
|
||||
super();
|
||||
this.activePath = window.location.hash.slice(1, Infinity);
|
||||
this.activePath = window.location.hash.slice(1, Infinity).split(ROUTE_SEPARATOR)[0];
|
||||
window.addEventListener("hashchange", () => {
|
||||
this.activePath = window.location.hash.slice(1, Infinity);
|
||||
this.activePath = window.location.hash.slice(1, Infinity).split(ROUTE_SEPARATOR)[0];
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
|||
|
||||
enum target {
|
||||
policy, group, user
|
||||
};
|
||||
}
|
||||
|
||||
@customElement("ak-policy-binding-form")
|
||||
export class PolicyBindingForm extends Form<PolicyBinding> {
|
||||
|
@ -41,7 +41,7 @@ export class PolicyBindingForm extends Form<PolicyBinding> {
|
|||
@property()
|
||||
targetPk?: string;
|
||||
|
||||
@property()
|
||||
@property({type: Number})
|
||||
policyGroupUser?: target;
|
||||
|
||||
getSuccessMessage(): string {
|
||||
|
|
Reference in a new issue