fix(workbench): hold refresh feedback
This commit is contained in:
@@ -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("每十五分钟检查预约维修涉及的边界阀门。");
|
||||
|
||||
Reference in New Issue
Block a user