1
0
Fork 0
VaultUI/src/pagerouter/PageRouter.ts
2022-01-06 23:02:34 +00:00

100 lines
2.8 KiB
TypeScript

import { PageListType } from "./PageListType";
import { PageType } from "./PageType";
const PageDoesNotExistError = new Error("Page does not exist.");
const PageHasNotBeenSetError = new Error("Page has not been set.");
export type Options = {
pageList: PageListType;
state: unknown;
pageContentElement: HTMLElement;
pageTitleElement: HTMLElement;
resetElementContent?: boolean;
onPageChange: () => void;
};
export class PageRouter {
constructor(options: Options) {
this.pageList = options.pageList;
this.state = options.state;
this.pageContentElement = options.pageContentElement;
this.pageTitleElement = options.pageTitleElement;
this.resetElementContent = (options.resetElementContent || true) == true;
this.onPageChange = options.onPageChange;
}
public onPageChange: () => void;
private pageList: PageListType;
private currentPageID: string;
private currentPage: PageType;
private resetElementContent: boolean;
public state: unknown;
public pageContentElement: HTMLElement;
public pageTitleElement: HTMLElement;
public async getPageIDs(): Promise<string[]> {
return await this.pageList.getPageIDs();
}
public async getCurrentPage(): Promise<PageType> {
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 = await this.pageList.getPage(pageID);
// Dispatch an event saying the page has been changed.
this.onPageChange();
await this.currentPage.setRouterAndState(this, this.state);
// Render the page.
await this.renderPage();
}
public async renderPage(): Promise<void> {
if (!this.currentPage) throw PageHasNotBeenSetError;
if (this.resetElementContent) {
// Reset back to blank.
this.pageContentElement.innerHTML = "";
this.pageTitleElement.innerHTML = "";
}
await Promise.all([this.currentPage.renderPageTitle(), 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();
}
}