From 4851f54595d39a1e66a4e97172b77566af3d54e8 Mon Sep 17 00:00:00 2001 From: maziggy Date: Fri, 5 Jun 2026 10:11:03 +0200 Subject: [PATCH] feat(file-manager): split "All Files" into internal-only + External views (#1621) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reporter linked a NAS and the auto-imported files drowned their own Bambuddy uploads in the "All Files" sidebar listing. There was no filter to escape it — only per-folder clicks. Restore the pre-external semantics: "All Files" now lists managed-storage files only. The combined across-every-external view moves to a new sibling sidebar entry, "External", that only appears when at least one external folder is linked. Backend: GET /api/v1/library/files gains internal_only and external_only query flags. Filter is on LibraryFile.is_external. Both flags set is a 400, not a silent pick-one. Frontend: new topLevelView state on FileManagerPage (default internal); the query passes the scope only when selectedFolderId is null. Mobile selector dropdown uses __top:internal / __top:external sentinels so the same state round-trips through option values. Empty-state copy distinguishes internal-empty from external-empty. --- CHANGELOG.md | 3 + backend/app/api/routes/library.py | 19 ++ backend/tests/integration/test_library_api.py | 46 +++++ .../__tests__/pages/FileManagerPage.test.tsx | 91 +++++++++ frontend/src/api/client.ts | 9 +- frontend/src/i18n/locales/de.ts | 3 + frontend/src/i18n/locales/en.ts | 3 + frontend/src/i18n/locales/es.ts | 3 + frontend/src/i18n/locales/fr.ts | 3 + frontend/src/i18n/locales/it.ts | 3 + frontend/src/i18n/locales/ja.ts | 3 + frontend/src/i18n/locales/ko.ts | 3 + frontend/src/i18n/locales/pt-BR.ts | 3 + frontend/src/i18n/locales/tr.ts | 3 + frontend/src/i18n/locales/zh-CN.ts | 3 + frontend/src/i18n/locales/zh-TW.ts | 3 + frontend/src/pages/FileManagerPage.tsx | 81 ++++++-- .../{index-C7bMJs5u.js => index-DrAXd6Gv.js} | 188 +++++++++--------- static/index.html | 2 +- 19 files changed, 363 insertions(+), 109 deletions(-) rename static/assets/{index-C7bMJs5u.js => index-DrAXd6Gv.js} (82%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 355cd922f..577fee919 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes to Bambuddy will be documented in this file. ## [0.2.5b1] - Unreleased +### Changed +- **File Manager sidebar: "All Files" now scopes to your own uploaded files; new "External" entry holds the combined linked-folder view (#1621, reported by @kcw96)** — Reporter linked a NAS share that auto-imported hundreds of 3MFs, and from then on their handful of Bambuddy-uploaded files was lost in the "All Files" listing — no filter, no toggle, only per-folder clicks to escape the noise. Restored the pre-external semantics so long-time users get their muscle memory back: "All Files" lists managed-storage files only (`is_external=False`), exactly what it meant before external folders existed. The combined "everything across every external mount" view moves to a new sibling sidebar entry, **External**, which only renders when at least one external folder is linked (zero-cost on installs that don't use the feature). Per-folder clicking is unchanged: clicking any folder in the tree — internal or external — still shows that folder's contents directly. **Backend**: `/api/v1/library/files` gains two mutually-exclusive query flags, `internal_only` and `external_only`, filtering directly on `LibraryFile.is_external`. Both-flags-set is a 400 (catches frontend regressions immediately instead of silently picking one). Folder- or project-scoped requests bypass both flags because they already imply a single scope. **Frontend**: new `topLevelView: 'internal' | 'external'` state on `FileManagerPage`, default `internal`; the query passes the corresponding scope only when `selectedFolderId === null`. Sidebar shows the "External" row gated on `folders.some(f => f.is_external)`; mobile selector dropdown carries a `__top:internal` / `__top:external` sentinel so the same state can round-trip through `