From c4ee51d05d0af71bad3119a6bf9ebe4179bb690e Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Fri, 20 Mar 2026 10:18:12 +0100 Subject: [PATCH] Update README and code to remove folder registration option --- README.md | 2 +- electron/main.cjs | 15 ++------------ electron/preload.cjs | 2 +- src/App.jsx | 32 +++++++++++++++++++++------- src/LibraryManager.jsx | 47 ++++-------------------------------------- 5 files changed, 33 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index 9cfabf1..1edad47 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Heimgeist is a local desktop chat client for Ollama. It combines an Electron + R The `DBs` tab is no longer a placeholder. You can: - create and rename libraries -- register files and folders +- register files - let Heimgeist rebuild retrieval automatically when files change - open or remove registered files from the UI diff --git a/electron/main.cjs b/electron/main.cjs index 9d04f21..038e64d 100644 --- a/electron/main.cjs +++ b/electron/main.cjs @@ -475,20 +475,9 @@ ipcMain.handle('update-settings', (event, settings) => { return true }) -function pickDialogProperties(kind) { - if (kind === 'directories') { - return ['openDirectory', 'multiSelections'] - } - if (kind === 'mixed') { - return ['openFile', 'openDirectory', 'multiSelections'] - } - return ['openFile', 'multiSelections'] -} - -ipcMain.handle('pick-paths', async (event, options = {}) => { - const kind = typeof options?.kind === 'string' ? options.kind : 'files' +ipcMain.handle('pick-paths', async () => { const result = await dialog.showOpenDialog(mainWindow, { - properties: pickDialogProperties(kind), + properties: ['openFile', 'multiSelections'], }) return result.canceled ? [] : result.filePaths }) diff --git a/electron/preload.cjs b/electron/preload.cjs index 2e47ca0..17fb860 100644 --- a/electron/preload.cjs +++ b/electron/preload.cjs @@ -8,7 +8,7 @@ contextBridge.exposeInMainWorld('electronAPI', { checkForUpdates: () => ipcRenderer.invoke('check-for-updates'), setSetting: (key, value) => ipcRenderer.invoke('set-setting', key, value), updateSettings: (settings) => ipcRenderer.invoke('update-settings', settings), - pickPaths: (options = {}) => ipcRenderer.invoke('pick-paths', options), + pickPaths: () => ipcRenderer.invoke('pick-paths'), openPath: (filePath) => ipcRenderer.invoke('open-path', filePath), openExternalLink: (event) => { event.preventDefault(); diff --git a/src/App.jsx b/src/App.jsx index 5addb01..2138a75 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1532,6 +1532,28 @@ async function createNewChat() { }); } + function handleLibraryDelete(slug) { + fetch(`${backendApiUrl}/libraries/${slug}`, { method: 'DELETE' }) + .then(async (response) => { + if (!response.ok) { + const detail = await response.text() + throw new Error(detail || `HTTP ${response.status}`) + } + + const nextLibraries = libraries.filter(library => library.slug !== slug) + setLibraries(nextLibraries) + setLibraryJobs(prevJobs => prevJobs.filter(job => job.slug !== slug)) + setEditingLibrarySlug(current => current === slug ? null : current) + if (activeLibrarySlug === slug) { + setActiveLibrarySlug(nextLibraries[0]?.slug || null) + } + removeLibraryFromChatSelections(slug) + }) + .catch((error) => { + console.error('Failed to delete library', error) + }) + } + // Auto-delete empty "New Chat" sessions useEffect(() => { const emptyNewChats = chatSessions.filter( @@ -1661,6 +1683,9 @@ async function createNewChat() { + )} @@ -1991,13 +2016,6 @@ async function createNewChat() { await refreshLibraries(); await refreshLibraryJobs(); }} - onDeleted={(slug) => { - if (activeLibrarySlug === slug) { - const next = libraries.find(lib => lib.slug !== slug); - setActiveLibrarySlug(next?.slug || null); - } - removeLibraryFromChatSelections(slug) - }} /> )} diff --git a/src/LibraryManager.jsx b/src/LibraryManager.jsx index 0fa9c87..3673d44 100644 --- a/src/LibraryManager.jsx +++ b/src/LibraryManager.jsx @@ -53,11 +53,9 @@ export default function LibraryManager({ apiBase, library, jobs, - onRefresh, - onDeleted + onRefresh }) { const [busy, setBusy] = useState(false) - const [confirmDelete, setConfirmDelete] = useState(false) const [errorMessage, setErrorMessage] = useState('') const [toasts, setToasts] = useState([]) const toastTimeoutsRef = useRef(new Map()) @@ -65,7 +63,6 @@ export default function LibraryManager({ const previousLibraryStateRef = useRef(null) useEffect(() => { - setConfirmDelete(false) setErrorMessage('') }, [library?.slug, library?.name]) @@ -114,7 +111,6 @@ export default function LibraryManager({ try { setErrorMessage('') await fn() - setConfirmDelete(false) } finally { setBusy(false) await onRefresh() @@ -132,9 +128,9 @@ export default function LibraryManager({ }) } - async function addPaths(kind = 'files') { + async function addPaths() { if (!library) return - const paths = await window.electronAPI?.pickPaths?.({ kind }) + const paths = await window.electronAPI?.pickPaths?.() if (!Array.isArray(paths) || paths.length === 0) return try { await registerPaths(paths) @@ -175,15 +171,6 @@ export default function LibraryManager({ } } - async function deleteLibrary() { - if (!library) return - await runAction(async () => { - const response = await fetch(`${apiBase}/libraries/${library.slug}`, { method: 'DELETE' }) - await expectOk(response) - }) - onDeleted?.(library.slug) - } - async function retrySync() { if (!library) return try { @@ -276,22 +263,6 @@ export default function LibraryManager({ return (
- {confirmDelete && ( -
-
Delete "{library.name}"? This removes the registered files and local retrieval data for this database.
-
- - -
-
- )} - {errorMessage &&
{errorMessage}
}
@@ -350,20 +321,10 @@ export default function LibraryManager({
- - + {library.files?.length > 0 && !isSyncing && !isReadyForChat && ( )} -
{toasts.length > 0 && (