feat(frontend): merge top-bar search with the filter bar, expose kind/created filters

Unify the upstream top-bar search box and the local SearchFilterBar into
one filtering capability sharing a single state store, with the URL as
its projection:

- lib/stores/filter.svelte.ts: module-level $state store, the single
  source of truth; every surface mutates the same proxy in place
- lib/composables/useFilterUrlSync.svelte.ts: one $effect serves both
  directions (URL -> store adoption, store -> URL replaceState write)
  with echo suppression so the loop settles in one round-trip
- FilterFields.svelte: the five selects (type/size/modified/created/
  kind) + recursive switch; word lists and i18n labels live in one
  place; SearchFilterBar reuses it instead of its own copies
- TopBarFilterPanel.svelte: dropdown panel anchored inside the top-bar
  search input (in-field toggle button with active-count badge);
  Escape/outside-click close, no overlay stacking with suggestions
- FilterChips.svelte: dismissible chips on /search, which is now
  URL-driven and loses its three inline <select>s
- New dimensions the backend already supported: kind (file/folder,
  resource_types) and created (created_after); URL keys q/type/size/
  date/created/kind/recursive, non-defaults only, unknown values
  degrade to defaults
- /files keeps in-place filtering (no navigation); folderTarget
  carries filter params through folder entry; ?file= and in/scope
  survive filter writes
- topbar.css: input right padding reserves the three in-field controls

