Merge remote-tracking branch 'upstream/dev' into fix/docker-dev

This commit is contained in:
Anish Sarkar 2026-03-10 12:30:03 +05:30
commit 831ea5d34c
2 changed files with 104 additions and 46 deletions

View file

@ -4,7 +4,7 @@ import { useAtomValue } from "jotai";
import { AlertTriangle, Cable, Settings } from "lucide-react"; import { AlertTriangle, Cable, Settings } from "lucide-react";
import Link from "next/link"; import Link from "next/link";
import { useSearchParams } from "next/navigation"; import { useSearchParams } from "next/navigation";
import { type FC, useMemo } from "react"; import { type FC, forwardRef, useImperativeHandle, useMemo } from "react";
import { documentTypeCountsAtom } from "@/atoms/documents/document-query.atoms"; import { documentTypeCountsAtom } from "@/atoms/documents/document-query.atoms";
import { import {
globalNewLLMConfigsAtom, globalNewLLMConfigsAtom,
@ -37,7 +37,16 @@ import { AllConnectorsTab } from "./connector-popup/tabs/all-connectors-tab";
import { ConnectorAccountsListView } from "./connector-popup/views/connector-accounts-list-view"; import { ConnectorAccountsListView } from "./connector-popup/views/connector-accounts-list-view";
import { YouTubeCrawlerView } from "./connector-popup/views/youtube-crawler-view"; import { YouTubeCrawlerView } from "./connector-popup/views/youtube-crawler-view";
export const ConnectorIndicator: FC = () => { export interface ConnectorIndicatorHandle {
open: () => void;
}
interface ConnectorIndicatorProps {
showTrigger?: boolean;
}
export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, ConnectorIndicatorProps>(
({ showTrigger = true }, ref) => {
const searchSpaceId = useAtomValue(activeSearchSpaceIdAtom); const searchSpaceId = useAtomValue(activeSearchSpaceIdAtom);
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const { data: currentUser } = useAtomValue(currentUserAtom); const { data: currentUser } = useAtomValue(currentUserAtom);
@ -189,38 +198,44 @@ export const ConnectorIndicator: FC = () => {
(connectors || []).map((c: SearchSourceConnector) => c.connector_type) (connectors || []).map((c: SearchSourceConnector) => c.connector_type)
); );
useImperativeHandle(ref, () => ({
open: () => handleOpenChange(true),
}));
if (!searchSpaceId) return null; if (!searchSpaceId) return null;
return ( return (
<Dialog open={isOpen} onOpenChange={handleOpenChange}> <Dialog open={isOpen} onOpenChange={handleOpenChange}>
<TooltipIconButton {showTrigger && (
data-joyride="connector-icon" <TooltipIconButton
tooltip={hasConnectors ? `Manage ${activeConnectorsCount} connectors` : "Connect your data"} data-joyride="connector-icon"
side="bottom" tooltip={hasConnectors ? `Manage ${activeConnectorsCount} connectors` : "Connect your data"}
className={cn( side="bottom"
"size-[34px] rounded-full p-1 flex items-center justify-center transition-colors relative", className={cn(
"hover:bg-muted-foreground/15 dark:hover:bg-muted-foreground/30", "size-[34px] rounded-full p-1 flex items-center justify-center transition-colors relative",
"outline-none focus:outline-none focus-visible:outline-none font-semibold text-xs", "hover:bg-muted-foreground/15 dark:hover:bg-muted-foreground/30",
"border-0 ring-0 focus:ring-0 shadow-none focus:shadow-none" "outline-none focus:outline-none focus-visible:outline-none font-semibold text-xs",
)} "border-0 ring-0 focus:ring-0 shadow-none focus:shadow-none"
aria-label={ )}
hasConnectors ? `View ${activeConnectorsCount} connectors` : "Add your first connector" aria-label={
} hasConnectors ? `View ${activeConnectorsCount} connectors` : "Add your first connector"
onClick={() => handleOpenChange(true)} }
> onClick={() => handleOpenChange(true)}
{isLoading ? ( >
<Spinner size="sm" /> {isLoading ? (
) : ( <Spinner size="sm" />
<> ) : (
<Cable className="size-4 stroke-[1.5px]" /> <>
{activeConnectorsCount > 0 && ( <Cable className="size-4 stroke-[1.5px]" />
<span className="absolute -top-0.5 right-0 flex items-center justify-center min-w-[16px] h-4 px-1 text-[10px] font-medium rounded-full bg-primary text-primary-foreground shadow-sm select-none"> {activeConnectorsCount > 0 && (
{activeConnectorsCount > 99 ? "99+" : activeConnectorsCount} <span className="absolute -top-0.5 right-0 flex items-center justify-center min-w-[16px] h-4 px-1 text-[10px] font-medium rounded-full bg-primary text-primary-foreground shadow-sm select-none">
</span> {activeConnectorsCount > 99 ? "99+" : activeConnectorsCount}
)} </span>
</> )}
)} </>
</TooltipIconButton> )}
</TooltipIconButton>
)}
<DialogContent className="max-w-3xl w-[95vw] sm:w-full h-[75vh] sm:h-[85vh] flex flex-col p-0 gap-0 overflow-hidden border border-border ring-0 dark:ring-0 bg-muted dark:bg-muted text-foreground focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0 [&>button]:right-4 sm:[&>button]:right-12 [&>button]:top-6 sm:[&>button]:top-10 [&>button]:opacity-80 hover:[&>button]:opacity-100 [&>button_svg]:size-5 select-none"> <DialogContent className="max-w-3xl w-[95vw] sm:w-full h-[75vh] sm:h-[85vh] flex flex-col p-0 gap-0 overflow-hidden border border-border ring-0 dark:ring-0 bg-muted dark:bg-muted text-foreground focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0 [&>button]:right-4 sm:[&>button]:right-12 [&>button]:top-6 sm:[&>button]:top-10 [&>button]:opacity-80 hover:[&>button]:opacity-100 [&>button_svg]:size-5 select-none">
<DialogTitle className="sr-only">Manage Connectors</DialogTitle> <DialogTitle className="sr-only">Manage Connectors</DialogTitle>
@ -429,4 +444,6 @@ export const ConnectorIndicator: FC = () => {
</DialogContent> </DialogContent>
</Dialog> </Dialog>
); );
}; });
ConnectorIndicator.displayName = "ConnectorIndicator";

View file

@ -14,6 +14,7 @@ import {
AlertCircle, AlertCircle,
ArrowDownIcon, ArrowDownIcon,
ArrowUpIcon, ArrowUpIcon,
Cable,
CheckIcon, CheckIcon,
ChevronLeftIcon, ChevronLeftIcon,
ChevronRightIcon, ChevronRightIcon,
@ -22,6 +23,7 @@ import {
PlusIcon, PlusIcon,
RefreshCwIcon, RefreshCwIcon,
SquareIcon, SquareIcon,
SquareLibrary,
} from "lucide-react"; } from "lucide-react";
import { useParams } from "next/navigation"; import { useParams } from "next/navigation";
import { type FC, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react"; import { type FC, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
@ -42,8 +44,10 @@ import {
import { currentUserAtom } from "@/atoms/user/user-query.atoms"; import { currentUserAtom } from "@/atoms/user/user-query.atoms";
import { AssistantMessage } from "@/components/assistant-ui/assistant-message"; import { AssistantMessage } from "@/components/assistant-ui/assistant-message";
import { ChatSessionStatus } from "@/components/assistant-ui/chat-session-status"; import { ChatSessionStatus } from "@/components/assistant-ui/chat-session-status";
import { ConnectorIndicator } from "@/components/assistant-ui/connector-popup"; import {
import { useDocumentUploadDialog } from "@/components/assistant-ui/document-upload-popup"; ConnectorIndicator,
type ConnectorIndicatorHandle,
} from "@/components/assistant-ui/connector-popup";
import { import {
InlineMentionEditor, InlineMentionEditor,
type InlineMentionEditorRef, type InlineMentionEditorRef,
@ -62,6 +66,7 @@ import {
} from "@/components/new-chat/document-mention-picker"; } from "@/components/new-chat/document-mention-picker";
import type { ThinkingStep } from "@/components/tool-ui/deepagent-thinking"; import type { ThinkingStep } from "@/components/tool-ui/deepagent-thinking";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import type { Document } from "@/contracts/types/document.types"; import type { Document } from "@/contracts/types/document.types";
import { useBatchCommentsPreload } from "@/hooks/use-comments"; import { useBatchCommentsPreload } from "@/hooks/use-comments";
import { useCommentsElectric } from "@/hooks/use-comments-electric"; import { useCommentsElectric } from "@/hooks/use-comments-electric";
@ -474,7 +479,8 @@ const ComposerAction: FC<ComposerActionProps> = ({ isBlockedByOtherUser = false
const mentionedDocuments = useAtomValue(mentionedDocumentsAtom); const mentionedDocuments = useAtomValue(mentionedDocumentsAtom);
const sidebarDocs = useAtomValue(sidebarSelectedDocumentsAtom); const sidebarDocs = useAtomValue(sidebarSelectedDocumentsAtom);
const setDocumentsSidebarOpen = useSetAtom(documentsSidebarOpenAtom); const setDocumentsSidebarOpen = useSetAtom(documentsSidebarOpenAtom);
const { openDialog: openUploadDialog } = useDocumentUploadDialog(); const connectorRef = useRef<ConnectorIndicatorHandle>(null);
const [addMenuOpen, setAddMenuOpen] = useState(false);
const isComposerTextEmpty = useAssistantState(({ composer }) => { const isComposerTextEmpty = useAssistantState(({ composer }) => {
const text = composer.text?.trim() || ""; const text = composer.text?.trim() || "";
@ -502,18 +508,53 @@ const ComposerAction: FC<ComposerActionProps> = ({ isBlockedByOtherUser = false
return ( return (
<div className="aui-composer-action-wrapper relative mx-2 mb-2 flex items-center justify-between"> <div className="aui-composer-action-wrapper relative mx-2 mb-2 flex items-center justify-between">
<div className="flex items-center gap-1"> <div className="flex items-center gap-1">
<TooltipIconButton <Popover open={addMenuOpen} onOpenChange={setAddMenuOpen}>
tooltip="Upload" <PopoverTrigger asChild>
side="bottom" <TooltipIconButton
variant="ghost" tooltip="Configuration"
size="icon" side="bottom"
className="size-[34px] rounded-full p-1 font-semibold text-xs hover:bg-muted-foreground/15 dark:border-muted-foreground/15 dark:hover:bg-muted-foreground/30" variant="ghost"
aria-label="Upload documents" size="icon"
onClick={openUploadDialog} className="size-[34px] rounded-full p-1 font-semibold text-xs hover:bg-muted-foreground/15 dark:border-muted-foreground/15 dark:hover:bg-muted-foreground/30"
> aria-label="Configuration"
<PlusIcon className="size-4" /> data-joyride="connector-icon"
</TooltipIconButton> >
<ConnectorIndicator /> <PlusIcon className="size-4" />
</TooltipIconButton>
</PopoverTrigger>
<PopoverContent
side="bottom"
align="start"
sideOffset={12}
className="w-[calc(100vw-2rem)] max-w-60 sm:w-60 p-2"
>
<div className="flex flex-col gap-0.5">
<button
type="button"
className="flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground"
onClick={() => {
setAddMenuOpen(false);
setDocumentsSidebarOpen(true);
}}
>
<SquareLibrary className="size-4 shrink-0" />
Documents
</button>
<button
type="button"
className="flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground"
onClick={() => {
setAddMenuOpen(false);
connectorRef.current?.open();
}}
>
<Cable className="size-4 shrink-0" />
Manage connectors
</button>
</div>
</PopoverContent>
</Popover>
<ConnectorIndicator ref={connectorRef} showTrigger={false} />
</div> </div>
{!hasModelConfigured && ( {!hasModelConfigured && (