// Use globals provided by the PowerShell-generated HTML bridge const tasks = (window.SAMY_TASKS || []); const defaultPage = (window.SAMY_DEFAULT_PAGE || "onboard"); let completedTasks = 0; let totalTasks = 0; // Progress / title handling function setTotalTaskCount(count) { totalTasks = count; completedTasks = 0; updateTitle(); } function logProgress(label, isSuccess) { const statusBox = document.getElementById("status-box"); completedTasks++; updateTitle(); const msg = isSuccess ? ` ${completedTasks}/${totalTasks} done: ${label}` : ` ${completedTasks}/${totalTasks} failed: ${label}`; const div = document.createElement("div"); div.style.color = isSuccess ? "lime" : "red"; div.textContent = msg; statusBox?.appendChild(div); if (completedTasks === totalTasks) { const finalMsg = document.createElement("div"); finalMsg.style.marginTop = "10px"; finalMsg.innerHTML = ` All tasks complete (${completedTasks}/${totalTasks})`; statusBox?.appendChild(finalMsg); document.title = ` ScriptMonkey - Complete (${completedTasks}/${totalTasks})`; const sound = new Audio( "data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEAESsAACJWAAACABAAZGF0YQAAAAA=" ); sound.play().catch(() => {}); flashTitle(document.title); } } function updateTitle() { document.title = `ScriptMonkey - ${completedTasks}/${totalTasks} Done`; } function flashTitle(finalTitle) { let flashes = 0; const interval = setInterval(() => { document.title = document.title === "" ? finalTitle : ""; flashes++; if (flashes >= 10) { clearInterval(interval); document.title = finalTitle; } }, 800); } // ======================================================================= // Tab Navigation // ======================================================================= document.addEventListener("DOMContentLoaded", () => { const tabButtons = document.querySelectorAll(".tab-button"); const tabContents = document.querySelectorAll(".tab-content"); if (!tabButtons?.length || !tabContents?.length) { console.error("ScriptMonkey: no tab buttons or tab contents found."); return; } tabButtons.forEach((btn) => { btn.addEventListener("click", () => { tabButtons.forEach((b) => b.classList.remove("active")); tabContents.forEach((c) => c.classList.remove("active")); btn.classList.add("active"); const targetId = btn.dataset.tab; const target = document.getElementById(targetId); if (target) target.classList.add("active"); }); }); // Default tab from PS (onboard/offboard/tweaks/SVSApps) const defaultTabId = `${defaultPage}Tab`; const defaultBtn = document.querySelector(`.tab-button[data-tab='${defaultTabId}']`); const defaultTab = document.getElementById(defaultTabId); if (defaultBtn) defaultBtn.classList.add("active"); if (defaultTab) defaultTab.classList.add("active"); }); // ======================================================================= // Onboarding: Select-all left/right columns // ======================================================================= function toggleColumn(col) { const master = document.getElementById( `selectAll${col[0].toUpperCase() + col.slice(1)}Checkbox` ); const children = document.querySelectorAll( `#onboardTab input[type=checkbox][data-column=${col}]` ); children.forEach((cb) => { cb.checked = master.checked; }); setTimeout(() => { children.forEach((cb) => { cb.dispatchEvent(new Event("change")); }); }, 0); } function updateSelectAll(col) { const master = document.getElementById( `selectAll${col[0].toUpperCase() + col.slice(1)}Checkbox` ); const children = document.querySelectorAll( `#onboardTab input[type=checkbox][data-column=${col}]` ); master.checked = Array.from(children).every((cb) => cb.checked); } document.addEventListener("DOMContentLoaded", () => { ["left", "right"].forEach((col) => { document .querySelectorAll(`#onboardTab input[type=checkbox][data-column=${col}]`) .forEach((cb) => cb.addEventListener("change", () => updateSelectAll(col)) ); }); }); // ======================================================================= // Off-boarding Select All // ======================================================================= function toggleOffboardAll() { const master = document.getElementById("offboardSelectAll"); const children = document.querySelectorAll( "#offboardTab input[type=checkbox]:not(#offboardSelectAll)" ); children.forEach((cb) => { cb.checked = master.checked; }); } function updateOffboardSelectAll() { const master = document.getElementById("offboardSelectAll"); if (!master) return; const children = document.querySelectorAll( "#offboardTab input[type=checkbox]:not(#offboardSelectAll)" ); if (!children.length) { master.checked = false; return; } master.checked = Array.from(children).every((cb) => cb.checked); } document.addEventListener("DOMContentLoaded", () => { const offChildren = document.querySelectorAll( "#offboardTab input[type=checkbox]:not(#offboardSelectAll)" ); if (!offChildren?.length) return; offChildren.forEach((cb) => cb.addEventListener("change", updateOffboardSelectAll) ); updateOffboardSelectAll(); }); // ======================================================================= // DattoRMM options + Enter key handling // ======================================================================= function toggleDattoRMMOptions() { const master = document.getElementById("installDattoRMM"); const container = document.getElementById("installDattoRMMOptionsContainer"); if (!container) return; const checked = master?.checked; container.style.display = checked ? "block" : "none"; container .querySelectorAll('input[type="checkbox"]') .forEach((cb) => (cb.checked = checked)); } document.addEventListener("DOMContentLoaded", () => { const master = document.getElementById("installDattoRMM"); if (master) { master.addEventListener("change", toggleDattoRMMOptions); } const passwordField = document.getElementById("Password"); const goButton = document.querySelector("button[onclick='fetchSites()']"); if (passwordField && goButton) { passwordField.addEventListener("keydown", (e) => { if (e.key === "Enter") { goButton.click(); } }); } const siteDropdown = document.getElementById("dattoDropdown"); const runButton = document.querySelector(".run-button"); if (siteDropdown && runButton) { siteDropdown.addEventListener("keydown", (e) => { if (e.key === "Enter" && siteDropdown.value) { runButton.click(); } }); } }); // ======================================================================= // Fetch Sites handler (calls /getpw) // ======================================================================= async function fetchSites() { const pwdInput = document.getElementById("Password"); const pwd = pwdInput?.value; if (!pwd) { alert("Please enter the password."); return; } const dropdown = document.getElementById("dattoDropdown"); dropdown.innerHTML = ''; try { const resp = await fetch("/getpw", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ password: pwd }), }); if (!resp.ok) throw "HTTP " + resp.status; const sites = await resp.json(); dropdown.innerHTML = ""; sites.forEach((site) => { const option = document.createElement("option"); option.value = site.UID; option.textContent = site.Name; dropdown.appendChild(option); }); document.getElementById("dattoRmmContainer").style.display = "block"; } catch (e) { console.error(e); dropdown.innerHTML = ''; alert("Failed to fetch sites. Check password and try again."); } } // ======================================================================= // Run Selected (main trigger) // ======================================================================= async function triggerInstall() { const runBtn = document.querySelector(".run-button"); if (!runBtn) return; runBtn.disabled = true; const statusBox = document.getElementById("status-box"); if (statusBox) statusBox.innerHTML = ""; try { const checkedTasks = tasks.filter((t) => { const cb = document.getElementById(t.id); return cb && cb.checked; }); setTotalTaskCount(checkedTasks.length); // 1. DattoRMM first const dattoCB = document.getElementById("installDattoRMM"); if (dattoCB && dattoCB.checked) { try { const sub = Array.from( document.querySelectorAll(".sub-option-installDattoRMM:checked") ).map((x) => x.value); const dropdown = document.getElementById("dattoDropdown"); const uid = dropdown?.value; const name = dropdown?.selectedOptions?.[0]?.text || "Datto"; await fetch("/installDattoRMM", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ checkedValues: sub, UID: uid, Name: name }), }); logProgress("Install DattoRMM", true); } catch (e) { logProgress("Install DattoRMM", false); console.error(e); } } // 2. SVSMSP module second const svsCB = document.getElementById("installSVSMSPModule"); if (svsCB && svsCB.checked) { try { await fetch("/installSVSMSPModule", { method: "GET" }); logProgress("Install SVSMSP Module", true); } catch (e) { logProgress("Install SVSMSP Module", false); console.error(e); } } // 3. Remaining tasks for (const t of tasks) { if (["installDattoRMM", "installSVSMSPModule"].includes(t.id)) continue; const cb = document.getElementById(t.id); if (!cb || !cb.checked) continue; try { await fetch(t.handler, { method: "GET" }); logProgress(t.label || t.id, true); } catch (e) { logProgress(t.label || t.id, false); console.error(`Error running ${t.id}:`, e); } } } catch (e) { console.error("triggerInstall fatal error:", e); } finally { runBtn.disabled = false; } } // ======================================================================= // Shutdown handler (Exit button & window close) // ======================================================================= function endSession() { fetch("/quit", { method: "GET" }).finally(() => window.close()); } // Sub-options auto-toggle, tagline rotation, and beforeunload hook document.addEventListener("DOMContentLoaded", () => { // Sub-option containers const tasksWithSubOptions = document.querySelectorAll( '[id$="OptionsContainer"]' ); tasksWithSubOptions.forEach((container) => { const taskId = container.id.replace("OptionsContainer", ""); const masterCheckbox = document.getElementById(taskId); if (!masterCheckbox) return; function updateVisibility() { const checked = masterCheckbox.checked; container.style.display = checked ? "block" : "none"; container .querySelectorAll('input[type="checkbox"]') .forEach((cb) => (cb.checked = checked)); if (taskId === "installDattoRMM") { const pwdBox = document.getElementById("PasswordContainer"); const rmmBox = document.getElementById("dattoRmmContainer"); if (pwdBox) pwdBox.style.display = checked ? "block" : "none"; if (rmmBox) rmmBox.style.display = checked ? "block" : "none"; } } masterCheckbox.addEventListener("change", updateVisibility); updateVisibility(); }); // Tagline rotation const taglines = [ "Fast deployments, no monkey business.", "Bananas for better builds.", "Deploy without flinging code.", "Tame your stack. Unleash the monkey.", "Monkey see, monkey deploy.", "Deploy smarter -- with a monkey on your team.", "Don't pass the monkey -- let it deploy.", "No more monkeying around. Stack handled.", "Own your stack. But let the monkey do the work.", "Why throw code when the monkey's got it?", "Deployments so easy, a monkey could do it. Ours does.", "Monkey in the stack, not on your back.", ]; const el = document.getElementById("tagline"); if (el) { let idx = Math.floor(Math.random() * taglines.length); el.textContent = taglines[idx]; setInterval(() => { idx = (idx + 1) % taglines.length; el.textContent = taglines[idx]; }, 10_000); } }); // notify server on window close window.addEventListener("beforeunload", () => { fetch("/quit", { method: "GET", keepalive: true }); });