diff --git a/src/rust/lqosd/src/node_manager/js_build/src/dashlets/dashboard.js b/src/rust/lqosd/src/node_manager/js_build/src/dashlets/dashboard.js index 8bc6d485..fa38022f 100644 --- a/src/rust/lqosd/src/node_manager/js_build/src/dashlets/dashboard.js +++ b/src/rust/lqosd/src/node_manager/js_build/src/dashlets/dashboard.js @@ -7,6 +7,7 @@ export class Dashboard { // Takes the name of the parent div to start building the dashboard constructor(divName) { this.divName = divName; + this.editingDashboard = false; this.parentDiv = document.getElementById(divName); if (this.parentDiv === null) { console.log("Dashboard parent not found"); @@ -26,9 +27,13 @@ export class Dashboard { editDiv.style.top = "5px"; editDiv.style.width = "40px"; editDiv.style.zIndex = "100"; - editDiv.innerHTML = ""; + editDiv.innerHTML = ""; editDiv.onclick = () => { - this.editMode(); + if (this.editingDashboard) { + this.closeEditMode(); + } else { + this.editMode(); + } }; this.parentDiv.appendChild(editDiv); } @@ -36,6 +41,8 @@ export class Dashboard { build() { this.#filterWidgetList(); let childDivs = this.#buildWidgetChildDivs(); + this.childIds = []; + childDivs.forEach((d) => { this.childIds.push(d.id); }); this.#clearRenderedDashboard(); childDivs.forEach((d) => { this.parentDiv.appendChild(d) }); this.#buildChannelList(); @@ -100,6 +107,199 @@ export class Dashboard { } editMode() { + // Insert a Temporary Div to hold edit options + let editDiv = document.createElement("div"); + editDiv.classList.add("col-12"); + editDiv.id = "dashboardEditingDiv"; + editDiv.style.height = "100px"; + editDiv.style.backgroundColor = "#007700"; + editDiv.style.padding = "10px"; + editDiv.style.borderRadius = "5px"; + let toasts = document.getElementById("toasts"); + this.editingDashboard = true; + + // Add the editing elements + let row = document.createElement("div"); + row.classList.add("row"); + + let c1 = document.createElement("div"); + c1.classList.add("col-3"); + c1.appendChild(heading5Icon("gear", "Dashboard Options")); + let nuke = document.createElement("button"); + nuke.type = "button"; + nuke.classList.add("btn", "btn-sm", "btn-danger"); + nuke.innerHTML = " Remove All Items"; + nuke.onclick = () => { this.removeAll(); }; + c1.appendChild(nuke); + let filler = document.createElement("button"); + filler.type = "button"; + filler.classList.add("btn", "btn-sm", "btn-warning"); + filler.innerHTML = " One of Everything"; + filler.onclick = () => { this.addAll(); }; + filler.style.marginLeft = "5px"; + c1.appendChild(filler); + + let c2 = document.createElement("div"); + c2.classList.add("col-3"); + c2.appendChild(heading5Icon("plus", "Add Dashlet")); + let list = document.createElement("div"); + list.classList.add("dropdown"); + let listBtn = document.createElement("button"); + listBtn.type = "button"; + listBtn.classList.add("btn", "btn-secondary", "dropdown-toggle"); + listBtn.setAttribute("data-bs-toggle", "dropdown"); + listBtn.innerHTML = " Add Widget"; + list.appendChild(listBtn); + let listUl = document.createElement("ul"); + listUl.classList.add("dropdown-menu"); + DashletMenu.forEach((d) => { + let entry = document.createElement("li"); + let item = document.createElement("a"); + item.classList.add("dropdown-item"); + item.innerText = d.name; + let myTag = d.tag; + item.onclick = () => { + let didSomething = false; + DashletMenu.forEach((d) => { + if (d.tag === myTag) { + this.dashletIdentities.push(d); + didSomething = true; + } + }); + if (didSomething) { + this.#replaceDashletList(); + } + }; + entry.appendChild(item); + listUl.appendChild(entry); + }); + list.appendChild(listUl); + c2.appendChild(list); + + let c3 = document.createElement("div"); + c3.classList.add("col-3"); + c3.appendChild(heading5Icon("save", "Save Layout")) + + let c4 = document.createElement("div"); + c4.classList.add("col-3"); + c4.appendChild(heading5Icon("cloud", "Load Layout")) + + row.appendChild(c1); + row.appendChild(c2); + row.appendChild(c3); + row.appendChild(c4); + editDiv.appendChild(row); + + // Decorate all the dashboard elements with controls + for (let i=0; i 0) { + let myI = i; + editDiv.appendChild(this.#dashEditButton( + clientLeft, + clientMiddleY, + "arrow-circle-left", + "warning", + () => { + this.clickUp(myI); + } + )); + } + + // Right Navigation Arrow + if (i < this.childIds.length-1) { + let myI = i; + editDiv.appendChild(this.#dashEditButton( + clientRight, + clientMiddleY, + "arrow-circle-right", + "warning", + () => { + this.clickDown(myI); + } + )); + } + + // Trash Button + let myI = i; + editDiv.appendChild(this.#dashEditButton( + clientMiddleX, + clientMiddleY, + "trash", + "danger", + () => { + this.clickTrash(myI); + } + )); + + // Expand Button + let myI2 = i; + editDiv.appendChild(this.#dashEditButton( + clientLeft, + clientTop, + "plus-circle", + "secondary", + () => { + this.zoomIn(myI2); + } + )); + + // Contract Button + let myI3 = i; + editDiv.appendChild(this.#dashEditButton( + (clientRect.left + 40) + "px", + clientTop, + "minus-circle", + "secondary", + () => { + this.zoomOut(myI3); + } + )); + } else { + console.log("Warning: NULL div found in dashlet list"); + } + } + + toasts.appendChild(editDiv); + } + + #dashEditButton(left, top, iconSuffix, style, closure) { + let div = document.createElement("div"); + div.style.position = "absolute"; + div.style.width = "20px"; + div.style.zIndex = "200"; + div.style.height = "20px"; + div.style.top = top; + div.style.left = left; + div.classList.add("dashEditButton"); + let button = document.createElement("button"); + button.type = "button"; + button.classList.add("btn", "btn-sm", "btn-" + style); + button.innerHTML = ""; + button.onclick = closure; + div.appendChild(button); + return div; + } + + closeEditMode() { + let editor = document.getElementById("dashboardEditingDiv"); + if (editor != null) { + editor.remove(); + } + this.editingDashboard = false; + } + + editModeOld() { let darken = darkBackground("darkEdit"); let content = modalContent("darkEdit"); @@ -270,9 +470,6 @@ export class Dashboard { #replaceDashletList() { resetWS(); - let newList = this.#buildDashletList(); - let target = document.getElementById("dashletList"); - target.replaceChildren(newList); // Apply this.build(); diff --git a/src/rust/lqosd/src/node_manager/js_build/src/dashlets/top_tree_summary.js b/src/rust/lqosd/src/node_manager/js_build/src/dashlets/top_tree_summary.js index e7becc56..44ca51c9 100644 --- a/src/rust/lqosd/src/node_manager/js_build/src/dashlets/top_tree_summary.js +++ b/src/rust/lqosd/src/node_manager/js_build/src/dashlets/top_tree_summary.js @@ -28,7 +28,6 @@ export class TopTreeSummary extends BaseDashlet { onMessage(msg) { if (msg.event === "TreeSummary") { - console.log(msg.data); let target = document.getElementById(this.id); let t = document.createElement("table"); diff --git a/src/rust/lqosd/src/node_manager/static2/node_manager.css b/src/rust/lqosd/src/node_manager/static2/node_manager.css index 52b8ecfa..8907b491 100644 --- a/src/rust/lqosd/src/node_manager/static2/node_manager.css +++ b/src/rust/lqosd/src/node_manager/static2/node_manager.css @@ -77,4 +77,5 @@ body.dark-mode { overflow: scroll; min-width: 500px; min-height: 500px; -} \ No newline at end of file +} +.dashEditButton { } \ No newline at end of file