feat(ui): live host row update via SSE without full reload

On new ingest, patch visible host from GET /hosts/{id}; SAC 0.8.1.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-05 10:47:21 +10:00
parent d9893497ce
commit 502971367e
7 changed files with 162 additions and 6 deletions
+32 -2
View File
@@ -130,7 +130,14 @@
<script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue";
import { useRoute } from "vue-router";
import { apiFetch, type EventListResponse, type HostDetail } from "../api";
import { useSacLiveEventStream } from "../composables/useSacLiveEventStream";
import {
apiFetch,
fetchHost,
fetchRecentEvents,
type EventListResponse,
type HostDetail,
} from "../api";
const props = defineProps<{ id: string }>();
const route = useRoute();
@@ -143,6 +150,11 @@ const error = ref("");
const eventsError = ref("");
const eventsPage = ref(1);
const eventsPageSize = 50;
let refreshingLive = false;
useSacLiveEventStream(() => {
void refreshFromLatestEvent();
});
const hostId = computed(() => parseInt(props.id, 10));
@@ -211,7 +223,7 @@ async function loadHost() {
loading.value = true;
error.value = "";
try {
host.value = await apiFetch<HostDetail>(`/api/v1/hosts/${hostId.value}`);
host.value = await fetchHost(hostId.value);
} catch (e) {
error.value = e instanceof Error ? e.message : "Ошибка загрузки хоста";
} finally {
@@ -219,6 +231,24 @@ async function loadHost() {
}
}
async function refreshFromLatestEvent() {
if (refreshingLive) return;
refreshingLive = true;
try {
const recent = await fetchRecentEvents(1);
const ev = recent[0];
if (!ev || ev.host_id !== hostId.value) return;
host.value = await fetchHost(hostId.value);
if (eventsPage.value === 1) {
await loadEvents(1);
}
} catch {
/* ignore transient errors */
} finally {
refreshingLive = false;
}
}
async function loadEvents(page = 1) {
eventsLoading.value = true;
eventsError.value = "";