fix: Replay controls

This commit is contained in:
voltsrage
2026-06-20 14:41:11 +08:00
parent 584d1edd58
commit 7cfc5567fd
9 changed files with 291 additions and 73 deletions
@@ -1,5 +1,6 @@
<script setup>
import { storeToRefs } from 'pinia'
import { computed } from 'vue'
import { useAlertStore } from '@/stores/alerts'
import { useSettingsStore } from '@/stores/settings'
import { usePolling } from '@/composables/usePolling'
@@ -20,11 +21,15 @@ const alertStore = useAlertStore()
const settings = useSettingsStore()
const { alerts, loading } = storeToRefs(alertStore)
function loadOpenAlerts() {
return alertStore.loadAlerts(props.encounterId, 'OPEN')
function loadEncounterAlerts() {
return alertStore.loadAlerts(props.encounterId)
}
usePolling(loadOpenAlerts, 5_000)
usePolling(loadEncounterAlerts, 5_000)
const visibleAlerts = computed(() =>
alerts.value.filter(a => a.status !== 'Resolved'),
)
function severityVariant(severity) {
return severity === 'Critical' ? 'critical' : 'warning'
@@ -32,12 +37,12 @@ function severityVariant(severity) {
async function acknowledge(alertId) {
await alertStore.acknowledge(alertId, settings.clinicianId)
await loadOpenAlerts()
await loadEncounterAlerts()
}
async function resolve(alertId) {
await alertStore.resolve(alertId)
await loadOpenAlerts()
await loadEncounterAlerts()
}
</script>
@@ -49,10 +54,11 @@ async function resolve(alertId) {
</h2>
</template>
<EmptyState v-if="!loading && alerts.length === 0" message="No open alerts" />
<EmptyState v-if="!loading && visibleAlerts.length === 0" message="No open alerts" />
<ul v-else class="divide-y divide-gray-200 dark:divide-gray-700">
<li
v-for="alert in alerts"
v-for="alert in visibleAlerts"
:id="`alert-row-${alert.id}`"
:key="alert.id"
class="flex cursor-pointer flex-col gap-4 py-4 first:pt-0 last:pb-0 sm:flex-row sm:items-start sm:justify-between"
:class="selectedId === alert.id ? 'bg-blue-50/50 dark:bg-blue-950/20' : ''"
@@ -1,11 +1,15 @@
<script setup>
import { useReplayControls } from '@/composables/useReplayControls'
import Button from '@/components/ui/Button.vue'
const { isPaused, speed, progress, formattedTime, pause, resume, setSpeed } = useReplayControls()
defineProps({
alerts: { type: Array, default: () => [] },
isPaused: { type: Boolean, required: true },
progress: { type: Number, required: true },
formattedTime: { type: String, required: true },
speed: { type: Number, required: true },
})
defineProps({ alerts: { type: Array, default: () => [] } })
const emit = defineEmits(['jump-to-alert'])
const emit = defineEmits(['jump-to-alert', 'pause', 'resume', 'set-speed'])
const speedPresets = [
{ label: '1×', value: 1 },
@@ -17,15 +21,17 @@ const speedPresets = [
<template>
<div class="flex w-full min-w-0 flex-col gap-4 rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-700 dark:bg-gray-900 sm:flex-row sm:items-center">
<Button variant="ghost" size="sm" @click="isPaused ? resume() : pause()">
<Button variant="ghost" size="sm" @click="isPaused ? emit('resume') : emit('pause')">
<span class="sr-only">{{ isPaused ? 'Resume' : 'Pause' }}</span>
{{ isPaused ? '▶' : '⏸' }}
</Button>
<div class="min-w-0 flex-1">
<div class="h-2 overflow-hidden rounded-full bg-gray-200 dark:bg-gray-700">
<div class="h-full rounded-full bg-blue-500 transition-all duration-300"
:style="{ width: `${progress}%` }" />
<div
class="h-full rounded-full bg-blue-500 transition-all duration-300"
:style="{ width: `${progress}%` }"
/>
</div>
</div>
@@ -41,16 +47,16 @@ const speedPresets = [
:class="speed === preset.value
? 'bg-blue-500 text-white'
: 'bg-gray-100 text-gray-600 hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-400'"
@click="setSpeed(preset.value)"
@click="emit('set-speed', preset.value)"
>
{{ preset.label }}
</button>
</div>
<div v-if="alerts.length" class="border-t border-gray-200 pt-4 sm:border-t-0 sm:border-l sm:pl-4 sm:pt-0 dark:border-gray-700">
<Button variant="ghost" size="sm" @click="$emit('jump-to-alert')">
<Button variant="ghost" size="sm" @click="emit('jump-to-alert')">
Next Alert &rarr;
</Button>
</div>
</div>
</template>
</template>