diff --git a/frontend/components/logo/dog-icon.tsx b/frontend/components/logo/dog-icon.tsx index ca53eabb..613bcd92 100644 --- a/frontend/components/logo/dog-icon.tsx +++ b/frontend/components/logo/dog-icon.tsx @@ -7,29 +7,29 @@ const DogIcon = ({ disabled = false, stroke, ...props }: DogIconProps) => { // CSS for the stepped animation states const animationCSS = ` - .state1 { animation: showState1 600ms infinite; } - .state2 { animation: showState2 600ms infinite; } - .state3 { animation: showState3 600ms infinite; } - .state4 { animation: showState4 600ms infinite; } + .state1 { animation: showDogState1 600ms infinite; } + .state2 { animation: showDogState2 600ms infinite; } + .state3 { animation: showDogState3 600ms infinite; } + .state4 { animation: showDogState4 600ms infinite; } - @keyframes showState1 { + @keyframes showDogState1 { 0%, 24.99% { opacity: 1; } 25%, 100% { opacity: 0; } } - @keyframes showState2 { + @keyframes showDogState2 { 0%, 24.99% { opacity: 0; } 25%, 49.99% { opacity: 1; } 50%, 100% { opacity: 0; } } - @keyframes showState3 { + @keyframes showDogState3 { 0%, 49.99% { opacity: 0; } 50%, 74.99% { opacity: 1; } 75%, 100% { opacity: 0; } } - @keyframes showState4 { + @keyframes showDogState4 { 0%, 74.99% { opacity: 0; } 75%, 100% { opacity: 1; } } diff --git a/frontend/src/app/chat/components/assistant-message.tsx b/frontend/src/app/chat/components/assistant-message.tsx index 2ed8c168..9abcc7e8 100644 --- a/frontend/src/app/chat/components/assistant-message.tsx +++ b/frontend/src/app/chat/components/assistant-message.tsx @@ -46,7 +46,7 @@ export function AssistantMessage({ > +
( fileInputRef.current?.click(); }, })); - + const handleFilePickerChange = (e: React.ChangeEvent) => { const files = e.target.files; if (files && files.length > 0) { @@ -92,242 +91,247 @@ export const ChatInput = forwardRef( }; return ( -
-
- {/* Outer container - flex-col to stack file preview above input */} -
- {/* File Preview Section - Always above */} - {uploadedFile && ( - { - onFileSelected(null); - }} - /> - )} +
+ + {/* Outer container - flex-col to stack file preview above input */} +
+ {/* File Preview Section - Always above */} + {uploadedFile && ( + { + onFileSelected(null); + }} + /> + )} - {/* Main Input Container - flex-row or flex-col based on textarea height */} -
40 ? 'flex-col' : 'flex-row items-center' - }`}> - {/* Filter + Textarea Section */} -
40 ? 'w-full' : 'flex-1'}`}> - {textareaHeight <= 40 && ( - selectedFilter ? ( - { - setSelectedFilter(null); - setIsFilterHighlighted(false); - }} - /> - ) : ( - - ) - )} -
- setTextareaHeight(height)} - maxRows={7} - minRows={1} - placeholder="Ask a question..." - disabled={loading} - className={`w-full text-sm bg-transparent focus-visible:outline-none resize-none`} - rows={1} + {/* Main Input Container - flex-row or flex-col based on textarea height */} +
40 ? "flex-col" : "flex-row items-center" + }`} + > + {/* Filter + Textarea Section */} +
40 ? "w-full" : "flex-1"}`} + > + {textareaHeight <= 40 && + (selectedFilter ? ( + { + setSelectedFilter(null); + setIsFilterHighlighted(false); + }} /> -
-
- - {/* Action Buttons Section */} -
40 ? 'justify-between w-full' : ''}`}> - {textareaHeight > 40 && ( - selectedFilter ? ( - { - setSelectedFilter(null); - setIsFilterHighlighted(false); - }} - /> - ) : ( - - ) - )} -
+ ) : ( + ))} +
+ setTextareaHeight(height)} + maxRows={7} + autoComplete="off" + minRows={1} + placeholder="Ask a question..." + disabled={loading} + className={`w-full text-sm bg-transparent focus-visible:outline-none resize-none`} + rows={1} + /> +
+
+ + {/* Action Buttons Section */} +
40 ? "justify-between w-full" : ""}`} + > + {textareaHeight > 40 && + (selectedFilter ? ( + { + setSelectedFilter(null); + setIsFilterHighlighted(false); + }} + /> + ) : ( -
+ ))} +
+ +
- +
+ - { - setIsFilterDropdownOpen(open); - }} - > - {anchorPosition && ( - -
- - )} - { - // Prevent auto focus on the popover content - e.preventDefault(); - // Keep focus on the input + { + setIsFilterDropdownOpen(open); + }} + > + {anchorPosition && ( + -
- {filterSearchTerm && ( -
- Searching: @{filterSearchTerm} -
- )} - {availableFilters.length === 0 ? ( -
- No knowledge filters available -
- ) : ( - <> - {!filterSearchTerm && ( - - )} - {availableFilters - .filter((filter) => - filter.name - .toLowerCase() - .includes(filterSearchTerm.toLowerCase()), - ) - .map((filter, index) => ( - - ))} - {availableFilters.filter((filter) => +
+ + )} + { + // Prevent auto focus on the popover content + e.preventDefault(); + // Keep focus on the input + }} + > +
+ {filterSearchTerm && ( +
+ Searching: @{filterSearchTerm} +
+ )} + {availableFilters.length === 0 ? ( +
+ No knowledge filters available +
+ ) : ( + <> + {!filterSearchTerm && ( + + )} + {availableFilters + .filter((filter) => filter.name .toLowerCase() .includes(filterSearchTerm.toLowerCase()), - ).length === 0 && - filterSearchTerm && ( -
- No filters match "{filterSearchTerm}" + ) + .map((filter, index) => ( +
- - - -
+ {selectedFilter?.id === filter.id && ( + + )} + + ))} + {availableFilters.filter((filter) => + filter.name + .toLowerCase() + .includes(filterSearchTerm.toLowerCase()), + ).length === 0 && + filterSearchTerm && ( +
+ No filters match "{filterSearchTerm}" +
+ )} + + )} +
+ + + +
); }, ); diff --git a/frontend/src/app/onboarding/components/animated-provider-steps.tsx b/frontend/src/app/onboarding/components/animated-provider-steps.tsx index b97113dc..fecf2c72 100644 --- a/frontend/src/app/onboarding/components/animated-provider-steps.tsx +++ b/frontend/src/app/onboarding/components/animated-provider-steps.tsx @@ -80,7 +80,7 @@ export function AnimatedProviderSteps({
-
+
void; @@ -191,84 +192,77 @@ const OnboardingCard = ({ > -
- -
- OpenAI + > + +
+ OpenAI + -
- -
- IBM watsonx.ai + > + +
+ IBM watsonx.ai + -
- -
- Ollama + > + +
+ Ollama + - - {isLoadingModels && ( - -
-
-
- )} -
- -
diff --git a/frontend/src/app/onboarding/components/onboarding-step.tsx b/frontend/src/app/onboarding/components/onboarding-step.tsx index 8670009f..f6bfd963 100644 --- a/frontend/src/app/onboarding/components/onboarding-step.tsx +++ b/frontend/src/app/onboarding/components/onboarding-step.tsx @@ -74,7 +74,7 @@ export function OnboardingStep({
) : ( icon || ( -
+
{ onClick={handleUploadClick} disabled={isUploading} > - {isUploading ? "Uploading..." : "Add a Document"} +
{isUploading ? "Uploading..." : "Add a document"}
{currentStep > 0 && onSkip && ( )} diff --git a/frontend/src/app/onboarding/components/tab-trigger.tsx b/frontend/src/app/onboarding/components/tab-trigger.tsx new file mode 100644 index 00000000..fdd6721d --- /dev/null +++ b/frontend/src/app/onboarding/components/tab-trigger.tsx @@ -0,0 +1,33 @@ +import AnimatedProcessingIcon from "@/components/ui/animated-processing-icon"; +import { cn } from "@/lib/utils"; + +export function TabTrigger({ + children, + selected, + isLoading, +}: { + children: React.ReactNode; + selected: boolean; + isLoading: boolean; +}) { + return ( +
+
+ +
+
+ {children} +
+
+ ); +} diff --git a/frontend/src/components/chat-renderer.tsx b/frontend/src/components/chat-renderer.tsx index 1e410ee8..71d913e7 100644 --- a/frontend/src/components/chat-renderer.tsx +++ b/frontend/src/components/chat-renderer.tsx @@ -156,7 +156,7 @@ export function ChatRenderer({ }} className={cn( "flex h-full w-full max-w-full max-h-full items-center justify-center overflow-hidden", - !showLayout && "absolute", + !showLayout && "absolute max-h-[calc(100vh-190px)]", showLayout && !isOnChatPage && "bg-background", )} > @@ -199,7 +199,7 @@ export function ChatRenderer({ initial={{ opacity: 0, y: 20 }} animate={{ opacity: showLayout ? 0 : 1, y: showLayout ? 20 : 0 }} transition={{ duration: ANIMATION_DURATION, ease: "easeOut" }} - className={cn("absolute bottom-10 left-0 right-0")} + className={cn("absolute bottom-6 left-0 right-0")} >