Run computers with resources and health checks, add settings for bots, workspaces, computers and users
- Computers get CPUs and memory (default 1 CPU, 2 GB), set at creation and editable; new resources stop, remove and recreate the container, its home dir kept. Every computer container has a docker health check and stays "creating" until it passes; only healthy computers are reached, by hostname, else by their IP on the network (dev outside docker). - Docker is required: the app creates the cobble network on startup and exits without docker. - Production container: deploy/run-app-container.sh mounts .env, the data dir and the docker socket; the database (DB_DIR), media, computers' homes and bun-sqlite's live schema now live on the data volume. - Settings pages for bots, workspaces, computers and users, sharing list components; bots can be deleted; users are created with a password and confirmation, edited and deleted through RBAC-gated APIs. - User types trimmed to super_admin, admin, member, read_only and revoked; admins manage members. UserAvatar shows profile photos from the user row. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import { useContext, useState } from "react";
|
||||
import Button from "@moduletrace/twui/layout/Button";
|
||||
import { Plus } from "lucide-react";
|
||||
import { AppContext } from "@/src/pages/__root";
|
||||
import { AddFlowContext } from "@/src/layouts/bots/(data)/add-flow-context";
|
||||
import type { BotWithLastMessage } from "@/src/types";
|
||||
import useSettingsList from "../../(hooks)/use-settings-list";
|
||||
import SettingsGroup from "../../(partials)/settings-group";
|
||||
import SettingsList from "../../(partials)/settings-list";
|
||||
import SettingsStatus from "../../(partials)/settings-status";
|
||||
import BotEditModal from "../(partials)/bot-edit-modal";
|
||||
import BotSettingsRow from "../(partials)/bot-settings-row";
|
||||
|
||||
/**
|
||||
* The user's crew, coordinator first: chat with a bot, edit it, set its
|
||||
* models, add one or delete a worker.
|
||||
*/
|
||||
export default function BotsSettingsSection() {
|
||||
const { pageProps } = useContext(AppContext);
|
||||
const { openForm } = useContext(AddFlowContext);
|
||||
const { items, busy, status, remove } = useSettingsList({ items: pageProps?.bots || [] });
|
||||
const [editing, setEditing] = useState<BotWithLastMessage>();
|
||||
|
||||
return (
|
||||
<SettingsGroup
|
||||
title="Your crew"
|
||||
description="The coordinator stays. Deleting a bot removes its conversations, tasks and models."
|
||||
>
|
||||
<SettingsList is_empty={!items.length} empty="No bots yet.">
|
||||
{items.map((bot) => (
|
||||
<BotSettingsRow
|
||||
key={bot.id}
|
||||
bot={bot}
|
||||
busy={busy}
|
||||
onEdit={() => setEditing(bot)}
|
||||
onDelete={() =>
|
||||
remove({
|
||||
id: bot.id,
|
||||
path: "bots/delete-bot",
|
||||
body: { bot_id: bot.id },
|
||||
confirm: `Delete ${bot.name || "this bot"}? Its conversations, tasks and models go with it.`,
|
||||
})
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</SettingsList>
|
||||
<Button
|
||||
title="Add a bot"
|
||||
type="button"
|
||||
variant="ghost"
|
||||
color="gray"
|
||||
size="small"
|
||||
onClick={() => openForm({ kind: "bot" })}
|
||||
className="self-start gap-1!"
|
||||
>
|
||||
<Plus size={14} aria-hidden />
|
||||
New bot
|
||||
</Button>
|
||||
<SettingsStatus status={status} />
|
||||
<BotEditModal bot={editing} onClose={() => setEditing(undefined)} />
|
||||
</SettingsGroup>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user