feat(workbench): integrate operational workflows and map state
This commit is contained in:
@@ -2,7 +2,6 @@ import { useEffect, useState } from "react";
|
||||
import type { AccessTokenProvider } from "@/shared/auth/keycloak-auth";
|
||||
import { env } from "@/shared/config/env";
|
||||
import {
|
||||
fetchWorkbenchRuntimeSnapshot,
|
||||
type WorkbenchRuntimeSnapshot
|
||||
} from "../api/workbench-runtime-client";
|
||||
import { fetchRealtimePipeFlows } from "../api/realtime-flow-client";
|
||||
@@ -13,6 +12,7 @@ import {
|
||||
import { WORKBENCH_SCENARIOS } from "../data/workbench-session";
|
||||
import type { ScheduledConditionItem } from "../types";
|
||||
import { createScheduledConditionAlerts } from "../utils/scheduled-condition-alerts";
|
||||
import type { WorkbenchSyncState } from "./use-workbench-sync";
|
||||
|
||||
const HEADER_DATA_TIME_STEP_MINUTES = 5;
|
||||
const INITIAL_HEADER_DATA_TIME = "同步中";
|
||||
@@ -80,6 +80,10 @@ export function resolveWorkbenchRuntimeData(
|
||||
(condition) => condition.kind === "condition"
|
||||
&& isSameLocalOperationalDate(condition.scheduledAt, operationalDate)
|
||||
);
|
||||
const demoWorkOrders = mockConditions.filter(
|
||||
(condition) => condition.kind === "work_order"
|
||||
&& isSameLocalOperationalDate(condition.scheduledAt, operationalDate)
|
||||
);
|
||||
const backendWorkOrders = (backendSnapshot?.workOrders ?? []).filter(
|
||||
(workOrder) => isSameLocalOperationalDate(workOrder.scheduledAt, operationalDate)
|
||||
);
|
||||
@@ -103,7 +107,7 @@ export function resolveWorkbenchRuntimeData(
|
||||
);
|
||||
|
||||
return {
|
||||
scheduledConditions: [...fallbackConditions, ...resolvedWorkOrders],
|
||||
scheduledConditions: [...fallbackConditions, ...demoWorkOrders, ...resolvedWorkOrders],
|
||||
workbenchAlerts: backendAlertsConfigured
|
||||
? backendSnapshot!.alerts
|
||||
: createScheduledConditionAlerts(fallbackConditions),
|
||||
@@ -128,10 +132,13 @@ function isSameLocalOperationalDate(value: string, operationalDate: Date) {
|
||||
&& candidate.getDate() === operationalDate.getDate();
|
||||
}
|
||||
|
||||
export function useWorkbenchRuntimeData(getAccessToken?: AccessTokenProvider) {
|
||||
export function useWorkbenchRuntimeData(
|
||||
getAccessToken: AccessTokenProvider | undefined,
|
||||
sync: WorkbenchSyncState
|
||||
) {
|
||||
const [headerDataTime, setHeaderDataTime] = useState(INITIAL_HEADER_DATA_TIME);
|
||||
const [mockConditions, setMockConditions] = useState<ScheduledConditionItem[]>([]);
|
||||
const [backendSnapshot, setBackendSnapshot] = useState<WorkbenchRuntimeSnapshot | null>(null);
|
||||
const backendSnapshot: WorkbenchRuntimeSnapshot | null = sync.snapshot?.runtime ?? null;
|
||||
const [realtimePipeFlows, setRealtimePipeFlows] = useState<Awaited<
|
||||
ReturnType<typeof fetchRealtimePipeFlows>
|
||||
> | null>(null);
|
||||
@@ -168,40 +175,15 @@ export function useWorkbenchRuntimeData(getAccessToken?: AccessTokenProvider) {
|
||||
return () => window.clearInterval(intervalId);
|
||||
}, [backendSnapshot]);
|
||||
|
||||
useEffect(() => {
|
||||
const controller = new AbortController();
|
||||
let timeoutId: number | undefined;
|
||||
|
||||
const refreshBackendSnapshot = async () => {
|
||||
try {
|
||||
const snapshot = await fetchWorkbenchRuntimeSnapshot(getAccessToken, controller.signal);
|
||||
if (!controller.signal.aborted) {
|
||||
setBackendSnapshot(snapshot);
|
||||
}
|
||||
} catch {
|
||||
if (!controller.signal.aborted) setBackendSnapshot(null);
|
||||
} finally {
|
||||
if (!controller.signal.aborted) {
|
||||
timeoutId = window.setTimeout(
|
||||
refreshBackendSnapshot,
|
||||
BACKEND_RUNTIME_REFRESH_INTERVAL_MS
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void refreshBackendSnapshot();
|
||||
return () => {
|
||||
controller.abort();
|
||||
if (timeoutId !== undefined) window.clearTimeout(timeoutId);
|
||||
};
|
||||
}, [getAccessToken]);
|
||||
|
||||
useEffect(() => {
|
||||
const controller = new AbortController();
|
||||
let timeoutId: number | undefined;
|
||||
|
||||
const refreshRealtimePipeFlows = async () => {
|
||||
if (document.visibilityState === "hidden") {
|
||||
timeoutId = window.setTimeout(refreshRealtimePipeFlows, BACKEND_RUNTIME_REFRESH_INTERVAL_MS);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const snapshot = await fetchRealtimePipeFlows(getAccessToken, controller.signal);
|
||||
if (!controller.signal.aborted) {
|
||||
@@ -219,9 +201,17 @@ export function useWorkbenchRuntimeData(getAccessToken?: AccessTokenProvider) {
|
||||
}
|
||||
};
|
||||
|
||||
const handleVisibilityChange = () => {
|
||||
if (document.visibilityState !== "visible") return;
|
||||
if (timeoutId !== undefined) window.clearTimeout(timeoutId);
|
||||
void refreshRealtimePipeFlows();
|
||||
};
|
||||
|
||||
void refreshRealtimePipeFlows();
|
||||
document.addEventListener("visibilitychange", handleVisibilityChange);
|
||||
return () => {
|
||||
controller.abort();
|
||||
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
||||
if (timeoutId !== undefined) window.clearTimeout(timeoutId);
|
||||
};
|
||||
}, [getAccessToken]);
|
||||
|
||||
Reference in New Issue
Block a user