1
0
Fork 0
VaultUI/src/PageSystem/PageRouter.ts

102 lines
2.6 KiB
TypeScript

import { Page } from "./Page";
import { PageState } from "../PageState";
import { getObjectKeys } from "../utils";
type pageList = {
[key: string]: Page;
};
const PageDoesNotExistError = new Error("Page does not exist.");
const PageHasNotBeenSetError = new Error("Page has not been set.");
export class PageRouter extends EventTarget {
constructor(
pages: pageList,
state: PageState,
pageContentElement: HTMLElement,
pageTitleElement: HTMLElement,
) {
super();
this.pages = pages;
this.state = state;
this.pageContentElement = pageContentElement;
this.pageTitleElement = pageTitleElement;
}
private pages: pageList;
private currentPageID: string;
private currentPage: Page;
public state: PageState;
public pageContentElement: HTMLElement;
public pageTitleElement: HTMLElement;
public async getPageIDs(): Promise<string[]> {
return getObjectKeys(this.pages);
}
public async getCurrentPage(): Promise<Page> {
return this.currentPage;
}
public async getCurrentPageID(): Promise<string> {
return this.currentPageID;
}
public async setPageContent(content: string | HTMLElement): Promise<void> {
if (typeof content === "string") {
this.pageContentElement.innerHTML = content;
} else {
this.pageContentElement.innerHTML = "";
this.pageContentElement.appendChild(content);
}
}
public async changePage(pageID: string): Promise<void> {
if (!(await this.getPageIDs()).includes(pageID)) throw PageDoesNotExistError;
// Do cleanup on current page.
if (this.currentPage) {
await this.currentPage.cleanup();
}
// Set the current page to the new page
this.currentPageID = pageID;
this.currentPage = this.pages[pageID];
await this.currentPage.setRouterAndState(this, this.state);
// Dispatch an event saying the page has been changed.
this.dispatchEvent(new CustomEvent("pageChanged"));
// Render the page.
await this.renderPage();
}
public async renderPage(): Promise<void> {
if (!this.currentPage) throw PageHasNotBeenSetError;
// Reset back to blank.
this.pageContentElement.innerHTML = "";
this.pageTitleElement.innerHTML = "";
const pageTitle = await this.currentPage.getPageTitle();
if (typeof pageTitle === "string") {
this.pageTitleElement.innerText = pageTitle;
} else {
this.pageTitleElement.appendChild(pageTitle);
}
await this.currentPage.render();
}
public async refresh(): Promise<void> {
await this.renderPage();
}
public async goBack(): Promise<void> {
if (!this.currentPage) throw PageHasNotBeenSetError;
await this.currentPage.goBack();
}
}