e30e75b5d4
Changesets / Create Version PR (push) Has been cancelled
Deploy Shadcn Registry / Deploy Production (push) Has been cancelled
Template Metrics / LOC + Bundle Size (push) Has been cancelled
Code Quality / Oxlint + Oxfmt (push) Has been cancelled
Code Quality / Template Sync (push) Has been cancelled
Code Quality / Build Changed Packages (push) Has been cancelled
Code Quality / Test Changed Packages (push) Has been cancelled
Deploy Expo Example / Deploy Production (push) Has been cancelled
Deploy Ink Example / Deploy Production (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.12) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.12) (push) Has been cancelled
71 lines
1.8 KiB
TypeScript
71 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState, type ReactNode } from "react";
|
|
import { createPortal } from "react-dom";
|
|
import { LayoutGrid, Plus } from "lucide-react";
|
|
import { Button } from "@/components/ui/button";
|
|
import type { XuluxStoredThread } from "../runtime/types";
|
|
import { XuluxHistoryMenu } from "./XuluxHistoryMenu";
|
|
|
|
function HeaderPortal({ children }: { children: ReactNode }) {
|
|
const [container, setContainer] = useState<HTMLElement | null>(null);
|
|
|
|
useEffect(() => {
|
|
setContainer(
|
|
document.querySelector<HTMLElement>("[data-sub-project-header-portal]"),
|
|
);
|
|
}, []);
|
|
|
|
if (!container) return null;
|
|
return createPortal(children, container);
|
|
}
|
|
|
|
export function XuluxHeaderActions({
|
|
visible,
|
|
showChatActions,
|
|
onNewChat,
|
|
onShowTemplates,
|
|
onRestoreThread,
|
|
}: {
|
|
visible: boolean;
|
|
showChatActions: boolean;
|
|
onNewChat: () => void;
|
|
onShowTemplates: () => void;
|
|
onRestoreThread: (thread: XuluxStoredThread) => void;
|
|
}) {
|
|
if (!visible) return null;
|
|
|
|
return (
|
|
<HeaderPortal>
|
|
<XuluxHistoryMenu
|
|
onNewChat={onNewChat}
|
|
onRestoreThread={onRestoreThread}
|
|
/>
|
|
{showChatActions && (
|
|
<>
|
|
<Button
|
|
type="button"
|
|
variant="outline"
|
|
size="sm"
|
|
className="h-7 gap-1.5 px-2.5 text-xs"
|
|
onClick={onShowTemplates}
|
|
>
|
|
<LayoutGrid className="size-3.5" />
|
|
<span className="hidden md:inline">Templates</span>
|
|
</Button>
|
|
<Button
|
|
type="button"
|
|
variant="outline"
|
|
size="sm"
|
|
className="h-7 gap-1.5 px-2.5 text-xs"
|
|
onClick={onNewChat}
|
|
>
|
|
<Plus className="size-3.5" />
|
|
<span className="hidden md:inline">New</span>
|
|
</Button>
|
|
</>
|
|
)}
|
|
</HeaderPortal>
|
|
);
|
|
}
|