ts: use pages modules in admin (kinda), change pseudo-links

pseudo-links are now just links, because i'm lazy and it's easier than
fixing an issue. They now take the form `/?invite=code` and
`/accounts/?user=userid`.

ts/modules.tabs.ts is now a wrapper for ts/modules/pages.ts.

Also, fixed no section appearing when visiting the settings tab.
This commit is contained in:
Harvey Tindall
2024-08-28 14:18:52 +01:00
parent d2e5209832
commit 02f4ba6e8e
10 changed files with 388 additions and 151 deletions
+62 -29
View File
@@ -1,44 +1,77 @@
import { PageManager, Page } from "../modules/pages.js";
export interface Tab {
page: Page;
tabEl: HTMLDivElement;
buttonEl: HTMLSpanElement;
preFunc?: () => void;
postFunc?: () => void;
}
export class Tabs implements Tabs {
private _current: string = "";
tabs: Array<Tab>;
private _baseOffset = -1;
tabs: Map<string, Tab>;
pages: PageManager;
constructor() {
this.tabs = [];
this.tabs = new Map<string, Tab>;
this.pages = new PageManager({
hideOthersOnPageShow: true,
defaultName: "invites",
defaultTitle: document.title,
});
}
addTab = (tabID: string, preFunc = () => void {}, postFunc = () => void {}) => {
let tab = {} as Tab;
tab.tabID = tabID;
tab.tabEl = document.getElementById("tab-" + tabID) as HTMLDivElement;
tab.buttonEl = document.getElementById("button-tab-" + tabID) as HTMLSpanElement;
addTab = (tabID: string, url: string, preFunc = () => void {}, postFunc = () => void {},) => {
let tab: Tab = {
page: null,
tabEl: document.getElementById("tab-" + tabID) as HTMLDivElement,
buttonEl: document.getElementById("button-tab-" + tabID) as HTMLSpanElement,
preFunc: preFunc,
postFunc: postFunc,
};
if (this._baseOffset == -1) {
this._baseOffset = tab.buttonEl.offsetLeft;
}
tab.page = {
name: tabID,
title: document.title, /*FIXME: Get actual names from translations*/
url: window.URLBase + "/" + url,
show: () => {
tab.buttonEl.classList.add("active", "~urge");
tab.tabEl.classList.remove("unfocused");
tab.buttonEl.parentElement.scrollTo(tab.buttonEl.offsetLeft-this._baseOffset, 0);
document.dispatchEvent(new CustomEvent("tab-change", { detail: tabID }));
return true;
},
hide: () => {
tab.buttonEl.classList.remove("active");
tab.buttonEl.classList.remove("~urge");
tab.tabEl.classList.add("unfocused");
return true;
},
shouldSkip: () => false,
};
this.pages.setPage(tab.page);
tab.buttonEl.onclick = () => { this.switch(tabID); };
tab.preFunc = preFunc;
tab.postFunc = postFunc;
this.tabs.push(tab);
this.tabs.set(tabID, tab);
}
get current(): string { return this._current; }
set current(tabID: string) { this.switch(tabID); }
switch = (tabID: string, noRun: boolean = false, keepURL: boolean = false) => {
this._current = tabID;
let baseOffset = -1;
for (let t of this.tabs) {
if (baseOffset == -1) baseOffset = t.buttonEl.offsetLeft;
if (t.tabID == tabID) {
t.buttonEl.classList.add("active", "~urge");
if (t.preFunc && !noRun) { t.preFunc(); }
t.tabEl.classList.remove("unfocused");
if (t.postFunc && !noRun) { t.postFunc(); }
document.dispatchEvent(new CustomEvent("tab-change", { detail: keepURL ? "" : tabID }));
// t.buttonEl.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' })
t.buttonEl.parentElement.scrollTo(t.buttonEl.offsetLeft-baseOffset, 0);
} else {
t.buttonEl.classList.remove("active");
t.buttonEl.classList.remove("~urge");
t.tabEl.classList.add("unfocused");
}
switch = (tabID: string, noRun: boolean = false) => {
let t = this.tabs.get(tabID);
if (t == undefined) {
[t] = this.tabs.values();
}
this._current = t.page.name;
if (t.preFunc && !noRun) { t.preFunc(); }
this.pages.load(tabID);
if (t.postFunc && !noRun) { t.postFunc(); }
}
}