feat(t135): 庫目錄可自主移除+標示還在不在同步

leo:「需要加移除按鈕。因為別人裝錯我沒辦法幫他弄,需要可以自主」
+「你應該要顯示這個庫沒有本地對應的 folder,那就不容易刪錯」
(兩態非三態——leo 二修:「分兩種沒意義」,那是內部狀態不是用戶分類)。
- DELETE /portal/admin/libraries/:id(登記簿)與 by-name/:name(auto 庫需輸入庫名確認)
- kbdb 加 deprecate-by-library(auto 庫移除=標 deprecated,資料保留可還原)
- daemon/libraries 存 active 清單 → 卡片標 🟢同步中/灰目前沒有在同步
- 不自動刪(daemon 可能沒開機);daemon 從未回報時整列不標
vitest 24 passed(1 紅=console HTML 搬遷陳舊測試,非本案)。
(實作=子 CC;驗證+commit=總管。含 t116/t117 先前未 commit 的 graph-executor/wasi-shim 修正)
This commit is contained in:
uncle6me-web
2026-07-29 14:45:44 +08:00
parent 6d4980d3d7
commit 0860e84d22
11 changed files with 362 additions and 5 deletions
+43
View File
@@ -1558,6 +1558,10 @@ function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return {
if (!adminLibs.length) { $('ad-libs').innerHTML = '<div class="muted" style="padding:16px 4px">同步小幫手還沒送來任何庫。裝好小幫手並選好資料夾後,庫會自動出現在這裡。</div>'; return; }
$('ad-libs').innerHTML = adminLibs.map(function (l) {
var disabled = l.status === 'disabled';
var notWatching = l.daemon_watching === false; // daemon 有報告但此庫不在其中
var removeBtn = l.auto
? '<button class="btn2" style="color:#c0392b;border-color:#e57373;margin-left:auto" data-act="lib-remove-auto" data-name="' + esc(l.name) + '">移除</button>'
: '<button class="btn2" style="color:#c0392b;border-color:#e57373;margin-left:auto" data-act="lib-remove" data-id="' + esc(l.record_id) + '" data-name="' + esc(l.display_name || l.name) + '">移除</button>';
return '<div class="card-item">' +
'<div style="display:flex;align-items:baseline;gap:10px;flex-wrap:wrap">' +
'<span class="serif" style="font-size:17px;font-weight:600">' + esc(l.display_name || l.name) + '</span>' +
@@ -1565,8 +1569,10 @@ function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return {
(l.auto
? '<span class="tag green">啟用中</span><span class="tag">同步自動出現</span>'
: '<span class="tag ' + (disabled ? 'dim' : 'green') + '">' + (disabled ? '已停用' : '啟用中') + '</span>') +
removeBtn +
'</div>' +
(!l.auto && l.description ? '<div style="margin-top:8px;font-size:14.5px;line-height:1.65;color:rgba(var(--ink-rgb),.65)">' + esc(l.description) + '</div>' : '') +
(notWatching ? '<div style="margin-top:6px;font-size:13px;color:rgba(var(--ink-rgb),.45)">小幫手目前沒有在同步這個資料夾</div>' : '') +
'</div>';
}).join('');
}
@@ -1682,6 +1688,43 @@ function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return {
.catch(function (e) { t.disabled = false; toast(friendlyErr(e)); });
return;
}
// 移除已登記庫(有 record_id
if (act === 'lib-remove') {
var libId = t.getAttribute('data-id') || '';
var libName = t.getAttribute('data-name') || libId;
if (!confirm('把「' + libName + '」從目錄移除?\n\n資料不會刪除,重新同步時會再出現。')) return;
t.disabled = true;
adminApi('DELETE', '/portal/admin/libraries/' + encodeURIComponent(libId))
.then(function (x) {
t.disabled = false;
if (guard401(x.status)) return;
if (!x.ok) { toast(x.d.error || ('移除失敗(HTTP ' + x.status + '')); return; }
adminLibs = adminLibs.filter(function (l) { return l.record_id !== libId; });
renderAdminLibs();
toast('已從目錄移除');
})
.catch(function (e) { t.disabled = false; toast(friendlyErr(e)); });
return;
}
// 移除 auto 庫(無 record_identries 標 deprecated
if (act === 'lib-remove-auto') {
var autoName = t.getAttribute('data-name') || '';
var input = window.prompt('移除「' + autoName + '」會讓它的內容不再被搜尋到(資料保留可還原)。\n\n請輸入庫名確認:');
if (input === null) return; // 取消
if (input.trim() !== autoName) { toast('庫名輸入不符,取消移除'); return; }
t.disabled = true;
adminApi('DELETE', '/portal/admin/libraries/by-name/' + encodeURIComponent(autoName), { confirm: autoName })
.then(function (x) {
t.disabled = false;
if (guard401(x.status)) return;
if (!x.ok) { toast(x.d.error || ('移除失敗(HTTP ' + x.status + '')); return; }
adminLibs = adminLibs.filter(function (l) { return l.name !== autoName; });
renderAdminLibs();
toast('已移除(' + (x.d.deprecated_count || 0) + ' 筆標為不可搜)');
})
.catch(function (e) { t.disabled = false; toast(friendlyErr(e)); });
return;
}
});
// 一次性密碼關閉鈕(otpbox 動態生成,掛在容器上)
$('ad-otp').addEventListener('click', function (ev) {