mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-26 01:06:23 +02:00
Merge branch 'dev' into documents-mentions
This commit is contained in:
commit
c4400a0ec2
13 changed files with 55 additions and 115 deletions
|
|
@ -8,6 +8,7 @@ import {
|
|||
ThreadPrimitive,
|
||||
useAssistantState,
|
||||
useThreadViewport,
|
||||
useMessage,
|
||||
} from "@assistant-ui/react";
|
||||
import { useAtom, useAtomValue, useSetAtom } from "jotai";
|
||||
import {
|
||||
|
|
@ -75,6 +76,8 @@ import { cn } from "@/lib/utils";
|
|||
*/
|
||||
interface ThreadProps {
|
||||
messageThinkingSteps?: Map<string, ThinkingStep[]>;
|
||||
/** Optional header component to render at the top of the viewport (sticky) */
|
||||
header?: React.ReactNode;
|
||||
}
|
||||
|
||||
// Context to pass thinking steps to AssistantMessage
|
||||
|
|
@ -267,20 +270,21 @@ const ThinkingStepsScrollHandler: FC = () => {
|
|||
};
|
||||
|
||||
export const Thread: FC<ThreadProps> = ({ messageThinkingSteps = new Map() }) => {
|
||||
export const Thread: FC<ThreadProps> = ({ messageThinkingSteps = new Map(), header }) => {
|
||||
return (
|
||||
<ThinkingStepsContext.Provider value={messageThinkingSteps}>
|
||||
<ThreadPrimitive.Root
|
||||
className="aui-root aui-thread-root @container flex h-full flex-col bg-background"
|
||||
className="aui-root aui-thread-root @container flex h-full min-h-0 flex-col bg-background"
|
||||
style={{
|
||||
["--thread-max-width" as string]: "44rem",
|
||||
}}
|
||||
>
|
||||
<ThreadPrimitive.Viewport
|
||||
turnAnchor="top"
|
||||
className="aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth px-4 pt-4"
|
||||
className="aui-thread-viewport relative flex flex-1 min-h-0 flex-col overflow-x-auto overflow-y-scroll scroll-smooth px-4 pt-4"
|
||||
>
|
||||
{/* Auto-scroll handler for thinking steps - must be inside Viewport */}
|
||||
<ThinkingStepsScrollHandler />
|
||||
{/* Optional sticky header for model selector etc. */}
|
||||
{header && <div className="sticky top-0 z-10 mb-4">{header}</div>}
|
||||
|
||||
<AssistantIf condition={({ thread }) => thread.isEmpty}>
|
||||
<ThreadWelcome />
|
||||
|
|
@ -375,7 +379,7 @@ const ThreadWelcome: FC = () => {
|
|||
return (
|
||||
<div className="aui-thread-welcome-root mx-auto flex w-full max-w-(--thread-max-width) grow flex-col items-center px-4 relative">
|
||||
{/* Greeting positioned above the composer - fixed position */}
|
||||
<div className="aui-thread-welcome-message absolute bottom-[calc(50%+5rem)] left-0 right-0 flex flex-col items-center text-center z-10">
|
||||
<div className="aui-thread-welcome-message absolute bottom-[calc(50%+5rem)] left-0 right-0 flex flex-col items-center text-center">
|
||||
<h1 className="aui-thread-welcome-message-inner fade-in slide-in-from-bottom-2 animate-in text-5xl delay-100 duration-500 ease-out fill-mode-both">
|
||||
{greeting}
|
||||
</h1>
|
||||
|
|
|
|||
|
|
@ -47,12 +47,7 @@ export function ChatHeader({ searchSpaceId }: ChatHeaderProps) {
|
|||
|
||||
return (
|
||||
<>
|
||||
{/* Header Bar */}
|
||||
<div className="flex items-center justify-between px-4 py-2 border-b border-border/30 bg-background/80 backdrop-blur-sm">
|
||||
<ModelSelector onEdit={handleEditConfig} onAddNew={handleAddNew} />
|
||||
</div>
|
||||
|
||||
{/* Config Sidebar */}
|
||||
<ModelSelector onEdit={handleEditConfig} onAddNew={handleAddNew} />
|
||||
<ModelConfigSidebar
|
||||
open={sidebarOpen}
|
||||
onOpenChange={handleSidebarClose}
|
||||
|
|
|
|||
|
|
@ -175,9 +175,10 @@ export function ModelSelector({ onEdit, onAddNew, className }: ModelSelectorProp
|
|||
role="combobox"
|
||||
aria-expanded={open}
|
||||
className={cn(
|
||||
"h-9 gap-2 px-3 rounded-xl border border-border/50 bg-background/50 backdrop-blur-sm",
|
||||
"hover:bg-muted/80 hover:border-border transition-all duration-200",
|
||||
"h-9 gap-2 px-3 rounded-xl border border-border/30 bg-background/50 backdrop-blur-sm",
|
||||
"hover:bg-muted/80 hover:border-border/30 transition-all duration-200",
|
||||
"text-sm font-medium text-foreground",
|
||||
"focus-visible:ring-0 focus-visible:ring-offset-0",
|
||||
className
|
||||
)}
|
||||
>
|
||||
|
|
@ -206,11 +207,14 @@ export function ModelSelector({ onEdit, onAddNew, className }: ModelSelectorProp
|
|||
</PopoverTrigger>
|
||||
|
||||
<PopoverContent
|
||||
className="w-[360px] p-0 rounded-xl shadow-lg border-border/50"
|
||||
className="w-[360px] p-0 rounded-xl shadow-lg border-border/30"
|
||||
align="start"
|
||||
sideOffset={8}
|
||||
>
|
||||
<Command shouldFilter={false} className="rounded-xl relative">
|
||||
<Command
|
||||
shouldFilter={false}
|
||||
className="rounded-xl relative [&_[data-slot=command-input-wrapper]]:border-0 [&_[data-slot=command-input-wrapper]]:px-0 [&_[data-slot=command-input-wrapper]]:gap-2"
|
||||
>
|
||||
{/* Switching overlay */}
|
||||
{isSwitching && (
|
||||
<div className="absolute inset-0 z-10 flex items-center justify-center bg-background/80 backdrop-blur-sm rounded-xl">
|
||||
|
|
@ -221,8 +225,7 @@ export function ModelSelector({ onEdit, onAddNew, className }: ModelSelectorProp
|
|||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex items-center gap-2 border-b px-3 py-2 bg-muted/30">
|
||||
<Bot className="size-4 text-muted-foreground" />
|
||||
<div className="flex items-center gap-2 border-b border-border/30 px-3 py-2">
|
||||
<CommandInput
|
||||
placeholder="Search models..."
|
||||
value={searchQuery}
|
||||
|
|
@ -300,7 +303,7 @@ export function ModelSelector({ onEdit, onAddNew, className }: ModelSelectorProp
|
|||
)}
|
||||
|
||||
{filteredGlobalConfigs.length > 0 && filteredUserConfigs.length > 0 && (
|
||||
<CommandSeparator className="my-1" />
|
||||
<CommandSeparator className="my-1 bg-border/30" />
|
||||
)}
|
||||
|
||||
{/* User Configs Section */}
|
||||
|
|
@ -362,7 +365,7 @@ export function ModelSelector({ onEdit, onAddNew, className }: ModelSelectorProp
|
|||
)}
|
||||
|
||||
{/* Add New Config Button */}
|
||||
<div className="p-2 border-t border-border/50 bg-muted/20">
|
||||
<div className="p-2 bg-muted/20">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
|
|
|
|||
|
|
@ -160,8 +160,8 @@ export function AllChatsSidebar({ open, onOpenChange, searchSpaceId }: AllChatsS
|
|||
|
||||
return (
|
||||
<Sheet open={open} onOpenChange={onOpenChange}>
|
||||
<SheetContent side="left" className="w-80 p-0 flex flex-col">
|
||||
<SheetHeader className="mx-3 px-4 py-4 border-b space-y-3">
|
||||
<SheetContent side="left" className="w-80 p-0 flex flex-col border-0">
|
||||
<SheetHeader className="mx-3 px-4 pt-4 pb-0 space-y-2">
|
||||
<SheetTitle>{t("all_chats") || "All Chats"}</SheetTitle>
|
||||
<SheetDescription className="sr-only">
|
||||
{t("all_chats_description") || "Browse and manage all your chats"}
|
||||
|
|
@ -175,7 +175,7 @@ export function AllChatsSidebar({ open, onOpenChange, searchSpaceId }: AllChatsS
|
|||
placeholder={t("search_chats") || "Search chats..."}
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="pl-9 pr-8 h-9"
|
||||
className="pl-9 pr-8 h-9 border-0 focus-visible:ring-0 focus-visible:border-0 shadow-none"
|
||||
/>
|
||||
{searchQuery && (
|
||||
<Button
|
||||
|
|
@ -193,7 +193,7 @@ export function AllChatsSidebar({ open, onOpenChange, searchSpaceId }: AllChatsS
|
|||
|
||||
{/* Tab toggle for active/archived (only show when not searching) */}
|
||||
{!isSearchMode && (
|
||||
<div className="flex border-b mx-3">
|
||||
<div className="flex border-b mx-3 -mt-3">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowArchived(false)}
|
||||
|
|
|
|||
|
|
@ -159,8 +159,8 @@ export function AllNotesSidebar({
|
|||
|
||||
return (
|
||||
<Sheet open={open} onOpenChange={onOpenChange}>
|
||||
<SheetContent side="left" className="w-80 p-0 flex flex-col">
|
||||
<SheetHeader className="mx-3 px-4 py-4 border-b space-y-3">
|
||||
<SheetContent side="left" className="w-80 p-0 flex flex-col border-0">
|
||||
<SheetHeader className="mx-3 px-4 pt-4 pb-2 border-b space-y-2">
|
||||
<SheetTitle>{t("all_notes") || "All Notes"}</SheetTitle>
|
||||
<SheetDescription className="sr-only">
|
||||
{t("all_notes_description") || "Browse and manage all your notes"}
|
||||
|
|
@ -174,7 +174,7 @@ export function AllNotesSidebar({
|
|||
placeholder={t("search_notes") || "Search notes..."}
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="pl-9 pr-8 h-9"
|
||||
className="pl-9 pr-8 h-9 border-0 focus-visible:ring-0 focus-visible:border-0 shadow-none"
|
||||
/>
|
||||
{searchQuery && (
|
||||
<Button
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue