fix(workbench): hold refresh feedback

This commit is contained in:
2026-09-24 12:57:16 +08:00
parent 0a53e665eb
commit 2191efab2f
2 changed files with 28 additions and 5 deletions
@@ -10,7 +10,7 @@ import {
XCircle
} from "lucide-react";
import { AnimatePresence, motion } from "motion/react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { MAP_TOOL_PANEL_SURFACE_CLASS_NAME, showMapNotice } from "@/features/map/core";
import { isGeneratedScheduledConditionSessionId } from "../data/scheduled-conditions";
import type {
@@ -62,6 +62,7 @@ const CONDITION_CONTENT_SURFACE_CLASS_NAME =
"surface-reading rounded-xl border border-slate-200/70";
const CONDITION_CONTROL_SURFACE_CLASS_NAME =
"surface-control rounded-xl border border-slate-200/70";
const MINIMUM_REFRESH_FEEDBACK_MS = 3_000;
export type ScheduledConditionFeedPresentation =
| "desktop-dock"
@@ -156,6 +157,7 @@ export function ScheduledConditionFeed({
const [scheduleSubmitting, setScheduleSubmitting] = useState(false);
const [scheduleError, setScheduleError] = useState<string | null>(null);
const [refreshing, setRefreshing] = useState(false);
const refreshingRef = useRef(false);
const mobileSheet = presentation === "mobile-sheet";
const desktopDock = presentation === "desktop-dock";
const compactPresentation = mobileSheet || desktopDock;
@@ -335,19 +337,32 @@ export function ScheduledConditionFeed({
}
async function handleRefresh() {
if (!onRefresh || refreshing) return;
if (!onRefresh || refreshingRef.current) return;
refreshingRef.current = true;
setRefreshing(true);
const startedAt = Date.now();
let refreshError: unknown = null;
try {
await onRefresh();
} catch (error) {
refreshError = error;
} finally {
const remainingFeedbackMs = MINIMUM_REFRESH_FEEDBACK_MS - (Date.now() - startedAt);
if (remainingFeedbackMs > 0) {
await new Promise((resolve) => window.setTimeout(resolve, remainingFeedbackMs));
}
refreshingRef.current = false;
setRefreshing(false);
}
if (refreshError) {
showMapNotice({
id: "scheduled-condition-refresh",
tone: "error",
title: "工况任务刷新失败",
message: error instanceof Error ? error.message : "暂时无法重新获取工况任务。"
message: refreshError instanceof Error
? refreshError.message
: "暂时无法重新获取工况任务。"
});
} finally {
setRefreshing(false);
}
}
@@ -271,8 +271,16 @@ test("审批动作展示中文参数和证据,viewer 不可审批,冲突后
await expect(conditionPanel.getByRole("button", { name: /预约任务/ })).toContainText("后端");
const conditionRefreshButton = conditionPanel.getByRole("button", { name: "刷新工况任务" });
await expect(conditionRefreshButton).toBeVisible();
const refreshStartedAt = Date.now();
await conditionRefreshButton.click();
await expect.poll(() => snapshotRequests).toBe(2);
const refreshingButton = conditionPanel.getByRole("button", { name: "正在刷新工况任务" });
await expect(refreshingButton).toBeDisabled();
await refreshingButton.evaluate((button: HTMLButtonElement) => button.click());
await page.waitForTimeout(500);
expect(snapshotRequests).toBe(2);
await expect(conditionRefreshButton).toBeEnabled({ timeout: 4_000 });
expect(Date.now() - refreshStartedAt).toBeGreaterThanOrEqual(2_900);
await conditionPanel.getByRole("button", { name: "配置定时流程" }).click();
await conditionPanel.getByLabel("定时流程名称").fill("夜间阀门巡检");
await conditionPanel.getByLabel("任务说明").fill("每十五分钟检查预约维修涉及的边界阀门。");