diff --git a/Makefile b/Makefile
index f38af17e0..0f348b8cf 100644
--- a/Makefile
+++ b/Makefile
@@ -81,3 +81,12 @@ migrate:
run:
go run -v cmd/server/main.go
+
+web: web-lint-fix web-lint
+
+web-lint-fix:
+ cd web && npm run prettier
+
+web-lint:
+ cd web && npm run lint
+ cd web && npm run lit-analyse
diff --git a/web/src/elements/Tabs.ts b/web/src/elements/Tabs.ts
index 744932d09..10075ea67 100644
--- a/web/src/elements/Tabs.ts
+++ b/web/src/elements/Tabs.ts
@@ -9,6 +9,7 @@ import PFTabs from "@patternfly/patternfly/components/Tabs/tabs.css";
import PFGlobal from "@patternfly/patternfly/patternfly-base.css";
import { CURRENT_CLASS, ROUTE_SEPARATOR } from "../constants";
+import { getURLParams, updateURLParams } from "./router/RouteMatch";
@customElement("ak-tabs")
export class Tabs extends LitElement {
@@ -65,9 +66,9 @@ export class Tabs extends LitElement {
onClick(slot?: string): void {
this.currentPage = slot;
- const currentUrl = window.location.hash.slice(1, Infinity).split(ROUTE_SEPARATOR)[0];
- const newUrl = `#${currentUrl};${slot}`;
- history.replaceState(undefined, "", newUrl);
+ updateURLParams({
+ page: slot,
+ });
}
renderTab(page: Element): TemplateResult {
@@ -81,18 +82,20 @@ export class Tabs extends LitElement {
render(): TemplateResult {
const pages = Array.from(this.querySelectorAll("[slot^='page-']"));
+ if (window.location.hash.includes(ROUTE_SEPARATOR)) {
+ const params = getURLParams();
+ if ("page" in params) {
+ if (this.querySelector(`[slot='${params.page}']`) !== null) {
+ // To update the URL to match with the current slot
+ this.currentPage = params.page;
+ }
+ }
+ }
if (!this.currentPage) {
if (pages.length < 1) {
return html`
${t`no tabs defined`}
`;
}
- 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];
- }
- }
+ const wantedPage = pages[0].attributes.getNamedItem("slot")?.value;
this.onClick(wantedPage);
}
return html`
diff --git a/web/src/elements/router/RouteMatch.ts b/web/src/elements/router/RouteMatch.ts
index cda3235ab..b887d58e3 100644
--- a/web/src/elements/router/RouteMatch.ts
+++ b/web/src/elements/router/RouteMatch.ts
@@ -1,5 +1,6 @@
import { TemplateResult } from "lit";
+import { ROUTE_SEPARATOR } from "../../constants";
import { Route } from "./Route";
export class RouteMatch {
@@ -22,3 +23,44 @@ export class RouteMatch {
)}>`;
}
}
+
+export function getURLParam
(key: string, fallback: T): T {
+ const params = getURLParams();
+ if (key in params) {
+ return params[key] as T;
+ }
+ return fallback;
+}
+
+export function getURLParams(): { [key: string]: unknown } {
+ const params = {};
+ if (window.location.hash.includes(ROUTE_SEPARATOR)) {
+ const urlParts = window.location.hash.slice(1, Infinity).split(ROUTE_SEPARATOR, 2);
+ const rawParams = decodeURIComponent(urlParts[1]);
+ try {
+ return JSON.parse(rawParams);
+ } catch {
+ return params;
+ }
+ }
+ return params;
+}
+
+export function setURLParams(params: { [key: string]: unknown }, replace = true): void {
+ const paramsString = JSON.stringify(params);
+ const currentUrl = window.location.hash.slice(1, Infinity).split(ROUTE_SEPARATOR)[0];
+ const newUrl = `#${currentUrl};${encodeURIComponent(paramsString)}`;
+ if (replace) {
+ history.replaceState(undefined, "", newUrl);
+ } else {
+ history.pushState(undefined, "", newUrl);
+ }
+}
+
+export function updateURLParams(params: { [key: string]: unknown }, replace = true): void {
+ const currentParams = getURLParams();
+ for (const key in params) {
+ currentParams[key] = params[key] as string;
+ }
+ setURLParams(currentParams, replace);
+}
diff --git a/web/src/elements/table/Table.ts b/web/src/elements/table/Table.ts
index 3ab94c6fa..6f57e853e 100644
--- a/web/src/elements/table/Table.ts
+++ b/web/src/elements/table/Table.ts
@@ -19,6 +19,7 @@ import { groupBy } from "../../utils";
import "../EmptyState";
import "../chips/Chip";
import "../chips/ChipGroup";
+import { getURLParams, updateURLParams } from "../router/RouteMatch";
import "./TablePagination";
import "./TableSearch";
@@ -355,6 +356,9 @@ export abstract class Table extends LitElement {
composed: true,
}),
);
+ updateURLParams({
+ search: value,
+ });
}}
>
`;
@@ -393,6 +397,10 @@ export abstract class Table extends LitElement {
}
firstUpdated(): void {
+ const params = getURLParams();
+ if ("search" in params) {
+ this.search = params.search;
+ }
this.fetch();
}
diff --git a/web/src/pages/property-mappings/PropertyMappingListPage.ts b/web/src/pages/property-mappings/PropertyMappingListPage.ts
index 69a5dd026..2492b2a15 100644
--- a/web/src/pages/property-mappings/PropertyMappingListPage.ts
+++ b/web/src/pages/property-mappings/PropertyMappingListPage.ts
@@ -15,6 +15,7 @@ import "../../elements/buttons/SpinnerButton";
import "../../elements/forms/DeleteBulkForm";
import "../../elements/forms/ModalForm";
import "../../elements/forms/ProxyForm";
+import { getURLParam, updateURLParams } from "../../elements/router/RouteMatch";
import { TableColumn } from "../../elements/table/Table";
import { TablePage } from "../../elements/table/TablePage";
import { groupBy } from "../../utils";
@@ -45,7 +46,7 @@ export class PropertyMappingListPage extends TablePage {
order = "name";
@property({ type: Boolean })
- hideManaged = false;
+ hideManaged = getURLParam("hideManaged", true);
async apiEndpoint(page: number): Promise> {
return new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsAllList({
@@ -171,6 +172,9 @@ export class PropertyMappingListPage extends TablePage {
this.hideManaged = !this.hideManaged;
this.page = 1;
this.fetch();
+ updateURLParams({
+ hideManaged: this.hideManaged,
+ });
}}
/>