fix: SurveyView history reactivity, timer cleanup, accessibility

- Reassign expandedHistory.value to a new Set on toggle so Vue tracks
  the change and template expressions re-evaluate correctly
- Capture saveSuccess setTimeout in a module-level variable; clear it
  on unmount to prevent state mutation after component teardown
- Add role="region" + aria-label to screenshot drop zone div
- Add box-sizing: border-box to .save-input to match .survey-textarea
This commit is contained in:
pyr0ball 2026-03-21 00:31:31 -07:00
parent 4bea0899db
commit 80999b9e7b

View file

@ -20,6 +20,7 @@ if (!jobId || isNaN(jobId)) {
} }
// UI state // UI state
let saveSuccessTimer: ReturnType<typeof setTimeout> | null = null
const activeTab = ref<'text' | 'screenshot'>('text') const activeTab = ref<'text' | 'screenshot'>('text')
const textInput = ref('') const textInput = ref('')
const imageB64 = ref<string | null>(null) const imageB64 = ref<string | null>(null)
@ -48,6 +49,7 @@ onMounted(async () => {
onUnmounted(() => { onUnmounted(() => {
surveyStore.clear() surveyStore.clear()
if (saveSuccessTimer) clearTimeout(saveSuccessTimer)
}) })
// Screenshot handling // Screenshot handling
@ -119,7 +121,8 @@ async function saveToJob() {
saveSuccess.value = true saveSuccess.value = true
surveyName.value = '' surveyName.value = ''
reportedScore.value = '' reportedScore.value = ''
setTimeout(() => { saveSuccess.value = false }, 3000) if (saveSuccessTimer) clearTimeout(saveSuccessTimer)
saveSuccessTimer = setTimeout(() => { saveSuccess.value = false }, 3000)
} }
} }
@ -137,8 +140,10 @@ function formatDate(iso: string | null): string {
} }
const expandedHistory = ref<Set<number>>(new Set()) const expandedHistory = ref<Set<number>>(new Set())
function toggleHistoryEntry(id: number) { function toggleHistoryEntry(id: number) {
if (expandedHistory.value.has(id)) expandedHistory.value.delete(id) const next = new Set(expandedHistory.value)
else expandedHistory.value.add(id) if (next.has(id)) next.delete(id)
else next.add(id)
expandedHistory.value = next
} }
</script> </script>
@ -188,6 +193,8 @@ function toggleHistoryEntry(id: number) {
<div <div
v-else v-else
class="screenshot-zone" class="screenshot-zone"
role="region"
aria-label="Screenshot upload area — paste, drag, or choose file"
@paste="handlePaste" @paste="handlePaste"
@dragover.prevent @dragover.prevent
@drop="handleDrop" @drop="handleDrop"
@ -563,6 +570,7 @@ function toggleHistoryEntry(id: number) {
font-size: 0.875rem; font-size: 0.875rem;
background: var(--color-bg, #fff); background: var(--color-bg, #fff);
color: var(--color-text, #1a202c); color: var(--color-text, #1a202c);
box-sizing: border-box;
} }
.save-btn { .save-btn {