fix(ui): сохранять вкладку и фильтры Ping в URL
This commit is contained in:
1 parent
f7e0e20673
commit
fd7a08d5dc
7 files changed
+157
-9
No files matched your search
@@ -0,0 +1,17 @@
|
||||
import assert from "node:assert/strict"
|
||||
import test from "node:test"
|
||||
import { readUptimeUrl, patchUptimeUrl } from "./uptime-url-state"
|
||||
|
||||
test("вкладка и фильтры Ping восстанавливаются из ссылки", () => {
|
||||
const state = readUptimeUrl(new URLSearchParams({ tab: "speed", q: "узел", status: "down", servers: '["1","x/2"]' }))
|
||||
assert.deepEqual(state, { tab: "speed", search: "узел", status: "down", servers: ["1", "x/2"], error: null })
|
||||
})
|
||||
test("некорректные и повторяющиеся параметры дают ошибку", () => {
|
||||
for (const raw of ['tab=unknown', 'status=online', 'q=a&q=b', 'servers={}', 'servers=[1]', 'servers=["1","1"]', 'servers=[""]']) {
|
||||
assert.ok(readUptimeUrl(new URLSearchParams(raw)).error, raw)
|
||||
}
|
||||
})
|
||||
test("сброс оставляет пробу, вкладку и чужие параметры", () => {
|
||||
const result = patchUptimeUrl(new URLSearchParams('probe=p%2F2&keep=1&tab=speed&q=a&status=down&servers=%5B%221%22%5D'), { q: null, status: null, servers: null })
|
||||
assert.equal(result, '/uptime?probe=p%2F2&keep=1&tab=speed')
|
||||
})
|
||||
@@ -0,0 +1,37 @@
|
||||
import type { Dispatch, SetStateAction } from "react"
|
||||
|
||||
export type UptimeTab = "probes" | "resources" | "speed"
|
||||
export type ProbeStatusFilter = "all" | "up" | "warn" | "down"
|
||||
export function readUptimeUrl(params: URLSearchParams) {
|
||||
const rawTab = params.get("tab")
|
||||
const rawStatus = params.get("status")
|
||||
const search = params.get("q") ?? ""
|
||||
const tab: UptimeTab = rawTab === "resources" || rawTab === "speed" ? rawTab : "probes"
|
||||
const status: ProbeStatusFilter = rawStatus === "up" || rawStatus === "warn" || rawStatus === "down" ? rawStatus : "all"
|
||||
let error: string | null = null
|
||||
let servers: string[] = []
|
||||
if ((rawTab !== null && !["probes", "resources", "speed"].includes(rawTab)) ||
|
||||
(rawStatus !== null && !["up", "warn", "down"].includes(rawStatus)) ||
|
||||
["tab", "q", "status", "servers"].some(key => params.getAll(key).length > 1)) error = "В ссылке указаны неверные или повторяющиеся параметры мониторинга."
|
||||
const rawServers = params.get("servers")
|
||||
if (rawServers !== null) {
|
||||
try {
|
||||
if (rawServers.length > 8192) throw new Error()
|
||||
const value: unknown = JSON.parse(rawServers)
|
||||
if (!Array.isArray(value) || value.length > 50 || !value.every(id => typeof id === "string" && id.length > 0 && id.length <= 128) || new Set(value).size !== value.length) throw new Error()
|
||||
servers = value
|
||||
} catch { error = "Не удалось прочитать выбранные серверы из ссылки." }
|
||||
}
|
||||
return { tab, search, status, servers, error }
|
||||
}
|
||||
|
||||
export function patchUptimeUrl(params: URLSearchParams, changes: Record<string, string | null>) {
|
||||
const next = new URLSearchParams(params)
|
||||
for (const [key, value] of Object.entries(changes)) {
|
||||
if (value === null || value === "") next.delete(key)
|
||||
else next.set(key, value)
|
||||
}
|
||||
return "/uptime" + (next.size ? "?" + next.toString() : "")
|
||||
}
|
||||
|
||||
export type UrlSetter<T> = Dispatch<SetStateAction<T>>
|
||||
Reference in new issue
Block a user