diff --git a/static/edit-mode.js b/static/edit-mode.js index f5e5c74..bbba256 100644 --- a/static/edit-mode.js +++ b/static/edit-mode.js @@ -2,7 +2,8 @@ import { apiAcquireLock, apiReleaseLock, apiSendHeartbeat, - apiGetLeafOptions, apiSyncLeafOptions, apiGenerateCli, apiExecuteConfig + apiGetLeafOptions, apiSyncLeafOptions, apiGenerateCli, apiExecuteConfig, + apiSyncLeafOptionsStream // 🌟 新增這一個 } from './api.js'; import { getGlobalConnectionInfo } from './utils.js'; @@ -28,6 +29,7 @@ export let currentEditPath = null; export let currentEditElementId = null; export let currentEditIsSuccess = false; export let currentEditType = null; +export let currentEditDiffs = []; // 🌟 新增:用來記錄這次修改了哪些路徑 export async function releaseAllLocks() { const pathsToRelease = Object.keys(ACTIVE_HEARTBEATS); @@ -310,6 +312,7 @@ export async function previewFolderCLI(path, elementId) { }); if (diffs.length === 0) return alert("沒有偵測到任何修改,無需生成指令!"); + currentEditDiffs = diffs; // 🌟 新增這行:記錄修改差異 try { const result = await apiGenerateCli(diffs, getInterfacesWithAdminState()); @@ -341,6 +344,7 @@ export async function previewLeafCLI(path, elementId) { if (originalVal === newVal) return alert("沒有偵測到任何修改,無需生成指令!"); const diffs = [{ path: path, old_val: originalVal, new_val: newVal }]; + currentEditDiffs = diffs; // 🌟 新增這行:記錄修改差異 try { const result = await apiGenerateCli(diffs, getInterfacesWithAdminState()); @@ -456,15 +460,47 @@ async function executeGeneratedCLI(script) { try { const result = await apiExecuteConfig(script, connInfo.host, connInfo.user, connInfo.pass); - document.getElementById('btn-side-close').style.display = 'inline-block'; + + // 注意:這裡移除了原本直接顯示 btn-side-close 的程式碼,改到後續判斷中顯示 if (result.status === 'success') { currentEditIsSuccess = true; - document.getElementById('side-pane-title').innerHTML = '✅ 執行成功'; - document.getElementById('side-pane-title').style.color = '#2ecc71'; - outputEl.innerHTML = `${result.data}`; + + // 🌟 1. 顯示寫入成功,並提示正在同步 + document.getElementById('side-pane-title').innerHTML = '✅ 寫入成功!正在從設備同步最新狀態...'; + document.getElementById('side-pane-title').style.color = '#f39c12'; + outputEl.innerHTML = `${result.data}\n\n[系統] 正在背景重新抓取變更欄位的最新選項,請稍候...`; + + // 🌟 2. 萃取出需要重新抓取的路徑 (精準打擊) + const pathsToSync = currentEditDiffs.map(d => { + let cacheKey = d.path.replace(/::/g, ' ').replace(/\s*\[\d+\]/g, ''); + if (d.path.endsWith('::no')) cacheKey = cacheKey.replace(/ no$/, '') + ' ' + d.old_val; + return cacheKey; + }); + const uniquePaths = [...new Set(pathsToSync)]; + + // 🌟 3. 呼叫後端爬蟲,去 CMTS 把這幾個欄位的最新狀態拉下來更新 Cache + try { + await apiSyncLeafOptionsStream(uniquePaths, (data) => { + if (data.event === 'done') { + document.getElementById('side-pane-title').innerHTML = '✅ 執行與快取同步完美達成'; + document.getElementById('side-pane-title').style.color = '#2ecc71'; + document.getElementById('btn-side-close').style.display = 'inline-block'; // 同步完成才顯示關閉按鈕 + outputEl.innerHTML += `

[系統] 快取同步完成!您可以關閉此面板。`; + } else if (data.event === 'error') { + document.getElementById('side-pane-title').innerHTML = '✅ 寫入成功 (但同步快取失敗)'; + document.getElementById('side-pane-title').style.color = '#e74c3c'; + document.getElementById('btn-side-close').style.display = 'inline-block'; // 失敗也顯示關閉按鈕 + outputEl.innerHTML += `

[系統] 同步失敗: ${data.message}`; + } + }); + } catch (syncErr) { + document.getElementById('btn-side-close').style.display = 'inline-block'; + } + } else { currentEditIsSuccess = false; + document.getElementById('btn-side-close').style.display = 'inline-block'; document.getElementById('side-pane-title').innerHTML = '❌ 執行失敗'; document.getElementById('side-pane-title').style.color = '#ff6b6b'; const rawLog = result.detail || result.message || '';