Files
cobble/src/pages/admin/bots/[bot_id]/(partials)/hook-proposal-ref-chip.tsx
T
tbenandClaude Opus 5.5 3e78d51b56 Keep bot messages inside the column on narrow screens
Lists no longer add twui's 25px list margin on top of full width,
markdown blocks and list items are capped at the column, long words
and inline code wrap anywhere, and ref chips with long labels truncate
instead of pushing the line past the edge.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-28 06:23:09 +01:00

74 lines
3.0 KiB
TypeScript

import { useState } from "react";
import { twMerge } from "tailwind-merge";
import Modal from "@moduletrace/twui/elements/Modal";
import Button from "@moduletrace/twui/layout/Button";
import H2 from "@moduletrace/twui/layout/H2";
import Span from "@moduletrace/twui/layout/Span";
import Stack from "@moduletrace/twui/layout/Stack";
import { Webhook } from "lucide-react";
import useHookProposal from "../(hooks)/use-hook-proposal";
import hookProposalTitle from "../(utils)/hook-proposal-title";
import proposalStatusLabel from "../(utils)/proposal-status-label";
import HookProposalCard from "./hook-proposal-card";
type Props = {
proposal_id: number;
};
/**
* A hook a bot proposed (`hookProposalRef`): a chip naming it and where
* it stands, which opens the card the user confirms or rejects it from.
* Anyone it wasn't proposed to sees its number only.
*/
export default function HookProposalRefChip({ proposal_id }: Props) {
const { view, loading, setView } = useHookProposal({ proposal_id });
const [open, setOpen] = useState(false);
if (!view) {
return (
<Span className="font-bold">
{loading ? `hook proposal ${proposal_id}` : `hook proposal ${proposal_id} (not available)`}
</Span>
);
}
const title = hookProposalTitle({ view });
const status = proposalStatusLabel({ view });
return (
<Modal
target={
<Button
type="button"
variant="outlined"
color="gray"
size="smaller"
title={`Review: ${title}`}
className={twMerge(
"inline-flex h-6 max-w-full gap-1.5! flex-nowrap align-middle px-2! text-[13px] font-bold text-ink whitespace-nowrap",
"[&_.twui-button-content-wrapper]:min-w-0",
)}
>
<Webhook size={14} aria-hidden className="shrink-0" />
<Span className="min-w-0 truncate">{`${title} · ${status}`}</Span>
</Button>
}
targetWrapperProps={{ className: "inline-flex max-w-full align-middle" }}
open={open}
setOpen={setOpen}
className="max-w-xl bg-paper p-6"
>
<Stack className="w-full gap-1! items-stretch">
<H2 className="text-lg! leading-6! tracking-normal! font-bold text-ink">{title}</H2>
<Span className="text-[13px] leading-[18px] text-ink-secondary">
{`${status}. ${view.bot_name} proposed this; nothing is saved until you confirm. Everything above the bot's own words is read from what Confirm would save.`}
</Span>
</Stack>
<Stack className="mt-2 max-h-[65vh] w-full gap-0! items-stretch overflow-y-auto">
<HookProposalCard view={view} onDecided={setView} onDone={() => setOpen(false)} />
</Stack>
</Modal>
);
}