Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | 22318x 22318x 22318x 22318x 22318x 22318x 22318x 374x 374x 22318x 6x 22318x 4x 74x 74x 74x 72x 72x 72x 72x 22318x | import { useState } from "react";
import { toast } from "sonner";
import { useUpdateTaskCache } from "@/hooks/cache/useUpdateTaskCache.ts";
import { useFlowsheetAccess } from "@/hooks/flowsheetAccess";
import { useCurrentGroupId } from "@/hooks/flowsheetObjects";
import {
useTaskCancelledSubscription,
useTaskCancellingSubscription,
useTaskCompletedSubscription,
} from "@/hooks/notifications/notificationSubscriptions.ts";
import { useSearchParam } from "@/hooks/searchParams";
import { store } from "@/store/store";
import {
api,
TaskStatusEnum as StatusEnum,
useIdaesSolveCreateMutation,
} from "../../../../api/apiStore.gen";
import { ContentTypes } from "../LeftSideBar/LeftSideBarTabDefinitions";
export function useSolve() {
const [requestSolve] = useIdaesSolveCreateMutation();
const updateTaskCache = useUpdateTaskCache();
const [solveRunning, setSolveRunning] = useState(false);
const groupId = useCurrentGroupId();
const access = useFlowsheetAccess();
const [, setContent] = useSearchParam("content");
// Subscribe to notifications of solve task completion
useTaskCompletedSubscription((message) => {
setSolveRunning(false);
console.log("solve task finished:", message); // This is helpful for debugging why the playwright tests are failing to solve, so I recommend leaving it in.
});
useTaskCancelledSubscription(() => {
setSolveRunning(false);
});
useTaskCancellingSubscription(() => {
setSolveRunning(false);
});
const solve = async (
scenarioNumber?: number,
perform_diagnostics?: boolean,
) => {
if (access?.can_edit === false) {
toast.warning("This flowsheet is read-only", {
description: "Make a copy to edit or solve this flowsheet.",
});
return;
}
try {
setSolveRunning(true);
// Wait for any current mutations to finish before starting the solve, to make sure all updates are complete.
await Promise.all(store.dispatch(api.util.getRunningMutationsThunk()));
const response = await requestSolve({
solveRequest: {
group_id: groupId,
perform_diagnostics,
scenario_number: scenarioNumber,
// is_rating_mode: ratingMode
},
}).unwrap();
updateTaskCache(response);
console.log("Solve task started:", response); // This is helpful for debugging why the playwright tests are failing to solve, so I recommend leaving it in.
if (
response.status === StatusEnum.Pending ||
response.status === StatusEnum.Running
)
toast.success("Solve started successfully", {
description: "A flowsheet solve is in progress.",
});
else {
setSolveRunning(false);
setContent(ContentTypes.solverLogs); // so the user can see the logs immediately
const error = response.error;
console.error("Error solving with idaes.");
console.error(error);
toast.error("Solve could not be started", {
description: solveErrorDescription(error),
});
}
return response;
// Known errors are handled at the task processing layer,
// but we still need to catch unknown errors here
} catch (error: unknown) {
setSolveRunning(false);
toast.error("Solve could not be started", {
description: solveErrorDescription(error),
});
}
};
return [solve, solveRunning] as const;
}
function solveErrorDescription(error: unknown) {
const fallback = "Open solver logs for details.";
Iif (!error) return fallback;
Iif (typeof error === "string") return error;
Iif (typeof error !== "object") return fallback;
const detail = stringField(error, "detail");
Iif (detail) return detail;
const data = (error as { data?: unknown }).data;
Iif (typeof data === "string") return data;
if (data && typeof data === "object") {
const dataDetail = stringField(data, "detail");
Iif (dataDetail) return dataDetail;
const dataError = stringField(data, "error");
Iif (dataError) return dataError;
}
const cause = stringField(error, "cause");
const message = stringField(error, "message");
Iif (cause && message) return `${cause}: ${message}`;
Iif (message) return message;
Iif (cause) return cause;
return fallback;
}
function stringField(source: object, key: string) {
const value = (source as Record<string, unknown>)[key];
return typeof value === "string" ? value : "";
}
|