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:
@@ -1,7 +1,7 @@
|
|||||||
import { get } from 'svelte/store';
|
import { get } from 'svelte/store';
|
||||||
import { api } from '$lib/api/client';
|
import { api } from '$lib/api/client';
|
||||||
import type { Tag, TagOffsetPage } from '$lib/api/types';
|
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
|
// 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
|
// 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;
|
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">
|
<script lang="ts">
|
||||||
import type { Tag } from '$lib/api/types';
|
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 {
|
interface Props {
|
||||||
fileTags: Tag[];
|
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(
|
let filteredAssigned = $derived(
|
||||||
search.trim()
|
search.trim()
|
||||||
? fileTags.filter((t) => t.name?.toLowerCase().includes(search.toLowerCase()))
|
? sortedAssigned.filter((t) => t.name?.toLowerCase().includes(search.toLowerCase()))
|
||||||
: fileTags
|
: sortedAssigned
|
||||||
);
|
);
|
||||||
|
|
||||||
async function handleAdd(tagId: string) {
|
async function handleAdd(tagId: string) {
|
||||||
|
|||||||
Reference in New Issue
Block a user