The update dialog kept the old bare title + spinner layout from the previous theme. Rework it (and the rebuild dialog, for consistency) to the approved The Hub dialog anatomy: - Header: green chip icon, title, version chip, status pill (Checking… / Up to date / Updating… / Restart required / Update failed / Status unknown) and a header close button. A spinner appears in the header while an update is starting or running. - System Details card: current version, release channel, and last checked (relative time, refreshed on every check). - The log renders as a console with green "ok" and dim hint lines; the up-to-date result shows as a single green console line exactly once (the redundant status line is hidden in that state). - Footer: Close plus a "Check again" primary action that re-runs the update check. Close and Check again are disabled while a check or update is in flight; all existing recovery actions (Save Error Report, Retry Status, Retry Update, Restart Entire System) keep their exact semantics. - Opening the dialog now shows a "Checking…" state immediately while the existing reattach-then-check logic runs; reattaching to an in-progress update (page reload, RDP reconnect) is unchanged. Sidebar Update System status tints now use the theme palette (red / amber / blue / green), and the periodic background check refreshes the dialog's "last checked" value. Rebuild dialog gets the same header (icon, version chip, Applying… / Done / Restart required / Failed pill, header close disabled while a rebuild runs); its log stays hidden as before. No API or state-machine changes: same endpoints, same polling, same reattach and recovery behavior.
131 lines
6.6 KiB
JavaScript
131 lines
6.6 KiB
JavaScript
"use strict";
|
|
|
|
// ── State ─────────────────────────────────────────────────────────
|
|
|
|
let _servicesCache = [];
|
|
let _categoryLabels = {};
|
|
let _updateLog = "";
|
|
let _updatePollTimer = null;
|
|
let _updatePollInFlight = false;
|
|
let _updateLogOffset = 0;
|
|
let _updateVisibleLogChars = 0;
|
|
let _serverWasDown = false;
|
|
let _updateFinished = false;
|
|
let _updateStatusUnavailable = false;
|
|
let _updatePollFailures = 0; // consecutive failed update-status polls
|
|
let _supportTimerInt = null;
|
|
let _supportEnabledAt = null;
|
|
let _supportStatus = null; // last fetched /api/support/status payload
|
|
let _walletUnlockTimerInt = null;
|
|
let _cachedExternalIp = null;
|
|
|
|
// Current role (set during init from /api/config)
|
|
let _currentRole = "server_plus_desktop";
|
|
|
|
// Feature Manager state
|
|
let _featuresData = null;
|
|
let _rebuildLog = "";
|
|
let _rebuildLogOffset = 0;
|
|
let _rebuildPollTimer = null;
|
|
let _rebuildPollInFlight = false;
|
|
let _rebuildFinished = false;
|
|
let _rebuildServerDown = false;
|
|
let _rebuildPollFailures = 0; // consecutive failed rebuild-status polls
|
|
let _pendingToggle = null; // {feature, extra} waiting for domain/confirm
|
|
let _rebuildFeatureName = "";
|
|
let _rebuildIsEnabling = true;
|
|
|
|
// ── DOM refs ──────────────────────────────────────────────────────
|
|
|
|
const $tilesArea = document.getElementById("tiles-area");
|
|
const $sidebarSupport = document.getElementById("sidebar-support");
|
|
const $sidebarFeatures = document.getElementById("sidebar-features");
|
|
// No longer needed — Update System moved to sidebar
|
|
// const $updateBtn = document.getElementById("btn-update");
|
|
// const $updateBadge = document.getElementById("update-badge");
|
|
const $internalIp = document.getElementById("ip-internal");
|
|
const $externalIp = document.getElementById("ip-external");
|
|
|
|
const $modal = document.getElementById("update-modal");
|
|
const $modalSpinner = document.getElementById("modal-spinner");
|
|
const $modalStatus = document.getElementById("modal-status");
|
|
const $modalLog = document.getElementById("modal-log");
|
|
const $btnReboot = document.getElementById("btn-reboot");
|
|
const $btnSave = document.getElementById("btn-save-report");
|
|
const $btnRetryUpdate = document.getElementById("btn-retry-update-status");
|
|
const $btnRetryRun = document.getElementById("btn-retry-update");
|
|
const $btnCloseModal = document.getElementById("btn-close-modal");
|
|
const $btnCheckAgain = document.getElementById("btn-check-again");
|
|
const $updateCloseBtn = document.getElementById("update-close-btn");
|
|
const $updPill = document.getElementById("upd-pill");
|
|
const $updLastChecked = document.getElementById("upd-last-checked");
|
|
|
|
const $rebootOverlay = document.getElementById("reboot-overlay");
|
|
const $rebootMainCard = document.getElementById("reboot-main-card");
|
|
const $rebootErrorCard = document.getElementById("reboot-error-card");
|
|
const $rebootSubmessage = document.getElementById("reboot-submessage");
|
|
|
|
const $credsModal = document.getElementById("creds-modal");
|
|
const $credsTitle = document.getElementById("creds-modal-title");
|
|
const $credsBody = document.getElementById("creds-body");
|
|
const $credsCloseBtn = document.getElementById("creds-close-btn");
|
|
|
|
const $supportModal = document.getElementById("support-modal");
|
|
const $supportBody = document.getElementById("support-body");
|
|
const $supportCloseBtn = document.getElementById("support-close-btn");
|
|
|
|
const $logoutBtn = document.getElementById("btn-logout");
|
|
|
|
// Feature Manager — rebuild modal
|
|
const $rebuildModal = document.getElementById("rebuild-modal");
|
|
const $rebuildSpinner = document.getElementById("rebuild-spinner");
|
|
const $rebuildStatus = document.getElementById("rebuild-status");
|
|
const $rebuildLog = document.getElementById("rebuild-log");
|
|
const $rebuildReboot = document.getElementById("rebuild-reboot-btn");
|
|
const $rebuildSave = document.getElementById("rebuild-save-report");
|
|
const $rebuildClose = document.getElementById("rebuild-close-btn");
|
|
const $rebuildCloseHdr = document.getElementById("rebuild-close-hdr");
|
|
const $rebuildPill = document.getElementById("rebuild-pill");
|
|
|
|
// Feature Manager — domain setup modal
|
|
const $domainSetupModal = document.getElementById("domain-setup-modal");
|
|
const $domainSetupTitle = document.getElementById("domain-setup-title");
|
|
const $domainSetupBody = document.getElementById("domain-setup-body");
|
|
const $domainSetupClose = document.getElementById("domain-setup-close-btn");
|
|
|
|
// Feature Manager — SSL email modal
|
|
const $sslEmailModal = document.getElementById("ssl-email-modal");
|
|
const $sslEmailInput = document.getElementById("ssl-email-input");
|
|
const $sslEmailSave = document.getElementById("ssl-email-save-btn");
|
|
const $sslEmailCancel = document.getElementById("ssl-email-cancel-btn");
|
|
const $sslEmailClose = document.getElementById("ssl-email-close-btn");
|
|
|
|
// Feature Manager — confirm modal
|
|
const $featureConfirmModal = document.getElementById("feature-confirm-modal");
|
|
const $featureConfirmMsg = document.getElementById("feature-confirm-message");
|
|
const $featureConfirmOk = document.getElementById("feature-confirm-ok-btn");
|
|
const $featureConfirmCancel = document.getElementById("feature-confirm-cancel-btn");
|
|
const $featureConfirmClose = document.getElementById("feature-confirm-close-btn");
|
|
|
|
// Port Requirements modal
|
|
const $portReqModal = document.getElementById("port-requirements-modal");
|
|
const $portReqBody = document.getElementById("port-req-body");
|
|
const $portReqClose = document.getElementById("port-req-close-btn");
|
|
|
|
// Upgrade modal (Node → Server+Desktop)
|
|
const $upgradeModal = document.getElementById("upgrade-modal");
|
|
const $upgradeConfirmBtn = document.getElementById("upgrade-confirm-btn");
|
|
const $upgradeCancelBtn = document.getElementById("upgrade-cancel-btn");
|
|
const $upgradeCloseBtn = document.getElementById("upgrade-close-btn");
|
|
|
|
// Restart confirm dialog
|
|
const $restartConfirmModal = document.getElementById("restart-confirm-modal");
|
|
const $restartConfirmOk = document.getElementById("restart-confirm-ok-btn");
|
|
const $restartConfirmCancel = document.getElementById("restart-confirm-cancel-btn");
|
|
const $restartConflictBox = document.getElementById("restart-conflict-box");
|
|
|
|
// Header reboot button
|
|
const $headerRebootBtn = document.getElementById("btn-header-reboot");
|
|
|
|
// System status banner
|
|
// (removed — health is now shown per-tile via the composite health field)
|