feat: gestion desktop des vaults & dossiers — retrait par menu contextuel et ajout en configuration #159
This commit is contained in:
@@ -7,6 +7,7 @@ import { escapeHtml, safeCreateIcons } from './utils.js';
|
||||
import { showToast, closeHeaderMenu, closeMobileSidebar } from './ui.js';
|
||||
import { t, setLocale, getLocale } from './i18n.js';
|
||||
import { getModelCapabilities, renderCapabilityBadges, refreshAIPickers } from './ai.js';
|
||||
import { isTauriEnv, invoke, pickAndAddVault, pickAndAddDir, removeRoot } from './desktop.js';
|
||||
|
||||
let _recentTimestampTimer = null;
|
||||
let _recentFilesCache = [];
|
||||
@@ -776,6 +777,49 @@ function closeHelpModal() {
|
||||
if (modal) modal.classList.remove("active");
|
||||
}
|
||||
|
||||
// ── Vaults & root directories — desktop only (#159) ──────────────────────
|
||||
// Lists the roots the Tauri shell injects into the backend (vaults +
|
||||
// directories) and offers add/remove. The whole section — including its TOC
|
||||
// entry — is hidden outside the desktop app.
|
||||
async function renderDesktopRoots() {
|
||||
const section = document.getElementById("cfg-desktop-roots");
|
||||
const navLink = document.querySelector('#config-nav a[href="#cfg-desktop-roots"]');
|
||||
if (!section) return;
|
||||
if (!isTauriEnv()) {
|
||||
section.style.display = "none";
|
||||
if (navLink && navLink.parentElement) navLink.parentElement.style.display = "none";
|
||||
return;
|
||||
}
|
||||
section.style.display = "";
|
||||
if (navLink && navLink.parentElement) navLink.parentElement.style.display = "";
|
||||
const vaults = (await invoke("list_vaults")) || [];
|
||||
const dirs = (await invoke("list_dirs")) || [];
|
||||
const list = document.getElementById("desktop-roots-list");
|
||||
if (!list) return;
|
||||
const row = (name, path, kind) =>
|
||||
'<div class="hidden-files-vault-card" style="display:flex;align-items:center;gap:10px;margin-bottom:8px">' +
|
||||
'<i data-lucide="' + (kind === "vault" ? "vault" : "folder") + '" style="width:16px;flex-shrink:0"></i>' +
|
||||
'<div style="flex:1;min-width:0"><div style="font-weight:600">' + escapeHtml(name) + "</div>" +
|
||||
'<div style="font-size:12px;color:var(--text-muted);overflow:hidden;text-overflow:ellipsis">' + escapeHtml(path) + "</div></div>" +
|
||||
'<button class="config-btn-save" data-root="' + escapeHtml(name) + '" style="padding:4px 10px;font-size:12px;white-space:nowrap">' +
|
||||
'<i data-lucide="folder-minus" style="width:14px;vertical-align:-2px"></i> ' + escapeHtml(t("desktop.remove_root")) + "</button></div>";
|
||||
if (!vaults.length && !dirs.length) {
|
||||
list.innerHTML = '<div style="padding:12px;color:var(--text-muted)">' + escapeHtml(t("desktop.roots_empty")) + "</div>";
|
||||
} else {
|
||||
list.innerHTML = vaults.map((v) => row(v.name, v.path, "vault")).join("") +
|
||||
dirs.map((d) => row(d.name, d.path, "dir")).join("");
|
||||
for (const btn of list.querySelectorAll("button[data-root]")) {
|
||||
// onclick (not addEventListener): the modal re-renders on every open.
|
||||
btn.onclick = () => removeRoot(btn.dataset.root, t("desktop.remove_root_confirm", { name: btn.dataset.root }));
|
||||
}
|
||||
}
|
||||
const addVaultBtn = document.getElementById("cfg-desktop-add-vault");
|
||||
const addDirBtn = document.getElementById("cfg-desktop-add-dir");
|
||||
if (addVaultBtn) addVaultBtn.onclick = () => pickAndAddVault();
|
||||
if (addDirBtn) addDirBtn.onclick = () => pickAndAddDir();
|
||||
safeCreateIcons();
|
||||
}
|
||||
|
||||
function initConfigModal() {
|
||||
const openBtn = document.getElementById("config-open-btn");
|
||||
const closeBtn = document.getElementById("config-close");
|
||||
@@ -806,6 +850,7 @@ function initConfigModal() {
|
||||
loadTokensUI();
|
||||
loadSharesUI();
|
||||
loadToolKeys();
|
||||
renderDesktopRoots();
|
||||
safeCreateIcons();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user