mirror of
https://github.com/hansjone/netx.git
synced 2026-10-09 05:30:46 +08:00
fix(collect): stabilize start flow and default collapse create panel
Avoid false running-state conflicts when starting draft jobs, block overlapping NE runs across jobs, and default the create panel to collapsed for cleaner task-first operation. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
52f1b63b18
commit
d512679425
6 changed files with 87 additions and 11 deletions
|
|
@ -60,6 +60,8 @@ const en = {
|
|||
added: "Added",
|
||||
create: "Create job",
|
||||
creating: "Creating…",
|
||||
expand: "Expand",
|
||||
collapse: "Collapse",
|
||||
meta: "{{ne}} NE(s) selected · {{cmd}} command(s)",
|
||||
},
|
||||
eligible: {
|
||||
|
|
@ -85,6 +87,8 @@ const en = {
|
|||
retryFailedDone: "Retrying failed devices",
|
||||
deleted: "Job deleted",
|
||||
nothingToRetry: "No failed devices to retry",
|
||||
neBusy: "Some NEs are busy in another collection job; wait for it to finish before starting",
|
||||
jobRunning: "This job is already running",
|
||||
confirmDelete: "Delete this collection job and its log files?",
|
||||
jobs: {
|
||||
title: "Collection jobs",
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ const zh = {
|
|||
added: "已添加",
|
||||
create: "创建任务",
|
||||
creating: "创建中…",
|
||||
expand: "展开",
|
||||
collapse: "收起",
|
||||
meta: "已选 {{ne}} 台网元 · {{cmd}} 条命令",
|
||||
},
|
||||
eligible: {
|
||||
|
|
@ -85,6 +87,8 @@ const zh = {
|
|||
retryFailedDone: "已开始重采失败网元",
|
||||
deleted: "任务已删除",
|
||||
nothingToRetry: "没有可重试的失败网元",
|
||||
neBusy: "部分网元正在被其他采集任务占用,请等待其完成后再开始",
|
||||
jobRunning: "该任务已在执行中",
|
||||
confirmDelete: "确定删除该采集任务?相关日志文件将一并删除。",
|
||||
jobs: {
|
||||
title: "采集任务",
|
||||
|
|
|
|||
|
|
@ -909,6 +909,14 @@ pre {
|
|||
margin-right: auto;
|
||||
}
|
||||
|
||||
.collect-create-panel__head {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.collect-create-panel--collapsed {
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.collect-create-panel h3 {
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,13 @@ import { formatSystemTime } from "../utils/time";
|
|||
const POLL_MS = 2000;
|
||||
const ELIGIBLE_PAGE_SIZE = 20;
|
||||
|
||||
function collectionErrorMessage(err: unknown, t: (key: string) => string): string {
|
||||
const raw = String(err);
|
||||
if (raw.includes("collection_ne_busy")) return t("collect.neBusy");
|
||||
if (raw.includes("collection_job_running")) return t("collect.jobRunning");
|
||||
return raw;
|
||||
}
|
||||
|
||||
export function CollectPage() {
|
||||
const { t } = useI18n();
|
||||
const { showOk, showError } = useToast();
|
||||
|
|
@ -36,6 +43,7 @@ export function CollectPage() {
|
|||
const [nePage, setNePage] = useState(1);
|
||||
const [jobPage, setJobPage] = useState(1);
|
||||
const [expandedJobId, setExpandedJobId] = useState("");
|
||||
const [createOpen, setCreateOpen] = useState(false);
|
||||
|
||||
const selectedIds = useMemo(() => Object.keys(selectedMap), [selectedMap]);
|
||||
const selectedList = useMemo(() => Object.values(selectedMap), [selectedMap]);
|
||||
|
|
@ -98,7 +106,7 @@ export function CollectPage() {
|
|||
showOk(t("collect.paused"));
|
||||
await invalidateJobs(job.id);
|
||||
},
|
||||
onError: (err) => showError(String(err)),
|
||||
onError: (err) => showError(collectionErrorMessage(err, t)),
|
||||
});
|
||||
|
||||
const startJobMutation = useMutation({
|
||||
|
|
@ -108,7 +116,7 @@ export function CollectPage() {
|
|||
setExpandedJobId(job.id);
|
||||
await invalidateJobs(job.id);
|
||||
},
|
||||
onError: (err) => showError(String(err)),
|
||||
onError: (err) => showError(collectionErrorMessage(err, t)),
|
||||
});
|
||||
|
||||
const retryFailedMutation = useMutation({
|
||||
|
|
@ -140,6 +148,7 @@ export function CollectPage() {
|
|||
}),
|
||||
onSuccess: async (job) => {
|
||||
showOk(t("collect.created", { id: job.id }));
|
||||
setCreateOpen(false);
|
||||
setExpandedJobId(job.id);
|
||||
await queryClient.invalidateQueries({ queryKey: queryKeys.neCollectionsAll });
|
||||
await queryClient.invalidateQueries({ queryKey: queryKeys.neCollectionDetail(job.id) });
|
||||
|
|
@ -199,12 +208,23 @@ export function CollectPage() {
|
|||
|
||||
return (
|
||||
<div className="page-stack">
|
||||
<section className="panel collect-create-panel">
|
||||
<div>
|
||||
<h2>{t("collect.create.title")}</h2>
|
||||
<p className="panel__hint">{t("collect.create.hint")}</p>
|
||||
<section className={`panel collect-create-panel${createOpen ? "" : " collect-create-panel--collapsed"}`}>
|
||||
<div className="panel__toolbar collect-create-panel__head">
|
||||
<div>
|
||||
<h2>{t("collect.create.title")}</h2>
|
||||
<p className="panel__hint">
|
||||
{createOpen
|
||||
? t("collect.create.hint")
|
||||
: t("collect.create.meta", { ne: selectedIds.length, cmd: commandLines })}
|
||||
</p>
|
||||
</div>
|
||||
<button type="button" className="link-btn" onClick={() => setCreateOpen((open) => !open)}>
|
||||
{createOpen ? t("collect.create.collapse") : t("collect.create.expand")}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{createOpen ? (
|
||||
<>
|
||||
<div className="form-grid form-grid--single">
|
||||
<label className="form-grid__full">
|
||||
{t("collect.form.jobTitle")}
|
||||
|
|
@ -406,6 +426,8 @@ export function CollectPage() {
|
|||
{createMutation.isPending ? t("collect.create.creating") : t("collect.create.create")}
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
) : null}
|
||||
</section>
|
||||
|
||||
<section className="panel">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue