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:
@@ -10,7 +10,10 @@
|
||||
<p v-if="error" class="error">{{ error }}</p>
|
||||
<p v-else-if="loading">Загрузка…</p>
|
||||
<template v-else>
|
||||
<p>Всего: {{ data?.total ?? 0 }}</p>
|
||||
<p>
|
||||
Всего: {{ data?.total ?? 0 }}
|
||||
<span v-if="live" class="live-badge">live</span>
|
||||
</p>
|
||||
<table class="hosts-table">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -77,7 +80,15 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { apiFetch, type HostListResponse, type HostSummary } from "../api";
|
||||
import { useSacLiveEventStream } from "../composables/useSacLiveEventStream";
|
||||
import {
|
||||
apiFetch,
|
||||
fetchHost,
|
||||
fetchRecentEvents,
|
||||
type HostListResponse,
|
||||
type HostSummary,
|
||||
} from "../api";
|
||||
import { patchHostSummaryFromDetail } from "../utils/hostsLiveUpdate";
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
@@ -139,6 +150,11 @@ const initialSort = loadHostsSortPrefs();
|
||||
const sortBy = ref<SortKey>(initialSort.sortBy);
|
||||
const sortDir = ref<"asc" | "desc">(initialSort.sortDir);
|
||||
const deletingId = ref<number | null>(null);
|
||||
let patchingHostRow = false;
|
||||
|
||||
const { live } = useSacLiveEventStream(() => {
|
||||
void patchHostRowFromLatestEvent();
|
||||
});
|
||||
|
||||
function formatDt(iso: string) {
|
||||
return new Date(iso).toLocaleString("ru-RU");
|
||||
@@ -248,6 +264,24 @@ async function loadHosts() {
|
||||
}
|
||||
}
|
||||
|
||||
async function patchHostRowFromLatestEvent() {
|
||||
if (!data.value?.items.length || patchingHostRow) return;
|
||||
patchingHostRow = true;
|
||||
try {
|
||||
const recent = await fetchRecentEvents(1);
|
||||
const ev = recent[0];
|
||||
if (!ev) return;
|
||||
const row = data.value.items.find((h) => h.id === ev.host_id);
|
||||
if (!row) return;
|
||||
const detail = await fetchHost(ev.host_id);
|
||||
patchHostSummaryFromDetail(row, detail);
|
||||
} catch {
|
||||
/* keep table on transient errors */
|
||||
} finally {
|
||||
patchingHostRow = false;
|
||||
}
|
||||
}
|
||||
|
||||
interface HostDeleteResponse {
|
||||
status: string;
|
||||
host_id: number;
|
||||
|
||||
Reference in New Issue
Block a user