feat: virtualized tag manager with filter, sort, and light-theme support

Replaces the flat TagManageRow list with a virtualized grid of
TagManageTile cards using @tanstack/react-virtual and dynamic measured
heights (46px idle, 82px when editing/confirming). Adds a filter input
and a sort dropdown (most-used / least-used / A-Z / Z-A). renameTag and
deleteTag no longer clear exploreTagEntries on invalidation so the
manager keeps its filter/sort state during the background refresh.
Light-theme overrides cover all new tag-manager class names.
This commit is contained in:
2026-06-29 16:29:12 +01:00
parent 9144be2518
commit af3c8418ee
4 changed files with 312 additions and 49 deletions
+4 -2
View File
@@ -2370,9 +2370,10 @@ export const useGalleryStore = create<GalleryState>((set, get) => ({
renameTag: async (from, to) => {
await invoke("rename_tag", { params: { from, to } });
// Tag content changed — invalidate the explore-tags and tag-cloud caches.
// Keep the current tag list visible while the refresh runs so manager UI
// state such as filtering and sorting is not lost to a loading remount.
set({
exploreTagsFolderId: undefined,
exploreTagEntries: [],
tagCloudFolderId: undefined,
tagCloudEntries: [],
});
@@ -2388,9 +2389,10 @@ export const useGalleryStore = create<GalleryState>((set, get) => ({
deleteTag: async (tag) => {
const removed = await invoke<number>("delete_tag", { params: { tag } });
// Keep the current tag list visible while the refresh runs so manager UI
// state such as filtering and sorting is not lost to a loading remount.
set({
exploreTagsFolderId: undefined,
exploreTagEntries: [],
tagCloudFolderId: undefined,
tagCloudEntries: [],
});