Backend unchanged.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
2026-09-27 15:40:20 +08:00
parent b7640e9be4
commit 29d0c33558
32 changed files with 1445 additions and 284 deletions
+9 -1
View File
@@ -422,7 +422,15 @@
"advanced": "المرشحات",
"recursive": "تضمين المجلدات الفرعية",
"results_count": "{{n}} نتائج",
"clear_keyword": "مسح البحث"
"clear_keyword": "مسح البحث",
"modified_label": "Modified",
"created_label": "Created",
"kind_label": "Items",
"kind": {
"all": "Files and folders",
"file": "Files only",
"folder": "Folders only"
}
},
"files": {
"name": "الاسم",
+9 -1
View File
@@ -422,7 +422,15 @@
"advanced": "Filter",
"recursive": "Unterordner einbeziehen",
"results_count": "{{n}} Ergebnisse",
"clear_keyword": "Suche löschen"
"clear_keyword": "Suche löschen",
"modified_label": "Modified",
"created_label": "Created",
"kind_label": "Items",
"kind": {
"all": "Files and folders",
"file": "Files only",
"folder": "Folders only"
}
},
"files": {
"name": "Name",
+9 -1
View File
@@ -457,7 +457,15 @@
"advanced": "Filters",
"recursive": "Include subfolders",
"results_count": "{{n}} results",
"clear_keyword": "Clear search"
"clear_keyword": "Clear search",
"modified_label": "Modified",
"created_label": "Created",
"kind_label": "Items",
"kind": {
"all": "Files and folders",
"file": "Files only",
"folder": "Folders only"
}
},
"files": {
"name": "Name",
+9 -1
View File
@@ -422,7 +422,15 @@
"advanced": "Filtros",
"recursive": "Incluir subcarpetas",
"results_count": "{{n}} resultados",
"clear_keyword": "Borrar búsqueda"
"clear_keyword": "Borrar búsqueda",
"modified_label": "Modified",
"created_label": "Created",
"kind_label": "Items",
"kind": {
"all": "Files and folders",
"file": "Files only",
"folder": "Folders only"
}
},
"files": {
"name": "Nombre",
+9 -1
View File
@@ -422,7 +422,15 @@
"advanced": "فیلترها",
"recursive": "شامل زیرپوشه‌ها",
"results_count": "{{n}} نتیجه",
"clear_keyword": "پاک کردن جستجو"
"clear_keyword": "پاک کردن جستجو",
"modified_label": "Modified",
"created_label": "Created",
"kind_label": "Items",
"kind": {
"all": "Files and folders",
"file": "Files only",
"folder": "Folders only"
}
},
"files": {
"name": "نام",
+9 -1
View File
@@ -422,7 +422,15 @@
"advanced": "Filtres",
"recursive": "Inclure les sous-dossiers",
"results_count": "{{n}} résultats",
"clear_keyword": "Effacer la recherche"
"clear_keyword": "Effacer la recherche",
"modified_label": "Modified",
"created_label": "Created",
"kind_label": "Items",
"kind": {
"all": "Files and folders",
"file": "Files only",
"folder": "Folders only"
}
},
"files": {
"name": "Nom",
+9 -1
View File
@@ -422,7 +422,15 @@
"advanced": "फ़िल्टर",
"recursive": "सबफ़ोल्डर शामिल करें",
"results_count": "{{n}} परिणाम",
"clear_keyword": "खोज साफ़ करें"
"clear_keyword": "खोज साफ़ करें",
"modified_label": "Modified",
"created_label": "Created",
"kind_label": "Items",
"kind": {
"all": "Files and folders",
"file": "Files only",
"folder": "Folders only"
}
},
"files": {
"name": "नाम",
+9 -1
View File
@@ -422,7 +422,15 @@
"advanced": "Filtri",
"recursive": "Includi sottocartelle",
"results_count": "{{n}} risultati",
"clear_keyword": "Cancella ricerca"
"clear_keyword": "Cancella ricerca",
"modified_label": "Modified",
"created_label": "Created",
"kind_label": "Items",
"kind": {
"all": "Files and folders",
"file": "Files only",
"folder": "Folders only"
}
},
"files": {
"name": "Nome",
+9 -1
View File
@@ -422,7 +422,15 @@
"advanced": "フィルター",
"recursive": "サブフォルダを含める",
"results_count": "{{n}} 件の結果",
"clear_keyword": "検索をクリア"
"clear_keyword": "検索をクリア",
"modified_label": "Modified",
"created_label": "Created",
"kind_label": "Items",
"kind": {
"all": "Files and folders",
"file": "Files only",
"folder": "Folders only"
}
},
"files": {
"name": "名前",
+9 -1
View File
@@ -422,7 +422,15 @@
"advanced": "필터",
"recursive": "하위 폴더 포함",
"results_count": "{{n}}개 결과",
"clear_keyword": "검색 지우기"
"clear_keyword": "검색 지우기",
"modified_label": "Modified",
"created_label": "Created",
"kind_label": "Items",
"kind": {
"all": "Files and folders",
"file": "Files only",
"folder": "Folders only"
}
},
"files": {
"name": "이름",
+9 -1
View File
@@ -422,7 +422,15 @@
"advanced": "Filters",
"recursive": "Submappen opnemen",
"results_count": "{{n}} resultaten",
"clear_keyword": "Zoekopdracht wissen"
"clear_keyword": "Zoekopdracht wissen",
"modified_label": "Modified",
"created_label": "Created",
"kind_label": "Items",
"kind": {
"all": "Files and folders",
"file": "Files only",
"folder": "Folders only"
}
},
"files": {
"name": "Naam",
+9 -1
View File
@@ -422,7 +422,15 @@
"advanced": "Filtry",
"recursive": "Uwzględnij podfoldery",
"results_count": "Wyniki: {{n}}",
"clear_keyword": "Wyczyść wyszukiwanie"
"clear_keyword": "Wyczyść wyszukiwanie",
"modified_label": "Modified",
"created_label": "Created",
"kind_label": "Items",
"kind": {
"all": "Files and folders",
"file": "Files only",
"folder": "Folders only"
}
},
"files": {
"name": "Nazwa",
+9 -1
View File
@@ -422,7 +422,15 @@
"advanced": "Filtros",
"recursive": "Incluir subpastas",
"results_count": "{{n}} resultados",
"clear_keyword": "Limpar pesquisa"
"clear_keyword": "Limpar pesquisa",
"modified_label": "Modified",
"created_label": "Created",
"kind_label": "Items",
"kind": {
"all": "Files and folders",
"file": "Files only",
"folder": "Folders only"
}
},
"files": {
"name": "Nome",
+9 -1
View File
@@ -422,7 +422,15 @@
"advanced": "Фильтры",
"recursive": "Включая подпапки",
"results_count": "Результатов: {{n}}",
"clear_keyword": "Очистить поиск"
"clear_keyword": "Очистить поиск",
"modified_label": "Modified",
"created_label": "Created",
"kind_label": "Items",
"kind": {
"all": "Files and folders",
"file": "Files only",
"folder": "Folders only"
}
},
"files": {
"name": "Имя",
+9 -1
View File
@@ -422,7 +422,15 @@
"advanced": "篩選",
"recursive": "包含子資料夾",
"results_count": "{{n}} 個結果",
"clear_keyword": "清除搜尋"
"clear_keyword": "清除搜尋",
"modified_label": "修改時間",
"created_label": "建立時間",
"kind_label": "項目",
"kind": {
"all": "檔案與資料夾",
"file": "僅檔案",
"folder": "僅資料夾"
}
},
"files": {
"name": "名稱",
+9 -1
View File
@@ -422,7 +422,15 @@
"advanced": "筛选",
"recursive": "包含子文件夹",
"results_count": "{{n}} 个结果",
"clear_keyword": "清除搜索"
"clear_keyword": "清除搜索",
"modified_label": "修改时间",
"created_label": "创建时间",
"kind_label": "条目",
"kind": {
"all": "文件和文件夹",
"file": "仅文件",
"folder": "仅文件夹"
}
},
"files": {
"name": "名称",