fix(probes): проверять расписание и сохранять подтверждённые данные
This commit is contained in:
1 parent
1d27127b52
commit
271291a910
10 files changed
+108
-98
No files matched your search
@@ -15,10 +15,7 @@ import {
|
||||
type SchedRule,
|
||||
type SchedType,
|
||||
} from "@/components/data-grids/probes-schedule-data-grid"
|
||||
import {
|
||||
ProbesSpeedProbesDataGrid,
|
||||
type SpeedProbeApiRow,
|
||||
} from "@/components/data-grids/probes-speed-probes-data-grid"
|
||||
import {ProbesSpeedSchedule} from "@/components/probes-speed-schedule"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { ServerRailLayout, ServerRailMobileButton } from "@/components/server-rail-layout"
|
||||
@@ -32,7 +29,7 @@ import {
|
||||
PlayIcon, SquareIcon, CopyIcon, Trash2Icon, PlusIcon,
|
||||
ActivityIcon, RouteIcon, SearchIcon, NetworkIcon, RulerIcon,
|
||||
ZapIcon, CheckIcon, TerminalIcon,
|
||||
LoaderCircleIcon, AlertCircleIcon,
|
||||
LoaderCircleIcon,
|
||||
} from "lucide-react"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { requestJson } from "@/shared/api/http-client"
|
||||
@@ -382,65 +379,6 @@ function TerminalOutput({ test }: { test: DiagTest }) {
|
||||
}
|
||||
// ─── uptime speed probes (live) ───────────────────────────────────────────────
|
||||
|
||||
function ScheduleSpeedProbesLive({
|
||||
apiFetch,
|
||||
serversForName,
|
||||
}: {
|
||||
apiFetch: ReturnType<typeof makeApiFetch>
|
||||
serversForName: Server[]
|
||||
}) {
|
||||
const [rows, setRows] = useState<SpeedProbeApiRow[]>([])
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [err, setErr] = useState<string | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false
|
||||
setLoading(true)
|
||||
setErr(null)
|
||||
void apiFetch<{ probes: SpeedProbeApiRow[] }>("/api/uptime/speed-probes")
|
||||
.then(d => {
|
||||
if (!cancelled) setRows(d.probes ?? [])
|
||||
})
|
||||
.catch(e => {
|
||||
if (!cancelled) setErr(e instanceof Error ? e.message : String(e))
|
||||
})
|
||||
.finally(() => {
|
||||
if (!cancelled) setLoading(false)
|
||||
})
|
||||
return () => { cancelled = true }
|
||||
}, [apiFetch])
|
||||
|
||||
const name = (id: string) => serversForName.find(s => s.id === id)?.name ?? id
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center gap-2 py-12 text-sm text-muted-foreground">
|
||||
<LoaderCircleIcon aria-hidden="true" className="size-5 motion-safe:animate-spin" />
|
||||
Загрузка расписания из БД…
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if (err) {
|
||||
return (
|
||||
<div className="flex items-center gap-2 rounded-lg border border-destructive/30 bg-destructive/10 px-4 py-3 text-sm text-destructive">
|
||||
<AlertCircleIcon aria-hidden="true" className="size-4 shrink-0" />
|
||||
{err}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-3">
|
||||
<DataPageCard>
|
||||
<ProbesSpeedProbesDataGrid rows={rows} serverName={name} />
|
||||
</DataPageCard>
|
||||
<p className="text-[11px] text-muted-foreground">
|
||||
Данные из коллектора uptime (та же БД, что и дашборд). Редактирование — через настройки мониторинга / API.
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// ─── schedule tab ─────────────────────────────────────────────────────────────
|
||||
|
||||
const INIT_RULES: SchedRule[] = [
|
||||
@@ -464,21 +402,12 @@ function ScheduleTab({
|
||||
}) {
|
||||
const [showAdd, setShowAdd] = useState(false)
|
||||
const [addSrc, setAddSrc] = useState(defaultSrc ?? serverOptions[0]?.id ?? "srv1")
|
||||
const [addTun, setAddTun] = useState("")
|
||||
const [selectedTunnel, setAddTun] = useState("")
|
||||
const [addType, setAddType] = useState<SchedType>("ping")
|
||||
const [addMin, setAddMin] = useState(10)
|
||||
const addTunnels = useMemo(() => tunnelsForServer(addSrc), [addSrc, tunnelsForServer])
|
||||
|
||||
useEffect(() => {
|
||||
if (defaultSrc) setAddSrc(defaultSrc)
|
||||
}, [defaultSrc])
|
||||
|
||||
useEffect(() => {
|
||||
const list = tunnelsForServer(addSrc)
|
||||
if (list.length && !list.some(t => t.id === addTun)) {
|
||||
setAddTun(list[0]?.id ?? "")
|
||||
}
|
||||
}, [addSrc, addTun, tunnelsForServer])
|
||||
const addTun = addTunnels.some(t=>t.id===selectedTunnel) ? selectedTunnel : addTunnels[0]?.id ?? ""
|
||||
|
||||
const tunnelName = (srcId: string, tunnelId: string) =>
|
||||
tunnelsForServer(srcId).find((t) => t.id === tunnelId)?.name
|
||||
@@ -504,7 +433,7 @@ function ScheduleTab({
|
||||
</div>
|
||||
<div className="px-4 py-4 flex flex-wrap items-end gap-3">
|
||||
<div><OptionLabel>Сервер</OptionLabel>
|
||||
<NativeSelect ariaLabel="Устройство расписания" value={addSrc} onChange={setAddSrc} className="min-w-[160px]">
|
||||
<NativeSelect ariaLabel="Устройство расписания" value={addSrc} onChange={value=>{setAddSrc(value);setAddTun("")}} className="min-w-[160px]">
|
||||
{serverOptions.filter(s => s.enabled).map(s => <option key={s.id} value={s.id}>{s.name}</option>)}
|
||||
</NativeSelect>
|
||||
</div>
|
||||
@@ -1195,9 +1124,10 @@ function ProbesContent() {
|
||||
{/* schedule */}
|
||||
{tab === "schedule" && (
|
||||
isLive
|
||||
? <ScheduleSpeedProbesLive apiFetch={apiFetch} serversForName={allServers} />
|
||||
? <ProbesSpeedSchedule base={backendUrl} serversForName={allServers} />
|
||||
: (
|
||||
<ScheduleTab
|
||||
key={srcId}
|
||||
rules={rules}
|
||||
setRules={setRules}
|
||||
serverOptions={allServers}
|
||||
|
||||
Reference in new issue
Block a user