fix: a11y — QuickCapture label/role/aria-live/spinner, LogEntryRow expand button
This commit is contained in:
parent
f361c86019
commit
04f26e4074
2 changed files with 24 additions and 13 deletions
|
|
@ -1,8 +1,7 @@
|
|||
<template>
|
||||
<div
|
||||
class="border-b border-surface-border px-4 py-3 hover:bg-surface-raised transition-colors"
|
||||
:class="{ 'border-l-2 border-l-sev-error': isHighSeverity, 'cursor-pointer': isLong }"
|
||||
@click="isLong && (expanded = !expanded)"
|
||||
:class="{ 'border-l-2 border-l-sev-error': isHighSeverity }"
|
||||
>
|
||||
<div class="flex items-start gap-3">
|
||||
<SeverityBadge :severity="entry.severity" class="mt-0.5 shrink-0 w-16 text-center" />
|
||||
|
|
@ -18,14 +17,20 @@
|
|||
<span v-if="entry.repeat_count > 1" class="text-text-dim text-xs">×{{ entry.repeat_count }}</span>
|
||||
</div>
|
||||
<p
|
||||
:id="`entry-text-${entry.entry_id}`"
|
||||
class="text-text-primary text-sm whitespace-pre-wrap break-words leading-relaxed"
|
||||
:class="{ 'line-clamp-3': isLong && !expanded }"
|
||||
>{{ entry.text }}</p>
|
||||
<button
|
||||
v-if="isLong"
|
||||
@click="expanded = !expanded"
|
||||
:aria-expanded="expanded"
|
||||
:aria-controls="`entry-text-${entry.entry_id}`"
|
||||
class="mt-1 text-text-dim hover:text-accent text-xs transition-colors"
|
||||
@click.stop="expanded = !expanded"
|
||||
>{{ expanded ? '▲ collapse' : '▼ expand' }}</button>
|
||||
>
|
||||
<span aria-hidden="true">{{ expanded ? '▲' : '▼' }}</span>
|
||||
{{ expanded ? 'Collapse entry' : 'Expand entry' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
<div>
|
||||
<!-- Input row -->
|
||||
<div class="flex gap-3 mb-6">
|
||||
<label for="qc-query" class="sr-only">Describe the symptom or issue</label>
|
||||
<input
|
||||
id="qc-query"
|
||||
v-model="query"
|
||||
type="text"
|
||||
placeholder='e.g. "plex stopped playing audio around 2pm"'
|
||||
|
|
@ -14,18 +16,20 @@
|
|||
@click="run()"
|
||||
class="px-6 py-2.5 rounded bg-accent text-white text-sm font-semibold hover:bg-blue-400 transition-colors disabled:opacity-50"
|
||||
>
|
||||
<span v-if="loading">Go</span>
|
||||
<span v-else>Go</span>
|
||||
<span v-if="loading">Searching…</span>
|
||||
<span v-else>Search logs</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Pipeline status -->
|
||||
<div
|
||||
v-if="loading && statusMsg"
|
||||
class="flex items-center gap-2 mb-3 text-xs text-text-dim"
|
||||
>
|
||||
<span class="inline-block w-3 h-3 rounded-full border-2 border-accent border-t-transparent animate-spin" />
|
||||
<span>{{ statusMsg }}</span>
|
||||
<div aria-live="polite" aria-atomic="true">
|
||||
<div
|
||||
v-if="loading && statusMsg"
|
||||
class="flex items-center gap-2 mb-3 text-xs text-text-dim"
|
||||
>
|
||||
<span class="inline-block w-3 h-3 rounded-full border-2 border-accent border-t-transparent animate-spin motion-reduce:animate-none" aria-hidden="true" />
|
||||
<span>{{ statusMsg }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Source scope badge -->
|
||||
|
|
@ -36,11 +40,12 @@
|
|||
@click="sourceScope = null"
|
||||
class="text-text-dim hover:text-text-primary ml-1"
|
||||
title="Clear scope"
|
||||
aria-label="Clear source scope filter"
|
||||
>✕</button>
|
||||
</div>
|
||||
|
||||
<!-- Error -->
|
||||
<div v-if="error" class="mb-4 p-3 rounded bg-red-900/30 border border-red-700/40 text-sev-error text-sm">
|
||||
<div v-if="error" role="alert" class="mb-4 p-3 rounded bg-red-900/30 border border-red-700/40 text-sev-error text-sm">
|
||||
{{ error }}
|
||||
</div>
|
||||
|
||||
|
|
@ -61,6 +66,7 @@
|
|||
v-for="(count, sev) in nonZeroSeverity"
|
||||
:key="String(sev)"
|
||||
@click="severityFilter = severityFilter === String(sev) ? null : String(sev)"
|
||||
:aria-pressed="severityFilter === String(sev)"
|
||||
:class="[
|
||||
'px-2 py-0.5 rounded text-xs font-medium border transition-colors',
|
||||
severityFilter === String(sev)
|
||||
|
|
|
|||
Loading…
Reference in a new issue