fix: stabilize cron scheduling and run history
This commit is contained in:
@@ -141,19 +141,38 @@ export default function SchedulePage({
|
||||
setArtifacts([]);
|
||||
setSchedule(null);
|
||||
setRuns([]);
|
||||
setRunsLoading(true);
|
||||
setRunsLoading(false);
|
||||
void useSchedulesStore.getState().loadInitial();
|
||||
}, [workspaceId, api, setSchedules, setArtifacts, setSchedule]);
|
||||
|
||||
// 进入调度页或切换调度方案后,主动加载该方案已经存在的运行记录。
|
||||
// 原先只有「手动运行」和运行中的轮询会更新列表,因此从其他页面返回时会
|
||||
// 一直停留在加载状态,直到产生新的运行记录。
|
||||
useEffect(() => {
|
||||
const scheduleId = schedule?.schedule_id;
|
||||
if (!scheduleId || !api) {
|
||||
setRuns([]);
|
||||
setRunsLoading(false);
|
||||
return;
|
||||
}
|
||||
void useSchedulesStore.getState().refreshRuns(scheduleId, true);
|
||||
}, [schedule?.schedule_id, api, setRuns, setRunsLoading]);
|
||||
|
||||
useEffect(() => {
|
||||
const scheduleId = schedule?.schedule_id;
|
||||
if (!scheduleId || !api) return;
|
||||
if (!runs.some((item) => item.run_status === "queued" || item.run_status === "running")) return;
|
||||
const hasActiveRun = runs.some(
|
||||
(item) => item.run_status === "queued" || item.run_status === "running",
|
||||
);
|
||||
const isEnabledCron = schedule.trigger_type === "cron" && schedule.enabled;
|
||||
// Cron 会由后端在未来某个整分钟创建新记录。即使当前没有运行中的
|
||||
// 记录,也要持续刷新,才能让新一轮运行自动出现在右侧列表中。
|
||||
if (!hasActiveRun && !isEnabledCron) return;
|
||||
const timer = window.setInterval(() => {
|
||||
void useSchedulesStore.getState().refreshRuns(scheduleId);
|
||||
}, 1500);
|
||||
}, hasActiveRun ? 1500 : 3000);
|
||||
return () => window.clearInterval(timer);
|
||||
}, [schedule?.schedule_id, runs, api]);
|
||||
}, [schedule?.schedule_id, schedule?.trigger_type, schedule?.enabled, runs, api]);
|
||||
|
||||
// Form submit wrapper for create-schedule modal — keeps the FormEvent flow out of JSX.
|
||||
const handleCreateScheduleSubmit = (event: FormEvent<HTMLFormElement>): void => {
|
||||
@@ -292,10 +311,15 @@ export default function SchedulePage({
|
||||
}}
|
||||
onDrop={onCanvasDrop}
|
||||
onClick={(event) => {
|
||||
if (event.target === event.currentTarget) {
|
||||
setSelectedNodeId(null);
|
||||
setSelectedEdgeId(null);
|
||||
}
|
||||
// 画布实际内容位于 surface/SVG 子元素中,不能只比较 currentTarget;
|
||||
// 点击节点或连线时保留选择,点击其余空白位置则返回调度方案基本信息。
|
||||
const target = event.target as Element;
|
||||
if (
|
||||
target.closest(".schedule-node") ||
|
||||
target.matches(".schedule-edge-line, .schedule-edge-hit")
|
||||
) return;
|
||||
setSelectedNodeId(null);
|
||||
setSelectedEdgeId(null);
|
||||
}}
|
||||
>
|
||||
<div
|
||||
|
||||
@@ -553,7 +553,11 @@ export const useSchedulesStore = create<State & Actions>((set, get) => {
|
||||
} catch (error) {
|
||||
if (showLoading) await handleError(error, "运行记录加载失败");
|
||||
} finally {
|
||||
if (showLoading) set({ runsLoading: false });
|
||||
// 如果用户已切换到另一个调度方案,不能让旧请求结束时覆盖新方案的
|
||||
// 加载状态;新方案会由自己的请求负责关闭 loading。
|
||||
if (showLoading && get().schedule?.schedule_id === scheduleId) {
|
||||
set({ runsLoading: false });
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user