mirror of
https://github.com/hansjone/netx.git
synced 2026-10-12 11:43:21 +08:00
Add seconds unit to biz-state collection interval picker.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
ff37d0866a
commit
108c9da00f
4 changed files with 56 additions and 24 deletions
|
|
@ -154,7 +154,7 @@ def create_task(db: Session, body: dict[str, Any]) -> dict[str, Any]:
|
||||||
device_type=device_type,
|
device_type=device_type,
|
||||||
note=str(body.get("note") or "")[:256],
|
note=str(body.get("note") or "")[:256],
|
||||||
status="draft",
|
status="draft",
|
||||||
interval_sec=max(3600, int(body.get("interval_sec") or 3600)),
|
interval_sec=max(60, int(body.get("interval_sec") or 3600)),
|
||||||
retention_batches=max(1, int(body.get("retention_batches") or 30)),
|
retention_batches=max(1, int(body.get("retention_batches") or 30)),
|
||||||
created_at=_utcnow(),
|
created_at=_utcnow(),
|
||||||
updated_at=_utcnow(),
|
updated_at=_utcnow(),
|
||||||
|
|
@ -228,7 +228,7 @@ def update_task(db: Session, task_id: str, body: dict[str, Any]) -> dict[str, An
|
||||||
if "note" in body:
|
if "note" in body:
|
||||||
task.note = str(body.get("note") or "")[:256]
|
task.note = str(body.get("note") or "")[:256]
|
||||||
if "interval_sec" in body:
|
if "interval_sec" in body:
|
||||||
task.interval_sec = max(3600, int(body.get("interval_sec") or 3600))
|
task.interval_sec = max(60, int(body.get("interval_sec") or 3600))
|
||||||
if "retention_batches" in body:
|
if "retention_batches" in body:
|
||||||
task.retention_batches = max(1, int(body.get("retention_batches") or 30))
|
task.retention_batches = max(1, int(body.get("retention_batches") or 30))
|
||||||
if "items" in body:
|
if "items" in body:
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,7 @@ const en = {
|
||||||
interval: "Interval",
|
interval: "Interval",
|
||||||
intervalUnitDays: "days",
|
intervalUnitDays: "days",
|
||||||
intervalUnitHours: "hours",
|
intervalUnitHours: "hours",
|
||||||
|
intervalUnitSeconds: "seconds",
|
||||||
retention: "Keep batches",
|
retention: "Keep batches",
|
||||||
saveSchedule: "Save schedule",
|
saveSchedule: "Save schedule",
|
||||||
scheduleSaved: "Schedule saved",
|
scheduleSaved: "Schedule saved",
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,7 @@ const zh = {
|
||||||
interval: "采集周期",
|
interval: "采集周期",
|
||||||
intervalUnitDays: "天",
|
intervalUnitDays: "天",
|
||||||
intervalUnitHours: "小时",
|
intervalUnitHours: "小时",
|
||||||
|
intervalUnitSeconds: "秒",
|
||||||
retention: "保留批次数",
|
retention: "保留批次数",
|
||||||
saveSchedule: "保存周期",
|
saveSchedule: "保存周期",
|
||||||
scheduleSaved: "周期配置已保存",
|
scheduleSaved: "周期配置已保存",
|
||||||
|
|
|
||||||
|
|
@ -74,21 +74,47 @@ type NeSourceFilter = "all" | "managed" | "ume";
|
||||||
|
|
||||||
const NE_PAGE_SIZE = 10;
|
const NE_PAGE_SIZE = 10;
|
||||||
|
|
||||||
function fmtIntervalLabel(sec: number, daysLabel: string, hoursLabel: string) {
|
function fmtIntervalLabel(
|
||||||
const hours = Math.max(1, Math.round(Number(sec || 0) / 3600) || 1);
|
sec: number,
|
||||||
if (hours % 24 === 0) return `${hours / 24} ${daysLabel}`;
|
daysLabel: string,
|
||||||
return `${hours} ${hoursLabel}`;
|
hoursLabel: string,
|
||||||
|
secondsLabel: string,
|
||||||
|
) {
|
||||||
|
const s = Math.max(1, Math.round(Number(sec || 0)) || 1);
|
||||||
|
if (s % 86400 === 0) return `${s / 86400} ${daysLabel}`;
|
||||||
|
if (s % 3600 === 0) return `${s / 3600} ${hoursLabel}`;
|
||||||
|
return `${s} ${secondsLabel}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function secToIntervalUi(sec: number): { value: number; unit: "days" | "hours" } {
|
function secToIntervalUi(sec: number): { value: number; unit: "days" | "hours" | "seconds" } {
|
||||||
const hours = Math.max(1, Math.round(Number(sec || 3600) / 3600) || 1);
|
const s = Math.max(1, Math.round(Number(sec || 3600)) || 3600);
|
||||||
if (hours % 24 === 0) return { value: hours / 24, unit: "days" };
|
if (s % 86400 === 0) return { value: s / 86400, unit: "days" };
|
||||||
return { value: hours, unit: "hours" };
|
if (s % 3600 === 0) return { value: s / 3600, unit: "hours" };
|
||||||
|
return { value: s, unit: "seconds" };
|
||||||
}
|
}
|
||||||
|
|
||||||
function intervalUiToSec(value: number, unit: "days" | "hours") {
|
function intervalUiToSec(value: number, unit: "days" | "hours" | "seconds") {
|
||||||
const n = Math.max(1, Number(value) || 1);
|
const n = Math.max(1, Number(value) || 1);
|
||||||
return unit === "days" ? n * 86400 : n * 3600;
|
if (unit === "days") return n * 86400;
|
||||||
|
if (unit === "hours") return n * 3600;
|
||||||
|
return Math.max(60, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
function intervalUnitMax(unit: "days" | "hours" | "seconds") {
|
||||||
|
if (unit === "days") return 365;
|
||||||
|
if (unit === "hours") return 8760;
|
||||||
|
return 604800; // up to 7 days in seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertIntervalValue(
|
||||||
|
value: number,
|
||||||
|
from: "days" | "hours" | "seconds",
|
||||||
|
to: "days" | "hours" | "seconds",
|
||||||
|
) {
|
||||||
|
const sec = intervalUiToSec(value, from);
|
||||||
|
if (to === "days") return Math.max(1, Math.min(365, Math.round(sec / 86400) || 1));
|
||||||
|
if (to === "hours") return Math.max(1, Math.min(8760, Math.round(sec / 3600) || 1));
|
||||||
|
return Math.max(60, Math.min(604800, sec));
|
||||||
}
|
}
|
||||||
|
|
||||||
function fmtTime(v?: string | null) {
|
function fmtTime(v?: string | null) {
|
||||||
|
|
@ -202,7 +228,7 @@ export function BizStatePage() {
|
||||||
const [batches, setBatches] = useState<BatchRow[]>([]);
|
const [batches, setBatches] = useState<BatchRow[]>([]);
|
||||||
const [taskTab, setTaskTab] = useState<TaskTab>("profiles");
|
const [taskTab, setTaskTab] = useState<TaskTab>("profiles");
|
||||||
const [intervalValue, setIntervalValue] = useState(1);
|
const [intervalValue, setIntervalValue] = useState(1);
|
||||||
const [intervalUnit, setIntervalUnit] = useState<"days" | "hours">("hours");
|
const [intervalUnit, setIntervalUnit] = useState<"days" | "hours" | "seconds">("hours");
|
||||||
const [retentionBatches, setRetentionBatches] = useState(30);
|
const [retentionBatches, setRetentionBatches] = useState(30);
|
||||||
|
|
||||||
// VRF bind (inside task modal)
|
// VRF bind (inside task modal)
|
||||||
|
|
@ -612,6 +638,7 @@ export function BizStatePage() {
|
||||||
Number(row.interval_sec || 3600),
|
Number(row.interval_sec || 3600),
|
||||||
t("bizState.intervalUnitDays"),
|
t("bizState.intervalUnitDays"),
|
||||||
t("bizState.intervalUnitHours"),
|
t("bizState.intervalUnitHours"),
|
||||||
|
t("bizState.intervalUnitSeconds"),
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -823,29 +850,32 @@ export function BizStatePage() {
|
||||||
<span>{t("bizState.interval")}</span>
|
<span>{t("bizState.interval")}</span>
|
||||||
<Input
|
<Input
|
||||||
type="number"
|
type="number"
|
||||||
min={1}
|
min={intervalUnit === "seconds" ? 60 : 1}
|
||||||
max={intervalUnit === "days" ? 365 : 8760}
|
max={intervalUnitMax(intervalUnit)}
|
||||||
value={String(intervalValue)}
|
value={String(intervalValue)}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const max = intervalUnit === "days" ? 365 : 8760;
|
const min = intervalUnit === "seconds" ? 60 : 1;
|
||||||
setIntervalValue(Math.max(1, Math.min(max, Number(e.target.value) || 1)));
|
const max = intervalUnitMax(intervalUnit);
|
||||||
|
setIntervalValue(Math.max(min, Math.min(max, Number(e.target.value) || min)));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<select
|
<select
|
||||||
value={intervalUnit}
|
value={intervalUnit}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const next = e.target.value === "hours" ? "hours" : "days";
|
const next =
|
||||||
|
e.target.value === "seconds"
|
||||||
|
? "seconds"
|
||||||
|
: e.target.value === "hours"
|
||||||
|
? "hours"
|
||||||
|
: "days";
|
||||||
if (next === intervalUnit) return;
|
if (next === intervalUnit) return;
|
||||||
if (next === "hours") {
|
setIntervalValue(convertIntervalValue(intervalValue, intervalUnit, next));
|
||||||
setIntervalValue(Math.max(1, Math.min(8760, intervalValue * 24)));
|
|
||||||
} else {
|
|
||||||
setIntervalValue(Math.max(1, Math.min(365, Math.round(intervalValue / 24) || 1)));
|
|
||||||
}
|
|
||||||
setIntervalUnit(next);
|
setIntervalUnit(next);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<option value="days">{t("bizState.intervalUnitDays")}</option>
|
<option value="seconds">{t("bizState.intervalUnitSeconds")}</option>
|
||||||
<option value="hours">{t("bizState.intervalUnitHours")}</option>
|
<option value="hours">{t("bizState.intervalUnitHours")}</option>
|
||||||
|
<option value="days">{t("bizState.intervalUnitDays")}</option>
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
<label className="config-sync-policy-field">
|
<label className="config-sync-policy-field">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue