"use client"; import { useState } from "react"; import { IconShare } from "@tabler/icons-react"; import { Button } from "@kandev/ui/button"; import { Tooltip, TooltipContent, TooltipTrigger } from "@kandev/ui/tooltip"; import { ShareDialog } from "./share-dialog"; type Props = { taskId: string; sessionId: string; /** When true, render as an icon-only button suited for top bars. */ iconOnly?: boolean; }; // Matches the ghost-style action buttons in the dockview header bar so the // share entry point sits flush with the maximize/split/browser icons. const TOP_BAR_BUTTON_CLASS = "h-6 w-6 p-0 cursor-pointer text-muted-foreground hover:bg-muted/70 hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring"; /** * Renders the "Share" entry point. Callers are responsible for gating * visibility on `session.state` via {@link shareableSessionStateClient}; * keeping that check at the call site lets us hide the button entirely * (rather than disabling it) for unshareable sessions. */ export function ShareButton({ taskId, sessionId, iconOnly = false }: Props) { const [open, setOpen] = useState(false); const button = iconOnly ? ( ) : ( ); return ( <> {button} Share this task conversation as a public link ); } // shareableSessionStateClient gates the Share entry point. Sessions that // haven't produced any conversation yet (CREATED / STARTING) have nothing // worth publishing; everything else — RUNNING, IDLE, WAITING_FOR_INPUT, // COMPLETED, FAILED, CANCELLED — gets the button. Backend enforces the // same rule (see internal/task/share/builder.go). export function shareableSessionStateClient(state?: string | null): boolean { if (!state) return false; return state !== "CREATED" && state !== "STARTING"; }