fix(frontend): sort a file's assigned tags by the chosen tag order

The file viewer's assigned-tags list showed tags in API order, ignoring the
sort the user picked on the tags page. Add a client-side sortTags helper and
order the assigned list (in TagPicker) by tagSorting, reactively so it re-sorts
the moment the sort changes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-11 14:22:23 +03:00
parent 88a8cac048
commit 8f213e780c
2 changed files with 36 additions and 4 deletions
+29 -1
View File
@@ -1,7 +1,7 @@
import { get } from 'svelte/store';
import { api } from '$lib/api/client';
import type { Tag, TagOffsetPage } from '$lib/api/types';
import { tagSorting } from '$lib/stores/sorting';
import { tagSorting, type SortState, type TagSortField } from '$lib/stores/sorting';
// The /tags endpoint caps limit at 200 per request. Pickers and the filter bar
// filter the tag list client-side, so they need the *whole* list — otherwise
@@ -28,3 +28,31 @@ export async function fetchAllTags(): Promise<Tag[]> {
}
return all;
}
// Field a tag is keyed on for a given sort choice. created_at is an ISO string,
// so lexical comparison matches chronological order.
function tagSortKey(t: Tag, field: TagSortField): string {
switch (field) {
case 'name':
return t.name ?? '';
case 'color':
return t.color ?? '';
case 'category_name':
return t.category_name ?? '';
case 'created':
return t.created_at ?? '';
default:
return '';
}
}
/**
* Returns a copy of `tags` sorted by the given tag sort state — used to order a
* file's already-assigned tags the same way as the tags page and the pickers'
* available list (which the server sorts). Client-side so it reacts instantly
* when the user changes the sort.
*/
export function sortTags(tags: Tag[], { sort, order }: SortState<TagSortField>): Tag[] {
const dir = order === 'asc' ? 1 : -1;
return [...tags].sort((a, b) => dir * tagSortKey(a, sort).localeCompare(tagSortKey(b, sort)));
}
@@ -1,6 +1,7 @@
<script lang="ts">
import type { Tag } from '$lib/api/types';
import { fetchAllTags } from '$lib/api/tags';
import { fetchAllTags, sortTags } from '$lib/api/tags';
import { tagSorting } from '$lib/stores/sorting';
interface Props {
fileTags: Tag[];
@@ -30,10 +31,13 @@
)
);
// Show a file's already-assigned tags in the user's chosen tag order too.
let sortedAssigned = $derived(sortTags(fileTags, $tagSorting));
let filteredAssigned = $derived(
search.trim()
? fileTags.filter((t) => t.name?.toLowerCase().includes(search.toLowerCase()))
: fileTags
? sortedAssigned.filter((t) => t.name?.toLowerCase().includes(search.toLowerCase()))
: sortedAssigned
);
async function handleAdd(tagId: string) {