const elementName = 'main-menu'
import {userRoles, userPermissions, getUser, isSignedIn} from "../system/user.mjs";
import {goto, state, isMobile, menu, ready} from "../system/core.mjs"
import {on} from "../system/events.mjs"
const template = document.createElement('template');
template.innerHTML = `
`;
class Page extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(template.content.cloneNode(true));
this.toggleDisplay = this.toggleDisplay.bind(this)
this.updateSelected = this.updateSelected.bind(this)
this.refreshData = this.refreshData.bind(this)
this.refreshData();
this.shadowRoot.querySelector("#container").addEventListener("click", event => {
let item = event.target.closest(".item")
if(item) {
let path = item.getAttribute("data-path")
if(path){
if(path.startsWith("/_"))
window.open(path)
else
goto(path, {forceRefresh: path == state().path})
}
} else {
let menu = event.target.closest(".menu")
if(menu){
this.toggleMenu(menu)
}
}
})
on("changed-page", "mainmenu", this.updateSelected)
on("toggle-menu", "mainmenu", this.toggleDisplay)
}
toggleDisplay(){
let doShow = document.getElementById("grid-container").classList.contains("collapsed")
document.getElementById("grid-container").classList.toggle("collapsed", !doShow)
if(doShow && isMobile()){
document.getElementById("grid-container").classList.remove("rightvisible");
}
}
toggleMenu(menu, force){
let doShow = force !== undefined ? force : !menu.classList.contains("open");
let display = doShow ? "block" : "none";
menu.classList.toggle("open", doShow)
let mi = menu.nextSibling
while(mi){
if(mi.classList.contains("menu")){
if(mi.dataset.parentmenuid == menu.dataset.menuid){
mi.style.display = display
if(!doShow){
this.toggleMenu(mi, false)
}
}
} else if(mi.dataset.menuid == menu.dataset.menuid){
mi.style.display = display
}
mi = mi.nextSibling
}
}
async refreshData(){
await ready;
if(isSignedIn()){
this.user = await getUser()
this.userRoles = await userRoles()
this.userPermissions = await userPermissions()
} else {
this.user = null;
this.userRoles = []
this.userPermissions = []
}
this.refreshMenu();
}
updateSelected(){
this.shadowRoot.querySelectorAll(".selected").forEach(e => e.classList.remove("selected"))
this.shadowRoot.querySelectorAll(".menu").forEach(e => e.classList.remove("open"))
this.shadowRoot.querySelectorAll(".item").forEach(e => e.style.display = "none")
this.shadowRoot.querySelectorAll(`.item[data-path="${state().path}"]`).forEach(e => {
e.classList.add("selected")
let parentMenu = this.shadowRoot.querySelector(`.menu[data-menuid="${e.dataset.menuid}"]`);
let menus = []
while(parentMenu){
menus.push(parentMenu)
parentMenu = this.shadowRoot.querySelector(`.menu[data-menuid="${parentMenu.dataset.parentmenuid}"]`);
}
menus.reverse().forEach(m => this.toggleMenu(m, true))
})
}
addMenu(parent, items, parentMenuId){
let anyAdded = false;
let signedIn = isSignedIn();
for(let item of items){
if(!item.items){
if(item.role && !this.userRoles.includes(item.role)) continue;
if(item.permission && !this.userPermissions.includes(item.permission)) continue;
if(item.public !== true && !signedIn) continue;
if(item.hideWhenSignedIn && signedIn) continue;
}
anyAdded = true;
let itemDiv = document.createElement("div")
let titleElement = document.createElement("span")
itemDiv.appendChild(titleElement)
if(!item.items){
itemDiv.className = "item"
titleElement.attributes.class = "itemtitle"
titleElement.innerText = " - " + item.title
itemDiv.setAttribute("data-path", item.target||item.path)
itemDiv.setAttribute("data-menuid", parentMenuId)
} else {
let level = parentMenuId ? parseInt(this.shadowRoot.querySelector(`.menu[data-menuid="${parentMenuId}"]`).dataset.level)+1
: 0;
itemDiv.dataset.level = level;
itemDiv.style.display = parentMenuId ? "none" : "block";
itemDiv.className = "menu"
titleElement.innerHTML = `${level > 0 ? `${''.repeat(level)} `:''}${item.title}`
let arrow = document.createElement("span")
arrow.className = "menuarrow"
arrow.innerText = " ▾"
itemDiv.appendChild(arrow)
itemDiv.setAttribute("data-menuid", this.nextMenuId++)
itemDiv.setAttribute("data-parentmenuid", parentMenuId)
}
parent.appendChild(itemDiv)
if(item.items){
if(!this.addMenu(parent, item.items, itemDiv.getAttribute("data-menuid"))){
itemDiv.remove(); //No child items added
}
}
}
return anyAdded;
}
refreshMenu(){
let container = this.shadowRoot.querySelector("#container")
container.innerHTML = ""
this.nextMenuId = 1;
this.addMenu(container, menu())
this.updateSelected();
}
connectedCallback() {
on("logged-in", elementName, this.refreshData)
on("logged-out", elementName, this.refreshData)
}
disconnectedCallback() {
off("logged-in", elementName)
off("logged-out", elementName)
}
}
window.customElements.define(elementName, Page);
export {Page as Element, elementName as name}