feat: phase 1C JWT UI, events/hosts API, Vue frontend
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<h1>Хосты</h1>
|
||||
<p v-if="error" class="error">{{ error }}</p>
|
||||
<p v-else-if="loading">Загрузка…</p>
|
||||
<template v-else>
|
||||
<p>Всего: {{ data?.total ?? 0 }}</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Hostname</th>
|
||||
<th>Product</th>
|
||||
<th>OS</th>
|
||||
<th>IPv4</th>
|
||||
<th>Last seen</th>
|
||||
<th>Events</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="h in data?.items ?? []" :key="h.id">
|
||||
<td>{{ h.id }}</td>
|
||||
<td>{{ h.display_name || h.hostname }}</td>
|
||||
<td>{{ h.product }} {{ h.product_version || "" }}</td>
|
||||
<td>{{ h.os_family }}</td>
|
||||
<td>{{ h.ipv4 || "—" }}</td>
|
||||
<td>{{ formatDt(h.last_seen_at) }}</td>
|
||||
<td>{{ h.event_count ?? 0 }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from "vue";
|
||||
import { apiFetch, type HostListResponse } from "../api";
|
||||
|
||||
const data = ref<HostListResponse | null>(null);
|
||||
const loading = ref(false);
|
||||
const error = ref("");
|
||||
|
||||
function formatDt(iso: string) {
|
||||
return new Date(iso).toLocaleString("ru-RU");
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
data.value = await apiFetch<HostListResponse>("/api/v1/hosts?page=1&page_size=100");
|
||||
} catch (e) {
|
||||
error.value = e instanceof Error ? e.message : "Ошибка";
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user