Implement reactive sorting for IDAA Archives

- Forced priority archives to the top of the list.
- Implemented descending (DESC) sort by the 'sort' field within groups.
- Added a sort selector to the archive list component.
- Centralized sorting logic in-memory within LiveQuery for immediate reactivity.
This commit is contained in:
Scott Idem
2026-02-08 18:12:54 -05:00
parent 84cfed97ca
commit f84d6b638d
2 changed files with 58 additions and 11 deletions

View File

@@ -44,17 +44,26 @@
let lq__archive_obj_li = $derived(
liveQuery(async () => {
let results = await db_archives.archive
const results = await db_archives.archive
.where('account_id')
.equals($slct.account_id)
// .orderBy('updated_on')
// .toArray()
// .reverse() // Removed reverse: sortBy('sort') already provides the correct 1, 2, 3... order
.sortBy('sort');
// .sortBy('updated_on');
// .sortBy('updated_on, created_on');
// .sortBy('[updated_on+created_on]');
// .sortBy('[created_on+updated_on]');
.toArray();
// In-memory sort: Priority (desc) then Sort (desc)
results.sort((a, b) => {
// Priority: True (1) before False (0)
const prioA = a.priority ? 1 : 0;
const prioB = b.priority ? 1 : 0;
if (prioA !== prioB) return prioB - prioA;
// Sort: 9, 8, 7...
const sortA = a.sort ?? 0;
const sortB = b.sort ?? 0;
if (sortA !== sortB) return sortB - sortA;
// Fallback: Name
return (a.name ?? '').localeCompare(b.name ?? '');
});
return results;
})

View File

@@ -25,6 +25,35 @@
}
let { lq__archive_obj_li }: Props = $props();
// Local Sort State
let qry_sort_mode = $state('priority_sort'); // 'priority_sort', 'updated_desc', 'name_asc'
let sorted_archive_obj_li = $derived.by(() => {
const list = [...($lq__archive_obj_li ?? [])];
if (!list.length) return [];
list.sort((a, b) => {
if (qry_sort_mode === 'priority_sort') {
const prioA = a.priority ? 1 : 0;
const prioB = b.priority ? 1 : 0;
if (prioA !== prioB) return prioB - prioA;
const sortA = a.sort ?? 0;
const sortB = b.sort ?? 0;
if (sortA !== sortB) return sortB - sortA;
} else if (qry_sort_mode === 'updated_desc') {
const dateA = new Date(a.updated_on || a.created_on).getTime();
const dateB = new Date(b.updated_on || b.created_on).getTime();
return dateB - dateA;
}
// Default fallback: Name
return (a.name ?? '').localeCompare(b.name ?? '');
});
return list;
});
</script>
<section
@@ -33,8 +62,17 @@
flex flex-col gap-2 items-center justify-center w-full
"
>
{#if $lq__archive_obj_li && $lq__archive_obj_li.length}
{#each $lq__archive_obj_li as idaa_archive_obj, index}
<div class="w-full max-w-(--breakpoint-lg) flex flex-row items-center justify-end px-2 mb-2 gap-2">
<span class="text-xs font-bold opacity-50 uppercase tracking-widest">Sort By:</span>
<select bind:value={qry_sort_mode} class="select variant-filled-surface rounded-lg text-sm border border-surface-500/20 p-1 w-fit">
<option value="priority_sort">Priority & Order</option>
<option value="name_asc">Name (A-Z)</option>
<option value="updated_desc">Recently Updated</option>
</select>
</div>
{#if sorted_archive_obj_li && sorted_archive_obj_li.length}
{#each sorted_archive_obj_li as idaa_archive_obj, index}
<div
class="container archive archive_obj border rounded p-2 mb-2 space-y-2 w-full max-w-(--breakpoint-lg) flex flex-col items-center justify-center"
class:hidden={(idaa_archive_obj?.hide ||