feat: SAC 0.7.4 sidebar system stats block with UI toggle

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-02 09:15:15 +10:00
parent cf5a6f995c
commit 3053058cdf
20 changed files with 1082 additions and 255 deletions
+58
View File
@@ -11,6 +11,27 @@
<p v-else-if="loading">Загрузка</p>
<template v-else>
<section class="card settings-card settings-policy">
<h2>Интерфейс</h2>
<p class="settings-hint settings-hint-top">
Блок «Сервер» в левой панели: CPU, RAM, диск, задержка БД и счётчики SAC. Обновляется каждые 30 секунд.
</p>
<form class="settings-form" @submit.prevent="saveUiSettings">
<label class="settings-field settings-inline">
<input v-model="uiForm.show_sidebar_system_stats" type="checkbox" />
Показывать блок системной информации в боковой панели
</label>
<p v-if="uiLoaded" class="settings-meta">
Источник: <code>{{ uiLoaded.source }}</code>
</p>
<div class="settings-actions">
<button type="submit" :disabled="savingUi">
{{ savingUi ? "Сохранение…" : "Сохранить интерфейс" }}
</button>
</div>
</form>
</section>
<section class="card settings-card settings-policy">
<h2>Правило оповещений</h2>
<p class="settings-hint settings-hint-top">
@@ -291,6 +312,11 @@ interface NotificationPolicy {
source: string;
}
interface UiSettings {
show_sidebar_system_stats: boolean;
source: string;
}
interface SeverityOverrideRowApi {
event_type: string;
default_severity: string;
@@ -303,6 +329,7 @@ interface SeverityOverrideRowUi extends SeverityOverrideRowApi {
const loading = ref(true);
const savingPolicy = ref(false);
const savingUi = ref(false);
const savingTelegram = ref(false);
const savingWebhook = ref(false);
const savingEmail = ref(false);
@@ -316,6 +343,7 @@ const telegramLoaded = ref<TelegramSettings | null>(null);
const webhookLoaded = ref<WebhookSettings | null>(null);
const emailLoaded = ref<EmailSettings | null>(null);
const policyLoaded = ref<NotificationPolicy | null>(null);
const uiLoaded = ref<UiSettings | null>(null);
const severityRows = ref<SeverityOverrideRowUi[]>([]);
const severityFilter = ref("");
@@ -326,6 +354,10 @@ const policyForm = reactive({
use_email: false,
});
const uiForm = reactive({
show_sidebar_system_stats: true,
});
const telegramForm = reactive({
enabled: false,
bot_token: "",
@@ -429,6 +461,31 @@ async function saveSeverityOverrides() {
}
}
async function loadUiSettings() {
const data = await apiFetch<UiSettings>("/api/v1/settings/ui");
uiLoaded.value = data;
uiForm.show_sidebar_system_stats = data.show_sidebar_system_stats;
}
async function saveUiSettings() {
savingUi.value = true;
error.value = "";
success.value = "";
try {
uiLoaded.value = await apiFetch<UiSettings>("/api/v1/settings/ui", {
method: "PUT",
body: JSON.stringify({
show_sidebar_system_stats: uiForm.show_sidebar_system_stats,
}),
});
success.value = "Настройки интерфейса сохранены.";
} catch (e) {
error.value = e instanceof Error ? e.message : "Ошибка сохранения";
} finally {
savingUi.value = false;
}
}
async function load() {
loading.value = true;
error.value = "";
@@ -463,6 +520,7 @@ async function load() {
emailForm.mail_to = "";
emailForm.smtp_starttls = data.email.smtp_starttls;
emailForm.smtp_ssl = data.email.smtp_ssl;
await loadUiSettings();
await loadSeverityOverrides();
} catch (e) {
error.value = e instanceof Error ? e.message : "Ошибка загрузки";