fix(frontend): harden the streaming ui and extract copy and constants
Some checks are pending
ci / backend (push) Waiting to run
ci / frontend (push) Waiting to run

This commit is contained in:
Justin Visser 2026-08-10 15:42:18 +02:00
parent 036ef3cc6f
commit a3af8f45cc
36 changed files with 1662 additions and 226 deletions

View file

@ -1,29 +1,52 @@
<script setup lang="ts">
import { computed } from 'vue'
import { messages } from '../lib/messages'
import type { AppMode, AuthState } from '../lib/models'
import AuthStatus from './AuthStatus.vue'
defineProps<{
const props = defineProps<{
auth: AuthState
mode: AppMode | null
healthFailed: boolean
}>()
defineEmits<{ logout: []; toggleDev: [] }>()
const emit = defineEmits<{ logout: []; toggleDev: [opener: HTMLElement] }>()
function openDevPanel(event: MouseEvent): void {
if (event.currentTarget instanceof HTMLElement) {
emit('toggleDev', event.currentTarget)
}
}
const modeLabel = computed(() => {
if (props.mode === 'demo') return messages.appHeaderDemoMode
if (props.mode === 'live') return messages.appHeaderLiveMode
if (props.healthFailed) return messages.appHeaderModeUnavailable
return messages.appHeaderCheckingMode
})
</script>
<template>
<header class="header">
<div class="inner">
<div class="brand">
<span class="wordmark">discovery<span class="accent">-by-</span>llm</span>
<span class="kicker">proof of concept</span>
<span class="wordmark"
>{{ messages.appHeaderBrandPrefix
}}<span class="accent">{{ messages.appHeaderBrandAccent }}</span
>{{ messages.appHeaderBrandSuffix }}</span
>
<span class="kicker">{{ messages.appHeaderKicker }}</span>
</div>
<div class="controls">
<span class="mode" :class="{ failed: healthFailed }">
{{ mode ? `${mode} mode` : healthFailed ? 'mode unavailable' : 'checking mode' }}
{{ modeLabel }}
</span>
<AuthStatus :auth="auth" @logout="$emit('logout')" />
<button class="button" type="button" @click="$emit('toggleDev')">
Dev panel <span class="key">Ctrl+D</span>
<button class="button" type="button" data-dev-panel-opener @click="openDevPanel">
<span class="full-label">
{{ messages.appHeaderDevPanel }}
<span class="key">{{ messages.appHeaderDevPanelShortcut }}</span>
</span>
<span class="short-label">{{ messages.appHeaderDevPanelShort }}</span>
</button>
</div>
</div>
@ -116,6 +139,10 @@ defineEmits<{ logout: []; toggleDev: [] }>()
color: var(--c-text-ghost);
}
.short-label {
display: none;
}
@media (max-width: 760px) {
.kicker,
.mode,
@ -132,8 +159,12 @@ defineEmits<{ logout: []; toggleDev: [] }>()
font-size: 0;
}
.button::after {
content: 'Dev';
.full-label {
display: none;
}
.short-label {
display: inline;
font-size: var(--t-micro);
}
}