feat(bulk-edit): add canWrite-gated row checkboxes on /documents and /enrich
Each row in the document search list and the enrichment queue gets a WCAG-compliant (44px touch target) checkbox bound to bulkSelectionStore. Checkbox click does not trigger the row's stretched-link navigation — it sits inside the z-10 content sibling, the link is in the z-0 sibling, so click events do not bubble between them. Refs #225 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -119,7 +119,7 @@ function groupByReceiver(docItems: DocumentSearchItem[]) {
|
||||
</div>
|
||||
<ul class="divide-y divide-line">
|
||||
{#each group.items as item (group.label + '-' + item.document.id)}
|
||||
<DocumentRow item={item} />
|
||||
<DocumentRow item={item} canWrite={canWrite} />
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -19,5 +19,5 @@ export async function load({
|
||||
|
||||
const documents = result.response.ok ? (result.data ?? []) : [];
|
||||
|
||||
return { documents };
|
||||
return { documents, canWrite };
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { m } from '$lib/paraglide/messages.js';
|
||||
import BackButton from '$lib/components/BackButton.svelte';
|
||||
import { bulkSelectionStore } from '$lib/stores/bulkSelection.svelte';
|
||||
|
||||
let { data } = $props();
|
||||
|
||||
const documents = $derived(data.documents);
|
||||
const count = $derived(documents.length);
|
||||
const canWrite = $derived(data.canWrite);
|
||||
</script>
|
||||
|
||||
<div class="mx-auto max-w-4xl px-4 py-10">
|
||||
@@ -61,8 +63,24 @@ const count = $derived(documents.length);
|
||||
<div class="border border-line bg-surface shadow-sm">
|
||||
<ul class="divide-y divide-line-2">
|
||||
{#each documents as doc (doc.id)}
|
||||
<li class="group transition-colors duration-200 hover:bg-muted">
|
||||
<a href="/enrich/{doc.id}" class="flex items-center justify-between p-6">
|
||||
<li class="group relative transition-colors duration-200 hover:bg-muted">
|
||||
<a href="/enrich/{doc.id}" class="absolute inset-0 z-0 block" aria-label={doc.title}
|
||||
></a>
|
||||
<div class="pointer-events-none relative z-10 flex items-center justify-between p-6">
|
||||
{#if canWrite}
|
||||
<label
|
||||
class="pointer-events-auto mr-4 flex min-h-[44px] min-w-[44px] flex-shrink-0 cursor-pointer items-center"
|
||||
data-testid="bulk-select-checkbox"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="h-5 w-5 cursor-pointer accent-brand-navy"
|
||||
checked={bulkSelectionStore.has(doc.id)}
|
||||
onchange={() => bulkSelectionStore.toggle(doc.id)}
|
||||
aria-label={m.bulk_edit_select_document({ title: doc.title })}
|
||||
/>
|
||||
</label>
|
||||
{/if}
|
||||
<div class="min-w-0 flex-1">
|
||||
<p class="font-serif text-lg font-medium text-ink group-hover:underline">
|
||||
{doc.title}
|
||||
@@ -74,7 +92,7 @@ const count = $derived(documents.length);
|
||||
aria-hidden="true"
|
||||
class="ml-4 h-5 w-5 shrink-0 opacity-30 transition-opacity group-hover:opacity-70"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user