fix(netflow): сохранять черновики и показывать подтверждённые результаты
This commit is contained in:
1 parent
c9b0f9266e
commit
fcd8de2a96
9 files changed
+222
-156
No files matched your search
@@ -0,0 +1,10 @@
|
||||
import assert from "node:assert/strict"
|
||||
import {test} from "node:test"
|
||||
import {emptyNetflowDraft,netflowDraftPatch} from "./netflow-settings-form"
|
||||
test("NetFlow form sends selected values without defaulting invalid neighbours",()=>{
|
||||
assert.deepEqual(netflowDraftPatch({...emptyNetflowDraft,flowListenPort:"4740"},new Set(["flowListenPort"])),{flowListenPort:4740})
|
||||
assert.deepEqual(netflowDraftPatch({...emptyNetflowDraft,enabled:false,shareOn:false},new Set(["enabled","shareOn"])),{enabled:false,mapServiceMinSharePct:0})
|
||||
assert.deepEqual(netflowDraftPatch({...emptyNetflowDraft,shareOn:true,mapServiceMinSharePct:"0.25"},new Set(["shareOn","mapServiceMinSharePct"])),{mapServiceMinSharePct:0.25})
|
||||
for(const raw of ["0","65536","4739x","4.5",""])assert.throws(()=>netflowDraftPatch({...emptyNetflowDraft,flowListenPort:raw},new Set(["flowListenPort"])))
|
||||
for(const raw of ["0","100.01","NaN",""])assert.throws(()=>netflowDraftPatch({...emptyNetflowDraft,shareOn:true,mapServiceMinSharePct:raw},new Set(["mapServiceMinSharePct"])))
|
||||
})
|
||||
@@ -0,0 +1,26 @@
|
||||
import type { TrafficFlowSettingsDto, TrafficFlowSettingsPatch } from "@mmapp/contracts/traffic-flow"
|
||||
export type NetflowDraft = { enabled: boolean; collectorIp: string; flowListenPort: string; wgListenPort: string; prefix: string; publicEndpoint: string; retentionHours: string; topN: string; shareOn: boolean; mapServiceMinSharePct: string }
|
||||
export const emptyNetflowDraft: NetflowDraft = { enabled: false, collectorIp: "", flowListenPort: "", wgListenPort: "", prefix: "", publicEndpoint: "", retentionHours: "", topN: "", shareOn: false, mapServiceMinSharePct: "" }
|
||||
export function netflowDraftFromSettings(data: TrafficFlowSettingsDto): NetflowDraft {
|
||||
return { enabled: data.enabled, collectorIp: data.collectorIp, flowListenPort: String(data.flowListenPort), wgListenPort: String(data.wgListenPort), prefix: data.prefix, publicEndpoint: data.publicEndpoint, retentionHours: String(data.retentionHours), topN: String(data.topN), shareOn: data.mapServiceMinSharePct > 0, mapServiceMinSharePct: String(data.mapServiceMinSharePct) }
|
||||
}
|
||||
export function netflowDraftPatch(draft: NetflowDraft, dirty: ReadonlySet<keyof NetflowDraft>): TrafficFlowSettingsPatch {
|
||||
const patch: TrafficFlowSettingsPatch = {}
|
||||
for (const field of ["collectorIp", "prefix", "publicEndpoint"] as const) if (dirty.has(field)) {
|
||||
const value = draft[field].trim()
|
||||
if ((field !== "publicEndpoint" && !value) || /[\r\n]/.test(value)) throw new Error("Укажите корректное значение: " + field)
|
||||
patch[field] = value
|
||||
}
|
||||
for (const [field, label, max] of [["flowListenPort","UDP IPFIX",65535],["wgListenPort","WG listen",65535],["retentionHours","Хранение (часов)",Number.MAX_SAFE_INTEGER],["topN","Top-N разговоров",1000]] as const) if (dirty.has(field)) {
|
||||
const raw = draft[field], value = Number(raw)
|
||||
if (!/^\d+$/.test(raw) || !Number.isSafeInteger(value) || value < 1 || value > max) throw new Error(label + ": укажите целое число от 1 до " + max)
|
||||
patch[field] = value
|
||||
}
|
||||
if (dirty.has("enabled")) patch.enabled = draft.enabled
|
||||
if (dirty.has("shareOn") || dirty.has("mapServiceMinSharePct")) {
|
||||
const value = Number(draft.mapServiceMinSharePct)
|
||||
if (draft.shareOn && (!/^\d+(?:\.\d+)?$/.test(draft.mapServiceMinSharePct) || !Number.isFinite(value) || value <= 0 || value > 100)) throw new Error("Порог карты: укажите долю больше 0 и не более 100%")
|
||||
patch.mapServiceMinSharePct = draft.shareOn ? value : 0
|
||||
}
|
||||
return patch
|
||||
}
|
||||
Reference in new issue
Block a user