$(() => { var windowDisplayed = false; var data = null; const GRANT_TEXT = ["None", "Read Access", "Write Access", "Read Access (Strip meta)"]; const GRANT_ICON = ["", "bi-eye", "bi-pencil", "bi-eye-slash"]; const ACCESS_ICON = ["bi-question-lg", "bi-database", "bi-envelope-at", "bi-link-45deg", "bi-people"]; const TYPE_ICON = ["bi-question-lg", "bi-diagram-2", "bi-tags", "bi-braces-asterisk", "bi-images", "bi-gear"]; const TYPE_TEXT = ["Unknown", "Single photo", "Tags", "Meta", "Everything", "Admin access"]; class ShareData { dbId = 0; typeId = ""; typeData = ""; accessToId = 0; accessToData = ""; grant = 0; constructor(data) { this.dbId = data.id; this.typeId = [ "unknown", "ldapAccount", "email", "link", "every one" ].indexOf(data.type); this.typeData = data.typeData; this.accessToId = [ "unknown", "item", "tag", "meta", "everything", "admin"].indexOf(data.accessTo); this.accessToData = data.accessToData; this.grant = [ "none", "read", "write", "read without meta"].indexOf(data.grant); } objectify() { return { id: this.dbId, type: [ "unknown", "ldapAccount", "email", "link", "every one" ][this.typeId], typeData: this.typeData, accessTo: [ "unknown", "item", "tag", "meta", "everything", "admin"][this.accessToId], accessToData: this.accessToData, grant: [ "none", "read", "write", "read without meta"][this.grant] }; } compare(b) { if (this.typeId != b.typeId) return b.typeId - this.typeId; if (this.accessToId != b.accessToId) return b.accessToId - this.accessToId; if (this.grant != b.grant) return b.grant - this.grant; return 0; } } function getData() { return new Promise((ok) => { if (data) return ok(data); $.get("/api/accessAdmin/list", {}, okData => { data = (okData || []).map(x => new ShareData(x)).sort((a, b) => a.compare(b)); ok(data); }); }); } function updateData(data) { return new Promise(ok => { $.ajax({ url: `/api/accessAdmin/${data.dbId}`, type: "POST", data: data, success: allData => { ok(true); }, error: err => ok(false), }); }); } function revokeData(dbId) { return new Promise(ok => { $.ajax({ url: `/api/accessAdmin/${dbId}`, type: "DELETE", success: allData => { ok(true); }, error: err => ok(false), }); }); } async function buildTypeDepandentDiv(htmlElement, data) { htmlElement.textContent = ""; let input = document.createElement("input"); input.type = "text"; if (data.accessToId === 1) { input.value = data.accessToData; htmlElement.appendChild(input); let span = document.createElement("span"); span.textContent = " (" +((await MediaStorage.Instance.getMedia(data.accessToData))?.fileName || "File not found") + ")"; htmlElement.appendChild(span); input.addEventListener("change", async () => { span.textContent = " (" +((await MediaStorage.Instance.getMedia(input.value))?.fileName || "File not found") + ")"; }); } else if (data.accessToId === 2) { input.value = data.accessToData; htmlElement.appendChild(input); } else if (data.accessToId === 3) { input.value = data.accessToData; htmlElement.appendChild(input); } if (htmlElement.children.length) { input.addEventListener("change", async () => { data.accessToData = input.value; await updateData(data); }); } } async function buildShareItem(data) { const htmlId = `collapseShareItem${data.dbId}`; let container = document.createElement("li"); container.className = "accordion-item"; let header = document.createElement("h2"); header.className = "accordion-header"; let headerButton = document.createElement("button"); headerButton.className = `accordion-button bi ${ACCESS_ICON[data.typeId]}`; headerButton.type = "button"; headerButton.dataset.bsToggle = "collapse"; headerButton.dataset.bsTarget = `#${htmlId}`; headerButton.textContent = data.typeData; headerButton.ariaExpanded = false; headerButton.ariaControls = htmlId; let accordionBodyContainer = document.createElement("div"); accordionBodyContainer.className = "accordion-collapse collapse"; accordionBodyContainer.dataset.bsParent = "#pch-share-container"; accordionBodyContainer.id = htmlId; let accordionBody = document.createElement("div"); accordionBody.className = "accordion-body"; let typeDivRow = document.createElement("div"); typeDivRow.className = "row"; let typeDepandentDiv = document.createElement("div"); let grantDiv = document.createElement("div"); { let typeDiv = document.createElement("div"); typeDiv.className = "dropdown"; typeDiv.id = `pch-share-${data.dbId}-typeDropdown` let button = document.createElement("button"); button.className = "btn btn-secondary dropdown-toggle bi"; button.classList.add(TYPE_ICON[data.accessToId]); button.textContent = TYPE_TEXT[data.accessToId]; button.type = "button"; button.setAttribute("data-bs-toggle", "dropdown"); button.setAttribute("aria-expanded", false); button.id = `${typeDiv.id}-button`; let dropdownMenu = document.createElement("ul"); dropdownMenu.className = "dropdown-menu"; for (let i =1; i <= TYPE_TEXT.length; ++i) { let li = document.createElement("li"); let a = document.createElement("a"); a.className = "dropdown-item bi"; if (i === data.accessToId) a.classList.add("active"); a.href="#"; a.classList.add(TYPE_ICON[i]); a.textContent = TYPE_TEXT[i]; a.addEventListener("click", async () => { let dbData = await getData(); let dataIdx = dbData.findIndex(item => item.dbId === data.dbId); if (dataIdx === -1 || dbData[dataIdx].accessToId === i) return; dbData[dataIdx].accessToId = i; button.className = "btn btn-secondary dropdown-toggle bi"; button.textContent = TYPE_TEXT[data.accessToId]; button.classList.add(TYPE_ICON[data.accessToId]); button.setAttribute("aria-expanded", false); dropdownMenu.classList.remove("show"); dropdownMenu.querySelectorAll(".active").forEach(i => i.classList.remove("active")); a.classList.add("active"); if (dbData[dataIdx].accessToId === 5) grantDiv.classList.add("hidden"); else grantDiv.classList.remove("hidden"); await buildTypeDepandentDiv(typeDepandentDiv, dbData[dataIdx]); await updateData(dbData[dataIdx]); }); li.appendChild(a); dropdownMenu.appendChild(li); } typeDiv.appendChild(button); typeDiv.appendChild(dropdownMenu); typeDivRow.appendChild(typeDiv); await buildTypeDepandentDiv(typeDepandentDiv, data); typeDivRow.appendChild(typeDepandentDiv); } grantDiv.className = "dropdown"; if (data.accessToId === 5) grantDiv.classList.add("hidden"); grantDiv.id = `pch-share-${data.dbId}-grantDropdown`; let button = document.createElement("button"); button.className = "btn btn-secondary dropdown-toggle bi"; button.type = "button"; button.setAttribute("data-bs-toggle", "dropdown"); button.setAttribute("aria-expanded", false); button.id = `${grantDiv.id}-button`; button.textContent = GRANT_TEXT[data.grant]; button.classList.add(GRANT_ICON[data.grant]); let dropdownMenu = document.createElement("ul"); dropdownMenu.className = "dropdown-menu"; for (let i =1; i <= GRANT_TEXT.length; ++i) { let li = document.createElement("li"); let a = document.createElement("a"); a.className = "dropdown-item bi"; if (i === data.grant) a.classList.add("active"); a.href="#"; a.classList.add(GRANT_ICON[i]); a.textContent = GRANT_TEXT[i]; a.addEventListener("click", async () => { let dbData = await getData(); let dataIdx = dbData.findIndex(item => item.dbId === data.dbId); if (dataIdx === -1 || dbData[dataIdx].grant === i) return; dbData[dataIdx].grant = i; button.className = "btn btn-secondary dropdown-toggle bi"; button.textContent = GRANT_TEXT[data.grant]; button.classList.add(GRANT_ICON[data.grant]); button.setAttribute("aria-expanded", false); dropdownMenu.classList.remove("show"); dropdownMenu.querySelectorAll(".active").forEach(i => i.classList.remove("active")); a.classList.add("active"); await updateData(dbData[dataIdx]); }); li.appendChild(a); dropdownMenu.appendChild(li); } grantDiv.appendChild(button); grantDiv.appendChild(dropdownMenu); typeDivRow.appendChild(grantDiv); let deleteButtonRow = document.createElement("div"); let deleteButtonDiv = document.createElement("div"); let deleteButton = document.createElement("button"); deleteButtonRow.className = "row"; deleteButtonDiv.className = "col align-self-end"; deleteButton.className = "btn btn-danger"; deleteButton.textContent = "Revoke"; deleteButtonRow.appendChild(deleteButtonDiv); deleteButtonDiv.appendChild(deleteButton); deleteButton.addEventListener("click", async () => { revokeData(data.dbId).then(success => { if (success) { container.remove(); } }); }); header.appendChild(headerButton); container.appendChild(header); accordionBody.appendChild(typeDivRow); accordionBody.appendChild(deleteButtonRow); accordionBodyContainer.appendChild(accordionBody); container.appendChild(accordionBodyContainer); return container; } async function buildShareItems(data) { let container = document.createElement("ul"); for (let i of data) container.appendChild(await buildShareItem(i)); return container; } window.showShareUi = async () => { if (windowDisplayed) return; document.getElementById("pch-share-wrapper").classList.remove("hidden"); document.Title.pushTitle("Share"); document.body.classList.add("overlay-visible"); const data = await getData(); document.getElementById('pch-share-loading').classList.add("hidden"); const container = document.getElementById('pch-share-container'); container.innerHTML = ""; container.appendChild(await buildShareItems(data)); windowDisplayed = true; } window.closeShareUi = () => { if (!windowDisplayed) return; document.getElementById("pch-share-wrapper").classList.add("hidden"); document.body.classList.remove("overlay-visible"); windowDisplayed = false; document.Title.pop(); } document.onClosePopinRequested(() => { window.closeShareUi(); }); document.getElementById("pch-share-closeBt").addEventListener("click", window.closeShareUi); document.getElementById("pch-share-addLdap").addEventListener("click", () => {}); document.getElementById("pch-share-addEmail").addEventListener("click", () => {}); document.getElementById("pch-share-addLink").addEventListener("click", () => {}); document.getElementById("pch-share-addEveryone").addEventListener("click", () => {}); setTimeout(() => LoadingTasks.push(window.showShareUi), 1500); });