diff --git a/frontend/src/lib/api/tags.ts b/frontend/src/lib/api/tags.ts index 26245c4..85e9c22 100644 --- a/frontend/src/lib/api/tags.ts +++ b/frontend/src/lib/api/tags.ts @@ -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 { } 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): Tag[] { + const dir = order === 'asc' ? 1 : -1; + return [...tags].sort((a, b) => dir * tagSortKey(a, sort).localeCompare(tagSortKey(b, sort))); +} diff --git a/frontend/src/lib/components/file/TagPicker.svelte b/frontend/src/lib/components/file/TagPicker.svelte index 88e047d..32eb667 100644 --- a/frontend/src/lib/components/file/TagPicker.svelte +++ b/frontend/src/lib/components/file/TagPicker.svelte @@ -1,6 +1,7 @@