Skip to content

Commit

Permalink
feat: update chat bar to encapsulate thread actions and submit button
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanhopperlowe committed Dec 16, 2024
1 parent b8f3dc7 commit a2330b1
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 33 deletions.
7 changes: 1 addition & 6 deletions ui/admin/app/components/chat/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { useState } from "react";
import { cn } from "~/lib/utils";

import { useChat } from "~/components/chat/ChatContext";
import { ChatHelpers } from "~/components/chat/ChatHelpers";
import { Chatbar } from "~/components/chat/Chatbar";
import { MessagePane } from "~/components/chat/MessagePane";
import { RunWorkflow } from "~/components/chat/RunWorkflow";
Expand Down Expand Up @@ -56,9 +55,7 @@ export function Chat({ className }: ChatProps) {
setRunTriggered(true);
invoke(params && JSON.stringify(params));
}}
className={cn({
"w-full": threadId,
})}
className={cn({ "w-full": threadId })}
popoverContentProps={{
className: cn({ "translate-y-[-50%]": !threadId }),
}}
Expand All @@ -69,8 +66,6 @@ export function Chat({ className }: ChatProps) {
</RunWorkflow>
</div>
)}

<ChatHelpers />
</div>
);
}
10 changes: 4 additions & 6 deletions ui/admin/app/components/chat/ChatHelpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
} from "~/components/ui/popover";
import { Switch } from "~/components/ui/switch";

export function ChatHelpers() {
export function ChatHelpers({ className }: { className?: string }) {
const { threadId } = useChat();

const { data: thread } = useSWR(
Expand All @@ -39,10 +39,8 @@ export function ChatHelpers() {

const tools = thread?.tools;

console.log(knowledge);

return (
<div className="w-full flex items-center px-20 py-2">
<div className={cn("w-full flex items-center", className)}>
<div className="flex items-center gap-2">
<ToolsInfo
tools={tools ?? []}
Expand Down Expand Up @@ -100,7 +98,7 @@ function ToolsInfo({
<PopoverTrigger asChild>
<Button
size="sm"
variant="secondary"
variant="outline"
className={cn("gap-2", className)}
startContent={<WrenchIcon />}
disabled={disabled}
Expand Down Expand Up @@ -161,7 +159,7 @@ function KnowledgeInfo({
<PopoverTrigger asChild>
<Button
size="sm"
variant="secondary"
variant="outline"
className={cn("gap-2", className)}
startContent={<LibraryIcon />}
disabled={disabled}
Expand Down
32 changes: 22 additions & 10 deletions ui/admin/app/components/chat/Chatbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useState } from "react";
import { cn } from "~/lib/utils";

import { useChat } from "~/components/chat/ChatContext";
import { ChatHelpers } from "~/components/chat/ChatHelpers";
import { LoadingSpinner } from "~/components/ui/LoadingSpinner";
import { Button } from "~/components/ui/button";
import { AutosizeTextarea } from "~/components/ui/textarea";
Expand Down Expand Up @@ -34,7 +35,8 @@ export function Chatbar({ className }: ChatbarProps) {
>
<div className="relative flex-grow">
<AutosizeTextarea
className="rounded-xl bg-background"
className="rounded-3xl p-2"
variant="flat"
value={input}
onKeyDown={(e) => {
if (e.key === "Enter" && !e.shiftKey) {
Expand All @@ -46,17 +48,27 @@ export function Chatbar({ className }: ChatbarProps) {
minHeight={0}
onChange={(e) => setInput(e.target.value)}
placeholder="Type your message..."
bottomContent={
<div className="flex flex-row-reverse items-center justify-between">
<Button
size="icon-sm"
className="m-2"
color="primary"
type="submit"
disabled={!input || isRunning || isInvoking}
>
{isInvoking ? (
<LoadingSpinner />
) : (
<ArrowUpIcon />
)}
</Button>

<ChatHelpers className="p-2" />
</div>
}
/>
</div>

<Button
size="icon"
className="rounded-full"
type="submit"
disabled={!input || isRunning || isInvoking}
>
{isInvoking ? <LoadingSpinner /> : <ArrowUpIcon />}
</Button>
</form>
);
}
5 changes: 3 additions & 2 deletions ui/admin/app/components/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ const buttonVariants = cva(
variants: {
variant: {
default:
"bg-primary text-primary-foreground shadow hover:bg-primary/80",
"bg-primary text-primary-foreground shadow hover:bg-primary/80 focus-visible:ring-foreground",
destructive:
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/80",
outline:
"border border-input bg-background shadow-sm hover:bg-muted/80",
"border border-input bg-transparent shadow-sm hover:bg-muted/80",
secondary:
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
ghost: "hover:bg-secondary hover:text-secondary-foreground",
Expand All @@ -29,6 +29,7 @@ const buttonVariants = cva(
sm: "h-8 px-3 text-xs",
lg: "h-10 px-8",
icon: "h-9 w-9 min-w-9 min-h-9 [&_svg]:size-[1.375rem]",
"icon-sm": "h-8 w-8 min-w-8 min-h-8 [&_svg]:size-[1.125rem]",
},
shape: {
none: "",
Expand Down
92 changes: 83 additions & 9 deletions ui/admin/app/components/ui/textarea.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,49 @@
import { VariantProps, cva } from "class-variance-authority";
import * as React from "react";
import { useImperativeHandle } from "react";
import { forwardRef, useImperativeHandle } from "react";

import { cn } from "~/lib/utils";

export type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;
const textareaVariants = cva(
"flex w-full rounded-md bg-transparent text-sm placeholder:text-muted-foreground has-[:focus-visible]:ring-1 has-[:focus-visible]:ring-ring group group-disabled:cursor-not-allowed group-disabled:bg-opacity-50",
{
variants: {
variant: {
outlined: "border border-input shadow-sm",
flat: "border-none shadow-none bg-muted",
},
},
defaultVariants: {
variant: "outlined",
},
}
);

const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
({ className, ...props }, ref) => {
type TextAreaWrapperProps = React.HTMLAttributes<HTMLDivElement> &
VariantProps<typeof textareaVariants>;
const TextAreaWrapper = forwardRef<HTMLDivElement, TextAreaWrapperProps>(
({ className, variant, ...props }, ref) => {
return (
<div
ref={ref}
className={cn(textareaVariants({ variant, className }))}
{...props}
/>
);
}
);
TextAreaWrapper.displayName = "TextAreaWrapper";

type TextAreaBaseProps = React.TextareaHTMLAttributes<HTMLTextAreaElement> &
VariantProps<typeof textareaVariants>;

const TextAreaBase = forwardRef<HTMLTextAreaElement, TextAreaBaseProps>(
({ className, variant, ...props }, ref) => {
return (
<textarea
className={cn(
"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
"w-full px-3 py-2 bg-transparent border-none focus-visible:border-none focus-visible:outline-none disabled:group group-disabled:cursor-not-allowed",
variant === "flat" && "placeholder:text-muted-foreground",
className
)}
ref={ref}
Expand All @@ -19,6 +52,49 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
);
}
);
TextAreaBase.displayName = "TextAreaBase";

export type TextareaProps = TextAreaBaseProps &
VariantProps<typeof textareaVariants> & {
resizeable?: boolean;
endContent?: React.ReactNode;
bottomContent?: React.ReactNode;
};

const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
(
{
className,
resizeable = false,
variant,
endContent,
bottomContent,
...props
},
ref
) => {
return (
<TextAreaWrapper
variant={variant}
className={cn("flex flex-col", className)}
>
<div className="w-full flex">
<TextAreaBase
className={cn(
"w-full px-3 py-2 bg-transparent border-none focus-visible:border-none focus-visible:outline-none",
!resizeable && "resize-none"
)}
variant={variant}
ref={ref}
{...props}
/>
{endContent}
</div>
{bottomContent}
</TextAreaWrapper>
);
}
);
Textarea.displayName = "Textarea";

// note(ryanhopperlowe): AutosizeTextarea taken from (https://shadcnui-expansions.typeart.cc/docs/autosize-textarea)
Expand Down Expand Up @@ -90,10 +166,10 @@ export type AutosizeTextAreaRef = {
minHeight: number;
};

export type AutosizeTextAreaProps = {
export type AutosizeTextAreaProps = TextareaProps & {
maxHeight?: number;
minHeight?: number;
} & React.TextareaHTMLAttributes<HTMLTextAreaElement>;
};

const AutosizeTextarea = React.forwardRef<
AutosizeTextAreaRef,
Expand All @@ -105,7 +181,6 @@ const AutosizeTextarea = React.forwardRef<
minHeight = 52,
className,
onChange,
value,
...props
}: AutosizeTextAreaProps,
ref: React.Ref<AutosizeTextAreaRef>
Expand Down Expand Up @@ -139,7 +214,6 @@ const AutosizeTextarea = React.forwardRef<
return (
<Textarea
{...props}
value={value}
ref={initRef}
className={cn("resize-none", className)}
onChange={onChange}
Expand Down

0 comments on commit a2330b1

Please sign in to comment.