feature: Core Digitization Workstation (Entry, Verification, Approval)
CI / backend (push) Successful in 6m11s
CI / frontend (push) Failing after 1m7s

This commit is contained in:
2026-08-12 04:22:25 +08:00
parent 9811f2a2ed
commit 5caf928787
16 changed files with 2077 additions and 905 deletions
@@ -2,45 +2,58 @@
<div class="h-full min-h-0 flex flex-col">
<AppHeader title="Verification">
<template #subtitle>
<span v-if="currentBatch" class="text-sm text-gray-500">
<span v-if="currentBatch" class="text-sm text-ink-secondary">
Batch: {{ currentBatch.id.substring(0, 8) }}...
| Entered by: {{ currentBatch.enteredByUserId?.substring(0, 8) }}...
</span>
</template>
</AppHeader>
<!-- Queue view (no batch selected) -->
<div v-if="!batchId" class="flex-1 p-4 sm:p-6">
<h2 class="text-xl font-semibold mb-4">Verification Queue</h2>
<p class="text-sm text-gray-500 mb-4">
Batches pending verification, sorted by submission time (oldest first).
</p>
<BatchList
:batches="batchStore.batches"
:loading="batchStore.loading"
:error="batchStore.error"
empty-title="No batches are waiting for verification."
empty-description="New batches appear here after data entry is submitted."
@select="openBatch"
@retry="loadQueue"
/>
</div>
<WorkstationLayout :has-batch="!!batchId">
<template #queue>
<h2 class="text-xl font-semibold mb-4 text-ink-strong">Verification Queue</h2>
<p class="text-sm text-ink-secondary mb-4">
Batches pending verification, sorted by submission time (oldest first).
</p>
<BatchList
:batches="batchStore.batches"
:loading="batchStore.loading"
:error="batchStore.error"
empty-title="No batches are waiting for verification."
empty-description="New batches appear here after data entry is submitted."
@select="openBatch"
@retry="loadQueue"
/>
</template>
<!-- Split pane (batch selected) -->
<div v-else class="flex-1 split-pane">
<ScanViewer
v-if="documentUrl"
:url="documentUrl"
/>
<div v-else class="flex items-center justify-center bg-gray-100 rounded-lg">
<p class="text-gray-500">{{ documentError ?? 'Loading document...' }}</p>
</div>
<template #rail>
<WorkstationQueueRail
title="Verification queue"
:batches="batchStore.batches"
:selected-id="batchId"
:loading="batchStore.loading"
@select="openBatch"
@back="router.push('/verification')"
/>
</template>
<VerificationForm
:batch="currentBatch"
:batch-id="batchId"
/>
</div>
<template #scan>
<ScanViewer
:url="documentUrl"
:loading="documentLoading"
:error="documentError"
@retry="refreshUrl"
/>
</template>
<template #form>
<VerificationForm
v-if="batchId"
:batch="currentBatch"
:batch-id="batchId"
/>
</template>
</WorkstationLayout>
</div>
</template>
@@ -53,6 +66,8 @@ import AppHeader from '../components/AppHeader.vue'
import ScanViewer from '../components/ScanViewer.vue'
import VerificationForm from '../components/VerificationForm.vue'
import BatchList from '../components/BatchList.vue'
import WorkstationLayout from '../components/WorkstationLayout.vue'
import WorkstationQueueRail from '../components/WorkstationQueueRail.vue'
const props = defineProps<{ batchId?: string }>()
@@ -62,7 +77,7 @@ const router = useRouter()
const batchId = computed(() => props.batchId ?? (route.params.batchId as string | undefined))
const currentBatch = computed(() => batchStore.currentBatch)
const { documentUrl, documentError } = usePresignedUrl(batchId)
const { documentUrl, documentError, documentLoading, refreshUrl } = usePresignedUrl(batchId)
function openBatch(id: string) {
router.push(`/verification/${id}`)
@@ -87,8 +102,6 @@ watch(
)
onMounted(async () => {
if (!batchId.value) {
await loadQueue()
}
await loadQueue()
})
</script>