From ecb3f6b5243191e1a3969c74ea4723da80983832 Mon Sep 17 00:00:00 2001 From: dv Date: Tue, 5 May 2026 12:27:12 +0300 Subject: [PATCH] =?UTF-8?q?=D1=84=D0=B8=D0=BA=D1=81=20=D1=80=D0=B0=D0=B7?= =?UTF-8?q?=D0=BC=D0=B5=D1=82=D0=BA=D0=B8=20=D0=B8=20=D0=BA=D0=BE=D0=B4?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/Home.tsx | 109 +++++++++++++----------- frontend/src/pages/HomeObjectDetail.tsx | 108 ++++++++++++----------- frontend/src/pages/HomeSettings.tsx | 90 ++++++++++--------- 3 files changed, 163 insertions(+), 144 deletions(-) diff --git a/frontend/src/pages/Home.tsx b/frontend/src/pages/Home.tsx index b6846bd..109dad1 100644 --- a/frontend/src/pages/Home.tsx +++ b/frontend/src/pages/Home.tsx @@ -10,19 +10,19 @@ import { useDashboardMonitorSSE } from '../hooks/useDashboardMonitorSSE' function formatAge(seconds: number | null | undefined): string { if (seconds == null) return '-' - if (seconds < 60) return `${seconds}` - if (seconds < 3600) return `${Math.floor(seconds / 60)}` - return `${Math.floor(seconds / 3600)} ${Math.floor((seconds % 3600) / 60)}` + if (seconds < 60) return `${seconds}с` + if (seconds < 3600) return `${Math.floor(seconds / 60)}м` + return `${Math.floor(seconds / 3600)}ч ${Math.floor((seconds % 3600) / 60)}м` } function reasonLabel(reason: string): string { const map: Record = { - object_include_policy: ' ', - object_exclude_policy: ' ', - inherit_default: ' ', - tag_policy_enabled: ' ', - tag_policy_disabled: ' ', - scope_filtered: ' scope', + object_include_policy: 'Включен политикой объекта', + object_exclude_policy: 'Исключен политикой объекта', + inherit_default: 'Наследование по умолчанию', + tag_policy_enabled: 'Включен политикой тегов', + tag_policy_disabled: 'Исключен политикой тегов', + scope_filtered: 'Вне текущего scope', } return map[reason] ?? reason } @@ -72,9 +72,9 @@ export function HomePage() { const handleRunNow = async () => { try { await runNow.mutateAsync({ ...scope, force: true }) - message.success(' ') + message.success('Мониторинг запущен') } catch { - message.error(' ') + message.error('Не удалось запустить мониторинг') } } @@ -82,7 +82,7 @@ export function HomePage() { const columns = [ { - title: '', + title: 'Объект', key: 'object', render: (_: unknown, row: any) => ( @@ -99,12 +99,12 @@ export function HomePage() { ), }, { - title: '', + title: 'Причина', key: 'reason', render: (_: unknown, row: any) => {reasonLabel(row.inclusion_reason)}, }, { - title: '', + title: 'Устройств', dataIndex: 'device_count', key: 'device_count', }, @@ -137,22 +137,26 @@ export function HomePage() { return (
- - - NOC - - - - - - + + + + NOC Дешборд + + + + + + + + + - - + + ({ value: c, label: c }))} @@ -170,10 +174,10 @@ export function HomePage() { onChange={setClient} /> - + - : {monitorStatus?.status ?? '-'} + Статус: {monitorStatus?.status ?? '-'} {monitorStatus?.last_success_at - ? ` ${dayjs(monitorStatus.last_success_at).format('DD.MM HH:mm:ss')}` + ? ` · успешный запуск ${dayjs(monitorStatus.last_success_at).format('DD.MM HH:mm:ss')}` : ''} @@ -209,22 +213,22 @@ export function HomePage() { )} - - - + + + - - + + - - + + - - + + - + - - - + + +
- - + +
diff --git a/frontend/src/pages/HomeObjectDetail.tsx b/frontend/src/pages/HomeObjectDetail.tsx index c0aa0f3..40dd9ad 100644 --- a/frontend/src/pages/HomeObjectDetail.tsx +++ b/frontend/src/pages/HomeObjectDetail.tsx @@ -2,6 +2,7 @@ import { ArrowLeftOutlined } from '@ant-design/icons' import { Alert, Button, Card, Col, Row, Select, Space, Table, Tag, Typography } from 'antd' import dayjs from 'dayjs' import { useMemo, useState } from 'react' +import { useQueryClient } from '@tanstack/react-query' import { useNavigate, useParams, useSearchParams } from 'react-router-dom' import { useDashboardObjectAvailability, @@ -12,16 +13,15 @@ import { type DashboardScope, } from '../api/dashboard' import { useDashboardMonitorSSE } from '../hooks/useDashboardMonitorSSE' -import { useQueryClient } from '@tanstack/react-query' function reasonLabel(reason: string): string { const map: Record = { - object_include_policy: ' ', - object_exclude_policy: ' ', - inherit_default: ' ', - tag_policy_enabled: ' ', - tag_policy_disabled: ' ', - scope_filtered: ' scope', + object_include_policy: 'Включен политикой объекта', + object_exclude_policy: 'Исключен политикой объекта', + inherit_default: 'Наследование по умолчанию', + tag_policy_enabled: 'Включен политикой тегов', + tag_policy_disabled: 'Исключен политикой тегов', + scope_filtered: 'Вне текущего scope', } return map[reason] ?? reason } @@ -93,24 +93,28 @@ export function HomeObjectDetailPage() { return (
- - - - - {object?.object_name ?? ` #${objectId}`} - - - - {object?.allowed ? : } - {object?.health_score != null && ( - = 80 ? 'green' : object.health_score >= 60 ? 'orange' : 'red'}> - Health {object.health_score} - - )} - - + +
+ + + + {object?.object_name ?? `Объект #${objectId}`} + + + + + + {object?.allowed ? В мониторинге : Вне мониторинга} + {object?.health_score != null && ( + = 80 ? 'green' : object.health_score >= 60 ? 'orange' : 'red'}> + Health {object.health_score} + + )} + + + {object && ( @@ -123,43 +127,43 @@ export function HomeObjectDetailPage() { type="info" showIcon style={{ marginBottom: 12 }} - message=" " + message="Недостаточно данных для графика доступности в выбранном окне" /> )} - - + + - + Устройств {summary?.totals.devices ?? 0} - + - + Проблемных {summary?.totals.problem_devices ?? 0} - + - ({window}) + Доступность ({window}) - {availability?.overall_availability_pct != null ? `${availability.overall_availability_pct}%` : ''} + {availability?.overall_availability_pct != null ? `${availability.overall_availability_pct}%` : '—'} setWindow(v as DashboardAvailabilityWindow)} options={[ - { value: '24h', label: '24' }, - { value: '3d', label: '3' }, - { value: '7d', label: '7' }, + { value: '24h', label: '24ч' }, + { value: '3d', label: '3д' }, + { value: '7d', label: '7д' }, ]} style={{ width: 100 }} /> @@ -169,13 +173,14 @@ export function HomeObjectDetailPage() { - +
( {row.ip} - {row.hostname ?? ''} + {row.hostname ?? '—'} ), }, - { title: '', dataIndex: 'category', key: 'category' }, + { title: 'Категория', dataIndex: 'category', key: 'category' }, { title: 'Ping', key: 'ping', @@ -197,8 +202,8 @@ export function HomeObjectDetailPage() { {row.ping_status} - {row.ping_checked_at ? dayjs(row.ping_checked_at).format('DD.MM HH:mm:ss') : ''} - {row.last_ping_ms != null ? ` ${row.last_ping_ms}ms` : ''} + {row.ping_checked_at ? dayjs(row.ping_checked_at).format('DD.MM HH:mm:ss') : '—'} + {row.last_ping_ms != null ? ` · ${row.last_ping_ms}ms` : ''} ), @@ -211,37 +216,38 @@ export function HomeObjectDetailPage() { {row.disk_status}{row.disk_max_pct != null ? ` (${row.disk_max_pct}%)` : ''} - ) : '', + ) : '—', }, { - title: '', + title: 'Проблема', key: 'problem', - render: (_: unknown, row: any) => row.has_problem ? : , + render: (_: unknown, row: any) => row.has_problem ? Да : Нет, }, ]} /> - +
{v} }, - { title: 'Hostname', dataIndex: 'hostname', key: 'hostname', render: (v: string | null) => v ?? '' }, + { title: 'Hostname', dataIndex: 'hostname', key: 'hostname', render: (v: string | null) => v ?? '—' }, { title: 'Availability', key: 'availability_pct', - render: (_: unknown, row: any) => row.availability_pct != null ? `${row.availability_pct}%` : '', + render: (_: unknown, row: any) => row.availability_pct != null ? `${row.availability_pct}%` : '—', }, { title: 'Samples', dataIndex: 'samples', key: 'samples' }, { - title: ' ', + title: 'Последний статус', key: 'last_status', - render: (_: unknown, row: any) => row.last_status ? {row.last_status} : '', + render: (_: unknown, row: any) => row.last_status ? {row.last_status} : '—', }, ]} /> diff --git a/frontend/src/pages/HomeSettings.tsx b/frontend/src/pages/HomeSettings.tsx index b94b38d..58c4504 100644 --- a/frontend/src/pages/HomeSettings.tsx +++ b/frontend/src/pages/HomeSettings.tsx @@ -110,32 +110,36 @@ export function HomeSettingsPage() { const handleRunNow = async () => { try { await runNow.mutateAsync({ force: true }) - message.success(' ') + message.success('Мониторинг запущен') } catch { - message.error(' ') + message.error('Не удалось запустить мониторинг') } } return (
- - -
+ + + + Настройки мониторинга + + + + + - - - - - - + + - : {monitorStatus?.status ?? '-'} + Статус: {monitorStatus?.status ?? '-'} {monitorStatus?.last_success_at - ? ` ${dayjs(monitorStatus.last_success_at).format('DD.MM HH:mm:ss')}` + ? ` · успешный запуск ${dayjs(monitorStatus.last_success_at).format('DD.MM HH:mm:ss')}` : ''} @@ -143,12 +147,12 @@ export function HomeSettingsPage() { )} - + {(checksData?.checks ?? []).map((check) => ( - - {check.check_key} - + + {check.check_key} + { @@ -156,7 +160,7 @@ export function HomeSettingsPage() { }} /> - + - +
( ({ value: o.id, label: o.name }))} /> setOverrideCategoriesMode(v as OverrideCategoriesMode)} @@ -281,7 +286,7 @@ export function HomeSettingsPage() { mode="multiple" allowClear disabled={overrideCategoriesMode !== 'custom'} - placeholder=" override" + placeholder="Категории override" style={{ width: 280 }} value={overrideCategories} onChange={setOverrideCategories} @@ -291,7 +296,7 @@ export function HomeSettingsPage() { type="primary" onClick={async () => { if (!overrideObjectId || !overrideCheckKey) { - message.warning(' ') + message.warning('Выберите объект и проверку') return } await patchOverrides.mutateAsync([ @@ -309,15 +314,15 @@ export function HomeSettingsPage() { : null, }, ]) - message.success('Override ') + message.success('Override обновлен') }} > - override + Сохранить override @@ -343,14 +348,15 @@ export function HomeSettingsPage() { rowKey={(row) => `${row.object_id}:${row.check_key}`} pagination={{ pageSize: 6 }} dataSource={checksData?.object_overrides ?? []} + scroll={{ x: 900 }} columns={[ { - title: '', + title: 'Объект', key: 'object', render: (_: unknown, row: DashboardObjectOverride) => objects?.find((o) => o.id === row.object_id)?.name ?? row.object_id, }, - { title: '', dataIndex: 'check_key', key: 'check_key' }, + { title: 'Проверка', dataIndex: 'check_key', key: 'check_key' }, { title: 'Enabled', key: 'enabled_override', @@ -358,13 +364,13 @@ export function HomeSettingsPage() { row.enabled_override == null ? 'inherit' : row.enabled_override ? 'enabled' : 'disabled', }, { - title: '', + title: 'Интервал', key: 'interval_sec_override', render: (_: unknown, row: DashboardObjectOverride) => row.interval_sec_override == null ? 'inherit' : `${row.interval_sec_override}s`, }, { - title: '', + title: 'Категории', key: 'categories_override', render: (_: unknown, row: DashboardObjectOverride) => row.categories_override == null