2026-04-29 10:00:40 +00:00
<!DOCTYPE html>
< html lang = "zh-TW" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > Harmonic CMTS Manager< / title >
< link rel = "stylesheet" href = "https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.css" / >
< script src = "https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.js" > < / script >
< script src = "https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.js" > < / script >
2026-04-30 08:27:18 +00:00
<!-- 引入獨立的 CSS 樣式表 -->
2026-04-29 10:00:40 +00:00
< link rel = "stylesheet" href = "/static/style.css" / >
< / head >
< body >
2026-05-14 07:42:18 +00:00
<!-- 1. 標題加上 id="app - title" -->
< h1 id = "app-title" style = "cursor: default;" > 🎙️ Harmonic CMTS Admin< / h1 >
2026-04-29 10:00:40 +00:00
< div class = "global-settings" >
< label > < strong > 🌐 目標設備:< / strong > < / label >
< input type = "text" id = "cmtsHost" placeholder = "IP 地址" value = "10.14.110.4" style = "width: 130px;" >
< input type = "text" id = "cmtsUser" placeholder = "帳號" value = "admin" style = "width: 100px;" >
< input type = "password" id = "cmtsPass" placeholder = "密碼" value = "nsgadmin" style = "width: 100px;" >
< div style = "margin-left: 15px; display: flex; align-items: center; gap: 10px;" >
2026-05-18 03:51:23 +00:00
< button onclick = "connectWebSocket()" id = "btnConnect" class = "btn-modern btn-connect" > 連線至 CMTS< / button >
< button onclick = "disconnectWebSocket()" id = "btnDisconnect" class = "btn-modern btn-disconnect" style = "display: none;" > 斷開連線< / button >
2026-04-29 10:00:40 +00:00
< span id = "wsStatus" style = "color: #7f8c8d; font-size: 14px; font-weight: bold;" > 狀態:未連線< / span >
< / div >
< / div >
< div class = "tabs" >
< button class = "tab-btn active" onclick = "switchTab('cli-tab', this)" > 💻 True SSH Terminal< / button >
< button class = "tab-btn" onclick = "switchTab('query-tab', this)" > 🔍 CMTS 狀態查詢< / button >
< button class = "tab-btn" onclick = "switchTab('config-tab', this)" > ⚙️ CMTS 設備配置< / button >
2026-04-30 08:27:18 +00:00
<!-- 💡 新增:系統設定頁籤 -->
< button class = "tab-btn" onclick = "switchTab('settings-tab', this); openSystemSettings();" > ⚙️ 系統設定< / button >
2026-04-29 10:00:40 +00:00
< / div >
<!-- Tab 1: True SSH Terminal -->
< div id = "cli-tab" class = "tab-content active" >
< div class = "control-group" >
< label > < strong > 快捷指令:< / strong > < / label >
< select id = "fixedCmd" >
< option value = "show cable modem" > 數據機狀態 (show cable modem)< / option >
< option value = "show cable rpd" > RPD 狀態 (show cable rpd)< / option >
< option value = "show running-config | nomore" > 系統實時設定檔 (show running-config | nomore)< / option >
< / select >
2026-05-15 07:17:28 +00:00
< button onclick = "injectCommand()" class = "btn-modern btn-load" > 送出指令< / button >
2026-04-29 10:00:40 +00:00
< div style = "margin-left: auto; display: flex; gap: 8px;" >
2026-05-15 07:17:28 +00:00
< button onclick = "downloadTerminal()" class = "btn-modern btn-slate" > 💾 下載紀錄< / button >
2026-04-29 10:00:40 +00:00
< / div >
< / div >
< div id = "terminal-container" > < / div >
< / div >
<!-- Tab 2: CMTS 狀態查詢 -->
< div id = "query-tab" class = "tab-content" style = "overflow-y: auto; background-color: #f5f7fa;" >
< div class = "manager-container" >
< div class = "control-group" style = "background: #ffffff; padding: 15px 25px; border-radius: 8px; margin-bottom: 0; box-shadow: 0 2px 4px rgba(0,0,0,0.02); border: 1px solid #e2e8f0;" >
< label style = "font-weight: bold; color: #2c3e50; font-size: 16px; margin-right: 10px;" > 📌 選擇查詢任務:< / label >
< select id = "queryTask" onchange = "switchQueryTask()" style = "width: 400px; max-width: 100%; font-weight: bold; font-size: 15px; padding: 8px; background-color: #f8f9fa;" >
< option value = "form-cm-query" > 🔎 Cable 狀態綜合查詢< / option >
< option value = "form-rpd-query" > 📡 RPD 狀態綜合查詢< / option >
< / select >
< / div >
<!-- 表單 1: Cable 狀態綜合查詢 -->
< div id = "form-cm-query" class = "task-form active" >
< h3 style = "margin-top: 0; font-size: 18px; color: #2980b9; border-bottom: 2px solid #ecf0f1; padding-bottom: 10px; margin-bottom: 20px;" > Cable 狀態綜合查詢 (show cable modem...)< / h3 >
< div class = "form-grid" >
< div class = "form-row" >
< label > 目標設備 (Cable Modem MAC)< / label >
< input type = "text" id = "queryTargetCm" placeholder = "例: 6467.7240.4076 (留白則查詢全體)" >
< / div >
< div class = "form-row" >
< label > 查詢動作 (Action)< / label >
< select id = "queryTypeCm" onchange = "toggleQueryInputs('Cm')" >
< optgroup label = "Cable Modem 查詢 (支援特定目標或全體)" >
< option value = "base" > 基本狀態 (show cable modem)< / option >
< option value = "cpe" > CPE 資訊 (cpe)< / option >
< option value = "cpe_dhcp" > CPE DHCP (cpe dhcp)< / option >
< option value = "cpe_ipv6" > CPE IPv6 (cpe ipv6)< / option >
< option value = "bonding" > 綁定摘要 (bonding)< / option >
< option value = "bonding_ds" > 下行綁定 (bonding downstream)< / option >
< option value = "bonding_us" > 上行綁定 (bonding upstream)< / option >
< option value = "phy" > 實體層狀態 (phy)< / option >
< option value = "verbose" > 詳細資訊 (verbose)< / option >
< option value = "ofdm_profile" > OFDM Profile (ofdm-profile)< / option >
< option value = "ofdma_profile" > OFDMA Profile (ofdma-profile)< / option >
< option value = "dhcp_verbose" > DHCP 詳細資訊 (dhcp verbose)< / option >
< option value = "service_flow" > Service Flow (service-flow)< / option >
< option value = "service_flow_verbose" > Service Flow 詳細 (service-flow verbose)< / option >
< option value = "qos" > QoS 資訊 (qos)< / option >
< option value = "uptime" > 運行時間 (uptime)< / option >
< option value = "ugs" > UGS 資訊 (ugs)< / option >
< option value = "cm_status" > CM 狀態 (cm-status)< / option >
< / optgroup >
< optgroup label = "全域狀態查詢 (不分特定目標)" >
< option value = "partial_mode" > Partial Mode (partial-mode)< / option >
< option value = "hop" > Cable Hop (show cable hop)< / option >
< option value = "flap_list" > Flap List (show cable flap-list)< / option >
< option value = "flap_sum" > Flap Summary (show cable flap-sum)< / option >
< / optgroup >
< / select >
< / div >
< / div >
< div class = "form-actions" >
2026-05-15 07:17:28 +00:00
< button onclick = "executeQuery('Cm')" class = "btn-modern btn-load" > 執行查詢< / button >
2026-04-29 10:00:40 +00:00
< div style = "display: flex; align-items: center;" >
< input type = "checkbox" id = "debugQueryCm" style = "width: 18px; height: 18px; margin: 0; cursor: pointer;" >
< label for = "debugQueryCm" style = "cursor: pointer; color: #7f8c8d; margin-left: 8px; font-size: 14px;" > 🐞 顯示底層指令 (Debug)< / label >
< / div >
< / div >
< / div >
<!-- 表單 2: RPD 狀態綜合查詢 -->
< div id = "form-rpd-query" class = "task-form" >
< h3 style = "margin-top: 0; font-size: 18px; color: #e67e22; border-bottom: 2px solid #ecf0f1; padding-bottom: 10px; margin-bottom: 20px;" > RPD 狀態綜合查詢 (show cable rpd...)< / h3 >
< div class = "form-grid" >
< div class = "form-row" >
< label > 目標設備 (RPD VC:VS)< / label >
< input type = "text" id = "queryTargetRpd" placeholder = "例: 13:0 (留白則查詢全體)" >
< / div >
< div class = "form-row" >
< label > 查詢動作 (Action)< / label >
< select id = "queryTypeRpd" onchange = "toggleQueryInputs('Rpd')" >
< option value = "rpd_base" > 基本狀態 (show cable rpd)< / option >
< option value = "rpd_verbose" > 詳細資訊 (verbose)< / option >
< option value = "rpd_ptp_time" > PTP Time Property (ptp time-property)< / option >
< option value = "rpd_ptp_verbose" > PTP 詳細資訊 (ptp verbose)< / option >
< option value = "rpd_counters_map" > Counters Map (counters map)< / option >
< option value = "rpd_capabilities" > 能力資訊 (capabilities)< / option >
< option value = "rpd_video_counters" > Video Counters (video-channel counters)< / option >
< option value = "rpd_env_temp" > 環境溫度 (environment temperature)< / option >
< option value = "rpd_env_volt" > 環境電壓 (environment voltage)< / option >
< option value = "rpd_session" > Session (session)< / option >
< option value = "rpd_reset_history" > 重啟歷史 (reset-history)< / option >
< option value = "rpd_port_transceiver" > 光模組資訊 (port-transceiver)< / option >
< / select >
< / div >
< / div >
< div class = "form-actions" >
2026-05-15 07:17:28 +00:00
< button onclick = "executeQuery('Rpd')" class = "btn-modern btn-load" > 執行查詢< / button >
2026-04-29 10:00:40 +00:00
< div style = "display: flex; align-items: center;" >
< input type = "checkbox" id = "debugQueryRpd" style = "width: 18px; height: 18px; margin: 0; cursor: pointer;" >
< label for = "debugQueryRpd" style = "cursor: pointer; color: #7f8c8d; margin-left: 8px; font-size: 14px;" > 🐞 顯示底層指令 (Debug)< / label >
< / div >
< / div >
< / div >
2026-04-30 08:27:18 +00:00
< / div >
< / div >
2026-04-29 10:00:40 +00:00
<!-- Tab 3: CMTS 設備配置 -->
< div id = "config-tab" class = "tab-content" style = "overflow-y: auto; background-color: #fdfefe;" >
< div class = "manager-container" >
2026-05-14 07:42:18 +00:00
< div class = "control-group" style = "background: #ffffff; padding: 10px 15px; border-radius: 8px; margin-bottom: 0; box-shadow: 0 2px 4px rgba(0,0,0,0.02); border: 1px solid #e2e8f0;" >
2026-04-29 10:00:40 +00:00
< label style = "font-weight: bold; color: #c0392b; font-size: 16px; margin-right: 10px;" > 🛠️ 選擇配置任務:< / label >
2026-04-30 08:27:18 +00:00
< select id = "configTask" onchange = "switchConfigTask()" style = "width: 400px; max-width: 100%; font-weight: bold; font-size: 15px; padding: 8px; background-color: #fcf3f2; border-color: #fadbd8;" >
2026-04-29 10:00:40 +00:00
< option value = "form-bonding-config" > ⚠️ MAC Domain 狀態感知配置精靈< / option >
2026-04-30 08:27:18 +00:00
< option value = "form-full-config" > 🌳 完整設備配置樹狀圖< / option >
2026-04-29 10:00:40 +00:00
< / select >
2026-05-15 07:17:28 +00:00
< button id = "btn-load-task" onclick = "startConfigTask()" class = "btn-modern btn-load" style = "margin-left: 10px;" disabled > 🚀 載入任務< / button >
2026-04-29 10:00:40 +00:00
< / div >
2026-04-30 08:27:18 +00:00
<!-- 表單 3: MAC Domain 配置精靈 -->
< div id = "form-bonding-config" class = "task-form active" >
2026-04-29 10:00:40 +00:00
< h3 style = "margin-top: 0; font-size: 18px; color: #c0392b; border-bottom: 2px solid #ecf0f1; padding-bottom: 10px; margin-bottom: 20px;" > ⚠️ MAC Domain 狀態感知配置精靈< / h3 >
< div class = "control-group" style = "background: #fdf2e9; padding: 15px; border-radius: 6px; border: 1px solid #fadbd8;" >
< label style = "font-weight: bold; color: #d35400;" > 1. 目標 MAC Domain: < / label >
< select id = "cfgMacDomain" style = "width: 150px; padding: 6px; font-weight: bold; border: 1px solid #fadbd8; border-radius: 4px; background-color: #fff;" >
< option value = "" > 請先點擊上方載入任務...< / option >
< / select >
2026-05-15 07:17:28 +00:00
< button onclick = "fetchMacDomainConfig()" class = "btn-modern btn-load" > 🔍 讀取現有配置< / button >
2026-04-29 10:00:40 +00:00
< span id = "fetchStatus" style = "margin-left: 10px; font-size: 14px; color: #7f8c8d;" > 請先讀取設備狀態...< / span >
< / div >
< div id = "macDomainConfigArea" style = "display: none; margin-top: 20px;" >
<!-- Common Settings -->
< h4 style = "color: #2980b9; border-left: 4px solid #2980b9; padding-left: 8px;" > Common Settings< / h4 >
< div class = "form-grid" >
< div class = "form-row" > < label > IP Provisioning Mode< / label > < select id = "g_ip_prov" > < option value = "alternate" > alternate< / option > < option value = "dual-stack" > dual-stack< / option > < option value = "ipv4-only" > ipv4-only< / option > < option value = "ipv6-only" > ipv6-only< / option > < / select > < / div >
< div class = "form-row" > < label > Diplexer Band Edge Control< / label > < select id = "g_diplexer" > < option value = "enabled" > enabled< / option > < option value = "disabled" > disabled< / option > < / select > < / div >
< div class = "form-row" > < label > CM Battery Mode 3.1< / label > < select id = "g_bat31" > < option value = "enabled" > enabled< / option > < option value = "disabled" > disabled< / option > < / select > < / div >
< div class = "form-row" > < label > CM Battery Mode 3.0< / label > < select id = "g_bat30" > < option value = "enabled" > enabled< / option > < option value = "disabled" > disabled< / option > < / select > < / div >
< div class = "form-row" > < label > DOCSIS 4.0< / label > < select id = "g_docsis40" > < option value = "enabled" > enabled< / option > < option value = "disabled" > disabled< / option > < / select > < / div >
< div class = "form-row" > < label > DS Dynamic Bonding Group< / label > < select id = "g_ds_dyn" onchange = "toggleGroupVisibility()" > < option value = "enabled" > enabled< / option > < option value = "disabled" > disabled< / option > < / select > < / div >
< div class = "form-row" > < label > US Dynamic Bonding Group< / label > < select id = "g_us_dyn" onchange = "toggleGroupVisibility()" > < option value = "enabled" > enabled< / option > < option value = "disabled" > disabled< / option > < / select > < / div >
< / div >
<!-- [Basic] DS/US Channel Sets -->
< h4 style = "color: #27ae60; border-left: 4px solid #27ae60; padding-left: 8px; margin-top: 30px;" > [Basic] DS/US Channel Sets< / h4 >
< div class = "form-grid" >
< div class = "form-row" > < label > Admin State< / label > < select id = "b_admin" > < option value = "up" > up< / option > < option value = "down" > down< / option > < / select > < / div >
< div class = "form-row" > < label > DS Primary Set (0..157)< / label > < input type = "text" id = "b_ds_pri" placeholder = "例: 0-2" > < / div >
< div class = "form-row" > < label > DS Non-Primary Set (0..157)< / label > < input type = "text" id = "b_ds_non_pri" placeholder = "例: 3-4" > < / div >
< div class = "form-row" > < label > US PHY Channel Set (0..255)< / label > < input type = "text" id = "b_us_phy" placeholder = "例: 0-3" > < / div >
< div class = "form-row" > < label > DS OFDM Set (0..7)< / label > < input type = "text" id = "b_ds_ofdm" placeholder = "例: 0" > < / div >
< div class = "form-row" > < label > US OFDMA Set (0..1)< / label > < input type = "text" id = "b_us_ofdma" placeholder = "例: 0" > < / div >
< / div >
<!-- [Static] Downstream Bonding Groups -->
< div id = "section_group_ds" style = "margin-top: 30px;" >
< h4 style = "color: #8e44ad; border-left: 4px solid #8e44ad; padding-left: 8px;" > [Static] Downstream Bonding Groups< / h4 >
< div class = "control-group" style = "background: #f4f6f7; padding: 10px; border-radius: 4px;" >
< label > 選擇要編輯的 DS Group: < / label >
< select id = "select_ds_group" onchange = "loadDsGroupData()" style = "width: 200px;" > < / select >
< input type = "text" id = "input_new_ds_group" placeholder = "輸入新 Group 名稱 (例: D4A)" style = "display: none; width: 200px;" >
< / div >
< div class = "form-grid" >
< div class = "form-row" > < label > Admin State< / label > < select id = "ds_g_admin" > < option value = "up" > up< / option > < option value = "down" > down< / option > < / select > < / div >
< div class = "form-row" > < label > Down Channel Set (0..157)< / label > < input type = "text" id = "ds_g_down" placeholder = "例: 0-4" > < / div >
< div class = "form-row" > < label > OFDM Channel Set (0..7)< / label > < input type = "text" id = "ds_g_ofdm" placeholder = "例: 0-1" > < / div >
< div class = "form-row" > < label > FDX OFDM Channel Set (0..7)< / label > < input type = "text" id = "ds_g_fdx" placeholder = "例: 0-2" > < / div >
< / div >
< / div >
<!-- [Static] Upstream Bonding Groups -->
< div id = "section_group_us" style = "margin-top: 30px;" >
< h4 style = "color: #f39c12; border-left: 4px solid #f39c12; padding-left: 8px;" > [Static] Upstream Bonding Groups< / h4 >
< div class = "control-group" style = "background: #f4f6f7; padding: 10px; border-radius: 4px;" >
< label > 選擇要編輯的 US Group: < / label >
< select id = "select_us_group" onchange = "loadUsGroupData()" style = "width: 200px;" > < / select >
< input type = "text" id = "input_new_us_group" placeholder = "輸入新 Group 名稱 (例: U4A)" style = "display: none; width: 200px;" >
< / div >
< div class = "form-grid" >
< div class = "form-row" > < label > Admin State< / label > < select id = "us_g_admin" > < option value = "up" > up< / option > < option value = "down" > down< / option > < / select > < / div >
< div class = "form-row" > < label > US Channel Set< / label > < input type = "text" id = "us_g_us" placeholder = "例: 0-3.0" > < / div >
< div class = "form-row" > < label > OFDMA Channel Set (0..1)< / label > < input type = "text" id = "us_g_ofdma" placeholder = "例: 0" > < / div >
< div class = "form-row" > < label > FDX OFDMA Channel Set (0..5)< / label > < input type = "text" id = "us_g_fdx" placeholder = "例: 0-5" > < / div >
< / div >
< / div >
<!-- CLI 預覽區塊 -->
< div id = "cliPreviewContainer" style = "display: none; background: #2c3e50; color: #ecf0f1; padding: 15px; border-radius: 6px; margin-top: 30px; margin-bottom: 20px; font-family: monospace; white-space: pre-wrap;" > < / div >
< div class = "form-actions" >
2026-05-15 07:17:28 +00:00
< button id = "btnRevert" onclick = "revertFormChanges()" class = "btn-modern btn-disconnect" style = "margin-right: 15px;" > 🔄 復原重填< / button >
< button onclick = "generateMacDomainCLI()" class = "btn-modern btn-scan" > ⚙️ 產生絕對路徑指令預覽< / button >
< button id = "btnDeployConfig" onclick = "executeBondingConfig()" class = "btn-modern btn-save" style = "display: none;" disabled > 🚀 正式套用設定< / button >
2026-04-29 10:00:40 +00:00
< / div >
< / div >
< / div >
2026-04-30 08:27:18 +00:00
<!-- 表單 4: 完整設備配置樹狀圖 -->
< div id = "form-full-config" class = "task-form" style = "display: none;" >
2026-05-14 07:42:18 +00:00
< h3 style = "display: flex; align-items: center; margin-top: 0; margin-bottom: 10px; font-size: 16px; color: #2c3e50;" >
2026-04-30 10:52:55 +00:00
🌳 完整設備配置樹狀圖
2026-05-08 08:50:12 +00:00
2026-05-15 07:17:28 +00:00
<!-- 🌟 掃描與清除按鈕群組 -->
< button id = "btn-scan-visible" onclick = "scanVisibleMissingOptions()" class = "btn-modern btn-scan" disabled style = "display: none; margin-left: 20px;" >
🔍 掃描局部缺失選項
< / button >
< button id = "btn-clear-visible" onclick = "clearVisibleCache()" class = "btn-modern btn-clear" style = "display: none; margin-left: 10px;" >
🗑️ 清除局部選項快取
2026-05-08 08:50:12 +00:00
< / button >
2026-05-15 07:17:28 +00:00
< button id = "btn-scan-global" onclick = "scanGlobalMissingOptions()" class = "btn-modern btn-scan" disabled style = "display: none; margin-left: 10px;" >
🌍 掃描全域缺失選項
< / button >
< button id = "btn-clear-global" onclick = "clearGlobalCache()" class = "btn-modern btn-clear" style = "display: none; margin-left: 10px;" >
🔥 清除全域快取
2026-05-08 08:50:12 +00:00
< / button >
<!-- 🌟 新增:掃描進度提示 -->
< span id = "scan-status" style = "color: #7f8c8d; font-size: 14px; margin-left: 15px; font-weight: normal;" > < / span >
2026-04-30 10:52:55 +00:00
< span id = "loading-message" style = "display: none; color: #f39c12; font-size: 14px; margin-left: 15px; font-weight: normal;" >
2026-04-30 08:27:18 +00:00
⏳ 正在從設備抓取完整配置,可能需要 30~60 秒,請耐心稍候...
2026-04-30 10:52:55 +00:00
< / span >
< / h3 >
2026-05-04 10:26:12 +00:00
<!-- 🌟 左右分屏容器 -->
< div id = "split-container" style = "display: flex; align-items: flex-start; width: 100%; position: relative;" >
<!-- 左側:樹狀圖 (預設滿版,顯示預覽時會被 JS 改為 50%) -->
2026-05-08 08:50:12 +00:00
<!-- <div id="tree - container" style="width: 100%; background - color: #ffffff; padding: 15px; border - radius: 5px; border: 1px solid #e0e0e0; min - height: 100px; box - sizing: border - box; overflow - x: auto;">
< span style = "color: #7f8c8d;" > 尚未載入資料。請點擊上方「載入任務」按鈕開始。< / span >
< / div > -->
<!-- 左側:樹狀圖 (預設滿版,顯示預覽時會被 JS 改為 50%) -->
< div id = "tree-container" style = "width: 100%; background-color: #ffffff; padding: 15px; border-radius: 5px; border: 1px solid #e0e0e0; min-height: 100px; max-height: 600px; box-sizing: border-box; overflow-x: auto; overflow-y: auto;" >
2026-05-04 10:26:12 +00:00
< span style = "color: #7f8c8d;" > 尚未載入資料。請點擊上方「載入任務」按鈕開始。< / span >
< / div >
<!-- 🖱️ 拖曳分隔線 (預設隱藏) -->
< div id = "drag-resizer" style = "display: none; width: 12px; cursor: col-resize; margin: 0 5px; flex-shrink: 0; align-items: center; justify-content: center; position: sticky; top: 20px; height: 400px; z-index: 10;" title = "左右拖曳調整寬度" >
< div style = "width: 4px; height: 40px; background-color: #bdc3c7; border-radius: 2px;" > < / div >
< / div >
2026-04-30 08:27:18 +00:00
2026-05-04 10:26:12 +00:00
<!-- 右側: CLI 預覽與執行結果 (預設隱藏,顯示時佔 50%) -->
< div id = "side-cli-preview" style = "width: 50%; position: sticky; top: 20px; background: #2c3e50; padding: 12px 15px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); display: none; border: 1px solid #34495e; box-sizing: border-box; flex-shrink: 0;" >
<!-- 頂部標題列 -->
< div style = "display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;" >
< h4 id = "side-pane-title" style = "color: #f1c40f; margin: 0; font-size: 15px;" > ⚠️ 即將寫入的指令< / h4 >
< div style = "display: flex; align-items: center; gap: 10px;" >
<!-- 預覽模式按鈕 -->
2026-05-15 07:17:28 +00:00
< button id = "btn-side-cancel" onclick = "hideSideCLI()" class = "btn-modern btn-disconnect" style = "padding: 5px 12px; font-size: 13px;" > 取消< / button >
< button id = "btn-side-confirm" onclick = "executeSideCLI()" class = "btn-modern btn-save" style = "padding: 5px 12px; font-size: 13px;" > 🚀 確認寫入< / button >
2026-05-04 10:26:12 +00:00
<!-- 執行結果模式按鈕 (預設隱藏) -->
2026-05-15 07:17:28 +00:00
< button id = "btn-side-close" onclick = "hideSideCLI()" class = "btn-modern btn-load" style = "padding: 5px 12px; font-size: 13px; display: none;" > ✅ 完成並關閉< / button >
2026-05-04 10:26:12 +00:00
< div style = "width: 1px; height: 20px; background-color: #7f8c8d; margin: 0 5px;" > < / div >
< span onclick = "hideSideCLI()" style = "color: #bdc3c7; font-size: 26px; cursor: pointer; line-height: 1;" title = "關閉面板" > × < / span >
< / div >
< / div >
<!-- 模式一:指令預覽框 (可編輯) -->
< textarea id = "side-cli-textarea" style = "width: 100%; height: 400px; background: #1e1e1e; color: #ecf0f1; font-family: 'Consolas', 'Monaco', 'Courier New', monospace; font-size: 14px; line-height: 1.5; padding: 12px 15px; border: 1px solid #7f8c8d; border-radius: 4px; box-sizing: border-box; white-space: pre; overflow-wrap: normal; overflow-x: scroll; margin-bottom: 0; display: block;" > < / textarea >
<!-- 模式二:執行結果框 (唯讀,升級字體與行高) -->
< div id = "side-execution-result" style = "width: 100%; height: 400px; background: #1e1e1e; color: #ecf0f1; font-family: 'Consolas', 'Monaco', 'Courier New', monospace; font-size: 14px; line-height: 1.5; padding: 12px 15px; border: 1px solid #7f8c8d; border-radius: 4px; box-sizing: border-box; overflow-y: auto; margin-bottom: 0; display: none; white-space: pre-wrap; word-wrap: break-word;" > < / div >
< / div >
2026-04-30 08:27:18 +00:00
< / div >
2026-05-04 10:26:12 +00:00
< / div >
2026-04-29 10:00:40 +00:00
< / div >
< / div >
2026-04-30 08:27:18 +00:00
<!-- 💡 Tab 4: 系統設定 (System Settings) -->
< div id = "settings-tab" class = "tab-content" style = "overflow-y: auto; background-color: #fdfefe; text-align: left;" >
< div class = "manager-container" style = "display: block; max-width: 100%;" >
< div class = "control-group" style = "background: #ffffff; padding: 25px 30px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); border: 1px solid #e2e8f0; text-align: left; display: block;" >
< h3 style = "margin-top: 0; font-size: 18px; color: #2c3e50; border-bottom: 2px solid #ecf0f1; padding-bottom: 10px; margin-bottom: 20px;" >
⚙️ 全域系統設定 (God Mode Filters)
< / h3 >
< div style = "background: #f8f9fa; border-left: 4px solid #3498db; padding: 12px 15px; border-radius: 4px; margin-bottom: 20px;" >
< p style = "color: #2c3e50; font-size: 15px; margin: 0;" >
請勾選您希望在「完整設備配置樹狀圖」中 < b > 隱藏< / b > 的設定項目。< br >
< span style = "color: #7f8c8d; font-size: 14px;" > 💡 點擊下方按鈕載入設備實時配置,您可以深入展開並勾選任何層級的節點進行過濾。< / span >
< / p >
< / div >
< button onclick = "loadRealConfigForFilters()" style = "background-color: #3498db; color: white; padding: 8px 16px; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; margin-bottom: 15px;" >
📥 載入設備配置以設定過濾
< / button >
< span id = "filter-loading-msg" style = "display: none; color: #e67e22; margin-left: 10px; font-weight: bold;" > ⏳ 正在抓取配置,請稍候...< / span >
<!-- 樹狀 Checkbox 容器 -->
< div id = "filter-checkboxes" style = "margin: 15px 0; border: 1px solid #bdc3c7; padding: 15px; border-radius: 5px; background-color: #ffffff; overflow-x: auto; max-height: 500px; overflow-y: auto; display: none;" >
< / div >
< div style = "margin-top: 20px; border-top: 1px solid #ecf0f1; padding-top: 20px;" >
< button onclick = "saveSystemSettings()" style = "background-color: #27ae60; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer; font-size: 15px; font-weight: bold;" >
💾 儲存並套用設定
< / button >
< span id = "settings-status" style = "margin-left: 15px; color: #27ae60; font-weight: bold; display: none;" > ✅ 設定已成功儲存!< / span >
< / div >
< / div >
< / div >
< / div >
2026-04-29 10:00:40 +00:00
<!-- 獨立的彈出式輸出視窗 (Modal) -->
< div id = "outputModal" class = "modal-overlay" onclick = "closeModal(event)" >
< div class = "modal-container" onclick = "event.stopPropagation()" >
< div class = "modal-header" >
< div class = "modal-title" >
< span > 📄 執行結果< / span >
< span id = "modalTargetInfo" style = "font-size: 13px; color: #bdc3c7; font-weight: normal;" > < / span >
< / div >
< button class = "modal-close" onclick = "closeModal()" > × < / button >
< / div >
< div class = "modal-body" >
< pre id = "modalOutput" class = "readonly-terminal" > 等待執行中...< / pre >
< / div >
< / div >
< / div >
2026-04-30 08:27:18 +00:00
<!-- 引入獨立的 JavaScript 邏輯 -->
2026-05-13 03:09:19 +00:00
< script type = "module" src = "/static/app.js" > < / script >
2026-04-30 08:27:18 +00:00
2026-04-29 10:00:40 +00:00
< / body >
< / html >