feat(sdk,client): add menu to help navigation between apps
All checks were successful
arcad/edge/pipeline/head This commit looks good
All checks were successful
arcad/edge/pipeline/head This commit looks good
This commit is contained in:
144
pkg/sdk/client/src/menu-manager.ts
Normal file
144
pkg/sdk/client/src/menu-manager.ts
Normal file
@ -0,0 +1,144 @@
|
||||
import { Menu } from "./components/menu"
|
||||
|
||||
export interface MenuItem {
|
||||
label: string
|
||||
iconUrl: string
|
||||
linkUrl: string
|
||||
order: number
|
||||
}
|
||||
|
||||
const EdgeBodyAutoPaddingAttrName = 'edge-auto-padding'
|
||||
|
||||
export class MenuManager {
|
||||
|
||||
_items: { [name:string]: MenuItem }
|
||||
_menu: Menu
|
||||
_appIconUrl: string
|
||||
_appTitle: string
|
||||
_hidden: boolean
|
||||
_previousBodyAutoPadding: string
|
||||
|
||||
constructor() {
|
||||
this._items = {};
|
||||
|
||||
this._handleLoad = this._handleLoad.bind(this);
|
||||
|
||||
window.addEventListener('load', this._handleLoad);
|
||||
}
|
||||
|
||||
setItem(name: string, label:string, options?: { iconUrl?: string, linkUrl?: string, order?: number }) {
|
||||
this._items[name] = {
|
||||
label: label,
|
||||
iconUrl: options?.iconUrl ? options?.iconUrl : '',
|
||||
linkUrl: options?.linkUrl ? options?.linkUrl : '#',
|
||||
order: options?.order ? options?.order : 0,
|
||||
}
|
||||
this._render();
|
||||
return this;
|
||||
}
|
||||
|
||||
removeItem(name: string) {
|
||||
delete this._items[name];
|
||||
this._render();
|
||||
return this;
|
||||
}
|
||||
|
||||
setAppIconUrl(url: string) {
|
||||
this._appIconUrl = url;
|
||||
this._render();
|
||||
return this;
|
||||
}
|
||||
|
||||
setAppTitle(title: string) {
|
||||
this._appTitle = title;
|
||||
this._render();
|
||||
return this;
|
||||
}
|
||||
|
||||
show() {
|
||||
if (!this._hidden) return;
|
||||
|
||||
this._hidden = false;
|
||||
if (this._previousBodyAutoPadding) {
|
||||
document.body.setAttribute(EdgeBodyAutoPaddingAttrName, this._previousBodyAutoPadding);
|
||||
} else {
|
||||
document.body.removeAttribute(EdgeBodyAutoPaddingAttrName);
|
||||
}
|
||||
this._render();
|
||||
}
|
||||
|
||||
hide() {
|
||||
if (this._hidden) return;
|
||||
|
||||
this._hidden = true;
|
||||
this._previousBodyAutoPadding = document.body.getAttribute(EdgeBodyAutoPaddingAttrName);
|
||||
document.body.setAttribute(EdgeBodyAutoPaddingAttrName, "false");
|
||||
this._render();
|
||||
}
|
||||
|
||||
_handleLoad() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
_init() {
|
||||
this._initMenu();
|
||||
this._initGlobalStyle();
|
||||
}
|
||||
|
||||
_initMenu() {
|
||||
const menu = document.createElement('edge-menu');
|
||||
document.body.appendChild(menu);
|
||||
this._menu = menu;
|
||||
this._render();
|
||||
}
|
||||
|
||||
_initGlobalStyle() {
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
body:not([${EdgeBodyAutoPaddingAttrName}="false"]) {
|
||||
padding-top: 60px;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
_render() {
|
||||
if (!this._menu) return;
|
||||
|
||||
if (this._hidden) {
|
||||
this._menu.setAttribute("hidden", "true");
|
||||
} else {
|
||||
this._menu.removeAttribute("hidden");
|
||||
}
|
||||
|
||||
if (this._appIconUrl) {
|
||||
this._menu.setAttribute("app-icon-url", this._appIconUrl);
|
||||
} else {
|
||||
this._menu.removeAttribute("app-icon-url");
|
||||
}
|
||||
|
||||
if (this._appTitle) {
|
||||
this._menu.setAttribute("app-title", this._appTitle);
|
||||
} else {
|
||||
this._menu.removeAttribute("app-title");
|
||||
}
|
||||
|
||||
const children: Node[] = [];
|
||||
|
||||
const items: MenuItem[] = Object.keys(this._items)
|
||||
.map(key => ({ name: key, ...this._items[key] }))
|
||||
.sort((a, b) => a.order - b.order)
|
||||
;
|
||||
|
||||
for (let item: MenuItem, i = 0; (item = items[i]); i++) {
|
||||
const node = document.createElement('edge-menu-sub-item');
|
||||
node.label = item.label;
|
||||
node.iconUrl = item.iconUrl;
|
||||
node.linkUrl = item.linkUrl;
|
||||
children.push(node);
|
||||
}
|
||||
|
||||
this._menu.replaceChildren(...children);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user