Add fleet groups, agent screenshots, deploy guards, and Crucible polish.

This commit is contained in:
AetherForge
2026-06-02 20:51:52 -07:00
parent 01d76b3730
commit 41b5ec7a88
66 changed files with 1773 additions and 388 deletions

View File

@@ -0,0 +1,81 @@
import type { FleetGroup } from '../../help/fleetGroups';
import './FleetGroupsStrip.css';
interface Props {
groups: FleetGroup[];
liveAgentIds?: Set<string>;
onSelectGroup: (group: FleetGroup) => void;
onDeleteGroup?: (id: string) => void;
onCreateGroup?: () => void;
selectedCount?: number;
}
export default function FleetGroupsStrip({
groups,
liveAgentIds,
onSelectGroup,
onDeleteGroup,
onCreateGroup,
selectedCount = 0,
}: Props) {
if (groups.length === 0 && !onCreateGroup) return null;
return (
<div className="fleet-groups-strip card">
<span className="fleet-groups-strip-label font-tech">Groups</span>
<div className="fleet-groups-strip-list">
{groups.map((g) => {
const onlineInGroup = liveAgentIds
? g.agentIds.filter((id) => liveAgentIds.has(id)).length
: g.agentIds.length;
return (
<button
key={g.id}
type="button"
className="fleet-group-chip"
style={
{
'--group-color': g.color,
borderColor: `${g.color}66`,
background: `${g.color}18`,
} as React.CSSProperties
}
title={`Select ${g.name} (${onlineInGroup} online / ${g.agentIds.length} total)`}
onClick={() => onSelectGroup(g)}
>
<span className="fleet-group-chip-dot" style={{ background: g.color }} />
<span className="fleet-group-chip-name">{g.name}</span>
<span className="fleet-group-chip-count">{g.agentIds.length}</span>
{onDeleteGroup && (
<span
className="fleet-group-chip-del"
role="button"
tabIndex={0}
aria-label={`Delete group ${g.name}`}
onClick={(e) => {
e.stopPropagation();
if (window.confirm(`Delete group "${g.name}"?`)) onDeleteGroup(g.id);
}}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
e.stopPropagation();
if (window.confirm(`Delete group "${g.name}"?`)) onDeleteGroup(g.id);
}
}}
>
×
</span>
)}
</button>
);
})}
</div>
{onCreateGroup && selectedCount > 0 && (
<button type="button" className="btn btn-outline btn-sm" onClick={onCreateGroup}>
+ Create group ({selectedCount})
</button>
)}
</div>
);
}