Link existing bots from the workspace rail's "+"

The "+" beside "Workspace bots" now opens a modal listing the crew's
workers not in the workspace yet (api/admin/workspaces/linkable-bots),
each added in one click, with "New bot" stacking the bot form over it.
Adding a bot to a workspace now pushes server:bot-created so other
rails pick it up live.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-19 20:37:25 +01:00
co-authored by Claude Opus 5.5
parent 139b3e443d
commit bf7109952b
8 changed files with 282 additions and 15 deletions
@@ -0,0 +1,46 @@
import Button from "@moduletrace/twui/layout/Button";
import Row from "@moduletrace/twui/layout/Row";
import Span from "@moduletrace/twui/layout/Span";
import Stack from "@moduletrace/twui/layout/Stack";
import BotAvatar from "@/src/components/general/bot-avatar";
import type { BotFace, BotHue } from "@/src/dict/bot-dict";
import type { BotWithLastMessage } from "@/src/types";
type Props = {
bot: BotWithLastMessage;
linking?: boolean;
disabled?: boolean;
onLink: () => void;
};
/**
* One bot in the link-bots modal: stone, name, job, and Add.
*/
export default function LinkBotRow({ bot, linking, disabled, onLink }: Props) {
return (
<Row className="h-14 items-center gap-3 rounded-default px-3 flex-nowrap hover:bg-sunken transition-colors duration-[var(--m-fast)]">
<BotAvatar
image_media_id={bot.image_media_id}
hue={(bot.hue || null) as BotHue | null}
face={(bot.face || "idle") as BotFace}
/>
<Stack className="grow min-w-0 gap-0!">
<Span className="text-sm font-bold leading-5 text-ink truncate w-full">{bot.name}</Span>
<Span className="text-xs leading-4 text-ink-secondary truncate w-full">{bot.role || ""}</Span>
</Stack>
<Button
title={`Add ${bot.name || "this bot"}`}
type="button"
variant="ghost"
color="gray"
size="small"
loading={linking}
disabled={disabled}
onClick={onLink}
className="shrink-0"
>
Add
</Button>
</Row>
);
}