fixed nudges design
This commit is contained in:
parent
3d56fd4932
commit
ba4bf9adc4
2 changed files with 144 additions and 141 deletions
|
|
@ -11,7 +11,7 @@ export default function Nudges({
|
||||||
handleSuggestionClick: (suggestion: string) => void;
|
handleSuggestionClick: (suggestion: string) => void;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className="flex-shrink-0 h-12 w-full overflow-hidden pl-10">
|
<div className="flex-shrink-0 h-12 w-full overflow-hidden">
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{nudges.length > 0 && (
|
{nudges.length > 0 && (
|
||||||
<motion.div
|
<motion.div
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ function ChatPage() {
|
||||||
onComplete: (message, responseId) => {
|
onComplete: (message, responseId) => {
|
||||||
setMessages((prev) => [...prev, message]);
|
setMessages((prev) => [...prev, message]);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|
||||||
if (responseId) {
|
if (responseId) {
|
||||||
cancelNudges();
|
cancelNudges();
|
||||||
setPreviousResponseIds((prev) => ({
|
setPreviousResponseIds((prev) => ({
|
||||||
|
|
@ -739,7 +739,7 @@ function ChatPage() {
|
||||||
scrollToBottom({
|
scrollToBottom({
|
||||||
animation: "smooth",
|
animation: "smooth",
|
||||||
duration: 1000,
|
duration: 1000,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSendMessage = async (inputMessage: string) => {
|
const handleSendMessage = async (inputMessage: string) => {
|
||||||
|
|
@ -759,7 +759,7 @@ function ChatPage() {
|
||||||
scrollToBottom({
|
scrollToBottom({
|
||||||
animation: "smooth",
|
animation: "smooth",
|
||||||
duration: 1000,
|
duration: 1000,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (asyncMode) {
|
if (asyncMode) {
|
||||||
await handleSSEStream(userMessage);
|
await handleSSEStream(userMessage);
|
||||||
|
|
@ -1109,146 +1109,148 @@ function ChatPage() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (<>
|
return (
|
||||||
{/* Debug header - only show in debug mode */}
|
<>
|
||||||
{isDebugMode && (
|
{/* Debug header - only show in debug mode */}
|
||||||
<div className="flex items-center justify-between p-6">
|
{isDebugMode && (
|
||||||
<div className="flex items-center gap-2"></div>
|
<div className="flex items-center justify-between p-6">
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-2"></div>
|
||||||
{/* Async Mode Toggle */}
|
<div className="flex items-center gap-4">
|
||||||
<div className="flex items-center gap-2 bg-muted/50 rounded-lg p-1">
|
{/* Async Mode Toggle */}
|
||||||
<Button
|
<div className="flex items-center gap-2 bg-muted/50 rounded-lg p-1">
|
||||||
variant={!asyncMode ? "default" : "ghost"}
|
<Button
|
||||||
size="sm"
|
variant={!asyncMode ? "default" : "ghost"}
|
||||||
onClick={() => setAsyncMode(false)}
|
size="sm"
|
||||||
className="h-7 text-xs"
|
onClick={() => setAsyncMode(false)}
|
||||||
>
|
className="h-7 text-xs"
|
||||||
Streaming Off
|
>
|
||||||
</Button>
|
Streaming Off
|
||||||
<Button
|
</Button>
|
||||||
variant={asyncMode ? "default" : "ghost"}
|
<Button
|
||||||
size="sm"
|
variant={asyncMode ? "default" : "ghost"}
|
||||||
onClick={() => setAsyncMode(true)}
|
size="sm"
|
||||||
className="h-7 text-xs"
|
onClick={() => setAsyncMode(true)}
|
||||||
>
|
className="h-7 text-xs"
|
||||||
<Zap className="h-3 w-3 mr-1" />
|
>
|
||||||
Streaming On
|
<Zap className="h-3 w-3 mr-1" />
|
||||||
</Button>
|
Streaming On
|
||||||
</div>
|
</Button>
|
||||||
{/* Endpoint Toggle */}
|
</div>
|
||||||
<div className="flex items-center gap-2 bg-muted/50 rounded-lg p-1">
|
{/* Endpoint Toggle */}
|
||||||
<Button
|
<div className="flex items-center gap-2 bg-muted/50 rounded-lg p-1">
|
||||||
variant={endpoint === "chat" ? "default" : "ghost"}
|
<Button
|
||||||
size="sm"
|
variant={endpoint === "chat" ? "default" : "ghost"}
|
||||||
onClick={() => handleEndpointChange("chat")}
|
size="sm"
|
||||||
className="h-7 text-xs"
|
onClick={() => handleEndpointChange("chat")}
|
||||||
>
|
className="h-7 text-xs"
|
||||||
Chat
|
>
|
||||||
</Button>
|
Chat
|
||||||
<Button
|
</Button>
|
||||||
variant={endpoint === "langflow" ? "default" : "ghost"}
|
<Button
|
||||||
size="sm"
|
variant={endpoint === "langflow" ? "default" : "ghost"}
|
||||||
onClick={() => handleEndpointChange("langflow")}
|
size="sm"
|
||||||
className="h-7 text-xs"
|
onClick={() => handleEndpointChange("langflow")}
|
||||||
>
|
className="h-7 text-xs"
|
||||||
Langflow
|
>
|
||||||
</Button>
|
Langflow
|
||||||
</div>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<StickToBottom.Content className="flex flex-col min-h-full overflow-x-hidden p-6">
|
<StickToBottom.Content className="flex flex-col min-h-full overflow-x-hidden p-6">
|
||||||
<div className="flex flex-col place-self-center space-y-6 max-w-[960px] w-full mx-auto">
|
<div className="flex flex-col place-self-center space-y-6 max-w-[960px] w-full mx-auto">
|
||||||
{messages.length === 0 && !streamingMessage ? (
|
{messages.length === 0 && !streamingMessage ? (
|
||||||
<div className="flex items-center justify-center h-full text-muted-foreground">
|
<div className="flex items-center justify-center h-full text-muted-foreground">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
{isUploading ? (
|
{isUploading ? (
|
||||||
<>
|
<>
|
||||||
<Loader2 className="h-12 w-12 mx-auto mb-4 animate-spin" />
|
<Loader2 className="h-12 w-12 mx-auto mb-4 animate-spin" />
|
||||||
<p>Processing your document...</p>
|
<p>Processing your document...</p>
|
||||||
<p className="text-sm mt-2">
|
<p className="text-sm mt-2">This may take a few moments</p>
|
||||||
This may take a few moments
|
</>
|
||||||
</p>
|
) : null}
|
||||||
</>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
</div>
|
||||||
<>
|
) : (
|
||||||
{messages.map((message, index) => (
|
<>
|
||||||
<div
|
{messages.map((message, index) => (
|
||||||
key={`${
|
<div
|
||||||
message.role
|
key={`${
|
||||||
}-${index}-${message.timestamp?.getTime()}`}
|
message.role
|
||||||
className="space-y-6 group"
|
}-${index}-${message.timestamp?.getTime()}`}
|
||||||
>
|
className="space-y-6 group"
|
||||||
{message.role === "user" && (
|
>
|
||||||
<UserMessage content={message.content} />
|
{message.role === "user" && (
|
||||||
)}
|
<UserMessage content={message.content} />
|
||||||
|
)}
|
||||||
|
|
||||||
{message.role === "assistant" && (
|
{message.role === "assistant" && (
|
||||||
<AssistantMessage
|
<AssistantMessage
|
||||||
content={message.content}
|
content={message.content}
|
||||||
functionCalls={message.functionCalls}
|
functionCalls={message.functionCalls}
|
||||||
messageIndex={index}
|
messageIndex={index}
|
||||||
expandedFunctionCalls={expandedFunctionCalls}
|
expandedFunctionCalls={expandedFunctionCalls}
|
||||||
onToggle={toggleFunctionCall}
|
onToggle={toggleFunctionCall}
|
||||||
showForkButton={endpoint === "chat"}
|
showForkButton={endpoint === "chat"}
|
||||||
onFork={(e) => handleForkConversation(index, e)}
|
onFork={(e) => handleForkConversation(index, e)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{/* Streaming Message Display */}
|
{/* Streaming Message Display */}
|
||||||
{streamingMessage && (
|
{streamingMessage && (
|
||||||
<AssistantMessage
|
<AssistantMessage
|
||||||
content={streamingMessage.content}
|
content={streamingMessage.content}
|
||||||
functionCalls={streamingMessage.functionCalls}
|
functionCalls={streamingMessage.functionCalls}
|
||||||
messageIndex={messages.length}
|
messageIndex={messages.length}
|
||||||
expandedFunctionCalls={expandedFunctionCalls}
|
expandedFunctionCalls={expandedFunctionCalls}
|
||||||
onToggle={toggleFunctionCall}
|
onToggle={toggleFunctionCall}
|
||||||
isStreaming
|
isStreaming
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{!streamingMessage && (
|
{!streamingMessage && (
|
||||||
|
<div className="pl-10">
|
||||||
<Nudges
|
<Nudges
|
||||||
nudges={loading ? [] : (nudges as string[])}
|
nudges={loading ? [] : (nudges as string[])}
|
||||||
handleSuggestionClick={handleSuggestionClick}
|
handleSuggestionClick={handleSuggestionClick}
|
||||||
/>
|
/>
|
||||||
)}
|
</div>
|
||||||
</div>
|
)}
|
||||||
</StickToBottom.Content>
|
</div>
|
||||||
|
</StickToBottom.Content>
|
||||||
|
|
||||||
{/* Input Area - Fixed at bottom */}
|
{/* Input Area - Fixed at bottom */}
|
||||||
<ChatInput
|
<ChatInput
|
||||||
ref={chatInputRef}
|
ref={chatInputRef}
|
||||||
input={input}
|
input={input}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
isUploading={isUploading}
|
isUploading={isUploading}
|
||||||
selectedFilter={selectedFilter}
|
selectedFilter={selectedFilter}
|
||||||
isFilterDropdownOpen={isFilterDropdownOpen}
|
isFilterDropdownOpen={isFilterDropdownOpen}
|
||||||
availableFilters={availableFilters}
|
availableFilters={availableFilters}
|
||||||
filterSearchTerm={filterSearchTerm}
|
filterSearchTerm={filterSearchTerm}
|
||||||
selectedFilterIndex={selectedFilterIndex}
|
selectedFilterIndex={selectedFilterIndex}
|
||||||
anchorPosition={anchorPosition}
|
anchorPosition={anchorPosition}
|
||||||
textareaHeight={textareaHeight}
|
textareaHeight={textareaHeight}
|
||||||
parsedFilterData={parsedFilterData}
|
parsedFilterData={parsedFilterData}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
onHeightChange={(height) => setTextareaHeight(height)}
|
onHeightChange={(height) => setTextareaHeight(height)}
|
||||||
onFilterSelect={handleFilterSelect}
|
onFilterSelect={handleFilterSelect}
|
||||||
onAtClick={onAtClick}
|
onAtClick={onAtClick}
|
||||||
onFilePickerChange={handleFilePickerChange}
|
onFilePickerChange={handleFilePickerChange}
|
||||||
onFilePickerClick={handleFilePickerClick}
|
onFilePickerClick={handleFilePickerClick}
|
||||||
setSelectedFilter={setSelectedFilter}
|
setSelectedFilter={setSelectedFilter}
|
||||||
setIsFilterHighlighted={setIsFilterHighlighted}
|
setIsFilterHighlighted={setIsFilterHighlighted}
|
||||||
setIsFilterDropdownOpen={setIsFilterDropdownOpen}
|
setIsFilterDropdownOpen={setIsFilterDropdownOpen}
|
||||||
/></>
|
/>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1256,14 +1258,15 @@ export default function ProtectedChatPage() {
|
||||||
return (
|
return (
|
||||||
<ProtectedRoute>
|
<ProtectedRoute>
|
||||||
<div className="flex w-full h-full overflow-hidden">
|
<div className="flex w-full h-full overflow-hidden">
|
||||||
<StickToBottom
|
<StickToBottom
|
||||||
className="flex h-full flex-1 flex-col"
|
className="flex h-full flex-1 flex-col"
|
||||||
resize="smooth"
|
resize="smooth"
|
||||||
initial="instant"
|
initial="instant"
|
||||||
mass={1}
|
mass={1}
|
||||||
>
|
>
|
||||||
<ChatPage />
|
<ChatPage />
|
||||||
</StickToBottom></div>
|
</StickToBottom>
|
||||||
|
</div>
|
||||||
</ProtectedRoute>
|
</ProtectedRoute>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue