forked from phenom/healer-man
Release Healer Man 0.1.47
This commit is contained in:
1 parent
9ff574ac0b
commit
2162039b49
24 files changed
+486
-55
No files matched your search
@@ -5,11 +5,13 @@ import {
|
||||
fetchBalanceLabArtifact,
|
||||
getBalanceLabJob,
|
||||
getBalanceLabReport,
|
||||
getBalanceLabRuntime,
|
||||
listBalanceLabJobs,
|
||||
startBalanceLabJob,
|
||||
type BalanceLabBossCategory,
|
||||
type BalanceLabJob,
|
||||
type BalanceLabPartySource,
|
||||
type BalanceLabRuntimeStatus,
|
||||
type BalanceLabSuiteReport,
|
||||
} from "../app/balanceLabClient";
|
||||
import { BOSS_TESTING_CATALOG } from "../game/bossTesting";
|
||||
@@ -77,6 +79,7 @@ export function BalanceLabScreen({ onClose }: { readonly onClose: () => void })
|
||||
const [reports, setReports] = useState<Readonly<Record<string, BalanceLabSuiteReport>>>({});
|
||||
const [reportLoadingId, setReportLoadingId] = useState<string | null>(null);
|
||||
const [reportError, setReportError] = useState("");
|
||||
const [runtimeStatus, setRuntimeStatus] = useState<BalanceLabRuntimeStatus | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
@@ -106,9 +109,10 @@ export function BalanceLabScreen({ onClose }: { readonly onClose: () => void })
|
||||
if (!token) return;
|
||||
let cancelled = false;
|
||||
setLoading(true);
|
||||
void listBalanceLabJobs(token).then((nextJobs) => {
|
||||
void Promise.all([listBalanceLabJobs(token), getBalanceLabRuntime(token)]).then(([nextJobs, runtime]) => {
|
||||
if (cancelled) return;
|
||||
setJobs(nextJobs);
|
||||
setRuntimeStatus(runtime);
|
||||
setSelectedJobId((current) => current ?? nextJobs[0]?.id ?? null);
|
||||
setError("");
|
||||
}).catch((reason) => {
|
||||
@@ -169,6 +173,10 @@ export function BalanceLabScreen({ onClose }: { readonly onClose: () => void })
|
||||
};
|
||||
|
||||
const run = async () => {
|
||||
if (!runtimeStatus?.available) {
|
||||
setError(runtimeStatus?.error ?? "The server Balance Lab runtime is unavailable.");
|
||||
return;
|
||||
}
|
||||
if (bossScope === "specific" && selectedBossKeys.length === 0) {
|
||||
setError("Select at least one boss for a specific-boss run.");
|
||||
return;
|
||||
@@ -229,6 +237,10 @@ export function BalanceLabScreen({ onClose }: { readonly onClose: () => void })
|
||||
<p className="front-kicker">New automatic sweep</p>
|
||||
<h2>Simulation setup</h2>
|
||||
<p className="balance-lab-help">This mode runs on the game server. The browser submits the job and may be closed while the server continues.</p>
|
||||
{runtimeStatus && <div className={`balance-lab-runtime ${runtimeStatus.available ? "is-ready" : "is-unavailable"}`} role={runtimeStatus.available ? undefined : "alert"}>
|
||||
<strong>{runtimeStatus.available ? "Server runtime ready" : "Server runtime unavailable"}</strong>
|
||||
<span>{runtimeStatus.available ? runtimeStatus.version : `${runtimeStatus.error} Install Python 3 in the server container, set BALANCE_LAB_PYTHON=python3, and restart the app.`}</span>
|
||||
</div>}
|
||||
<div className="balance-lab-form-grid">
|
||||
<label><span>Party source</span><select value={source} onChange={(event) => setSource(event.currentTarget.value as BalanceLabPartySource)}>
|
||||
<option value="all">WoW + CoA + RoM</option><option value="wow">WoW only</option><option value="coa">CoA only</option><option value="rom">RoM only</option>
|
||||
@@ -254,7 +266,7 @@ export function BalanceLabScreen({ onClose }: { readonly onClose: () => void })
|
||||
</section>
|
||||
)}
|
||||
<div className="balance-lab-estimate"><span>Party configurations <b>{partyCount.toLocaleString()}</b></span><span>Bosses <b>{bossCount.toLocaleString()}</b></span><span>Total simulations <b>{estimatedRuns.toLocaleString()}</b></span></div>
|
||||
<button className="front-button front-button--primary balance-lab-run" type="button" disabled={submitting || !Number.isFinite(estimatedRuns) || estimatedRuns < 1} onClick={() => void run()}>{submitting ? "Queuing…" : "Run on server"}</button>
|
||||
<button className="front-button front-button--primary balance-lab-run" type="button" disabled={submitting || !runtimeStatus?.available || !Number.isFinite(estimatedRuns) || estimatedRuns < 1} onClick={() => void run()}>{submitting ? "Queuing…" : runtimeStatus && !runtimeStatus.available ? "Server runtime unavailable" : "Run on server"}</button>
|
||||
<p className="balance-lab-local-note">To spend this device's CPU instead, run <code>npm run balance:lab</code> from the project checkout.</p>
|
||||
{error && <p className="front-notice" role="alert">{error}</p>}
|
||||
</section>
|
||||
@@ -262,7 +274,7 @@ export function BalanceLabScreen({ onClose }: { readonly onClose: () => void })
|
||||
<section className="balance-lab-jobs">
|
||||
<header><div><p className="front-kicker">Saved on server</p><h2>Run history</h2></div><button type="button" disabled={loading} onClick={() => {
|
||||
setLoading(true);
|
||||
void listBalanceLabJobs(token).then(setJobs).catch((reason) => setError(errorMessage(reason))).finally(() => setLoading(false));
|
||||
void Promise.all([listBalanceLabJobs(token), getBalanceLabRuntime(token)]).then(([nextJobs, runtime]) => { setJobs(nextJobs); setRuntimeStatus(runtime); }).catch((reason) => setError(errorMessage(reason))).finally(() => setLoading(false));
|
||||
}}>Refresh</button></header>
|
||||
<div className="balance-lab-history-filters"><input type="search" aria-label="Search Balance Lab run history" placeholder="Find source, level, GM…" value={jobSearch} onChange={(event) => setJobSearch(event.currentTarget.value)} /><select aria-label="Filter Balance Lab run status" value={jobStatus} onChange={(event) => setJobStatus(event.currentTarget.value as "all" | BalanceLabJob["status"])}><option value="all">All statuses</option><option value="complete">Complete</option><option value="running">Running</option><option value="queued">Queued</option><option value="failed">Failed</option></select></div>
|
||||
<div className="balance-lab-job-list">
|
||||
|
||||
Reference in new issue
Block a user