Misc UI improvments

This commit is contained in:
Weves
2024-04-30 20:35:07 -07:00
committed by Chris Weaver
parent b89e9127d7
commit 96762cfe44
9 changed files with 137 additions and 78 deletions

View File

@@ -222,7 +222,6 @@ export function LLMProviderUpdateForm({
name,
value: name,
}))}
direction="up"
maxHeight="max-h-56"
/>
) : (
@@ -246,7 +245,6 @@ export function LLMProviderUpdateForm({
value: name,
}))}
includeDefault
direction="up"
maxHeight="max-h-56"
/>
) : (

View File

@@ -51,7 +51,7 @@ function Selector({
{label && <Label>{label}</Label>}
{subtext && <SubLabel>{subtext}</SubLabel>}
<div className="mt-2">
<div className="mt-2 w-full max-w-96">
<DefaultDropdown
options={options}
selected={selected}

View File

@@ -677,6 +677,18 @@ export function ChatPage({
{documentSidebarInitialWidth !== undefined ? (
<Dropzone
onDrop={(acceptedFiles) => {
const llmAcceptsImages = checkLLMSupportsImageInput(
...getFinalLLM(llmProviders, livePersona)
);
if (!llmAcceptsImages) {
setPopup({
type: "error",
message:
"The current Assistant does not support image input. Please select an assistant with Vision support.",
});
return;
}
uploadFilesForChat(acceptedFiles).then(([fileIds, error]) => {
if (error) {
setPopup({
@@ -690,11 +702,6 @@ export function ChatPage({
});
}}
noClick
disabled={
!checkLLMSupportsImageInput(
...getFinalLLM(llmProviders, livePersona)
)
}
onDragLeave={() => console.log("buh")}
onDragEnter={() => console.log("floppa")}
>

View File

@@ -3,6 +3,7 @@ import { BasicSelectable } from "@/components/BasicClickable";
import { User } from "@/lib/types";
import { Text } from "@tremor/react";
import Link from "next/link";
import { FaRobot } from "react-icons/fa";
import { FiEdit } from "react-icons/fi";
function AssistantDisplay({
@@ -24,7 +25,9 @@ function AssistantDisplay({
<div className="w-full" onClick={() => onSelect(persona)}>
<BasicSelectable selected={false} fullWidth>
<div className="flex">
<div className="truncate w-48 3xl:w-56">{persona.name}</div>
<div className="truncate w-48 3xl:w-56 flex">
<FaRobot className="mr-2 my-auto" size={16} /> {persona.name}
</div>
</div>
</BasicSelectable>
</div>
@@ -54,7 +57,7 @@ export function AssistantsTab({
const globalAssistants = personas.filter((persona) => persona.is_public);
const personalAssistants = personas.filter(
(persona) =>
!user || (persona.users.includes(user.id) && !persona.is_public)
(!user || persona.users.includes(user.id)) && !persona.is_public
);
return (

View File

@@ -156,6 +156,7 @@ export function ChatSessionDisplay({
/>
</div>
}
requiresContentPadding
/>
</div>
</div>

View File

@@ -286,78 +286,91 @@ export function DefaultDropdown({
selected,
onSelect,
includeDefault = false,
direction = "down",
side,
maxHeight,
}: {
options: StringOrNumberOption[];
selected: string | null;
onSelect: (value: string | number | null) => void;
includeDefault?: boolean;
direction?: "up" | "down";
side?: "top" | "right" | "bottom" | "left";
maxHeight?: string;
}) {
const selectedOption = options.find((option) => option.value === selected);
const [isOpen, setIsOpen] = useState(false);
const Content = (
<div
className={`
flex
text-sm
bg-background
px-3
py-1.5
rounded-lg
border
border-border
cursor-pointer`}
>
<p className="line-clamp-1">
{selectedOption?.name ||
(includeDefault ? "Default" : "Select an option...")}
</p>
<FiChevronDown className="my-auto ml-auto" />
</div>
);
const Dropdown = (
<div
className={`
border
border
rounded-lg
flex
flex-col
bg-background
${maxHeight || "max-h-96"}
overflow-y-auto
overscroll-contain`}
>
{includeDefault && (
<DefaultDropdownElement
key={-1}
name="Default"
onSelect={() => {
onSelect(null);
}}
isSelected={selected === null}
/>
)}
{options.map((option, ind) => {
const isSelected = option.value === selected;
return (
<DefaultDropdownElement
key={option.value}
name={option.name}
description={option.description}
onSelect={() => onSelect(option.value)}
isSelected={isSelected}
/>
);
})}
</div>
);
return (
<CustomDropdown
direction={direction}
dropdown={
<div
className={`
border
border
rounded-lg
flex
flex-col
bg-background
${maxHeight || "max-h-96"}
overflow-y-auto
overscroll-contain`}
>
{includeDefault && (
<DefaultDropdownElement
key={-1}
name="Default"
onSelect={() => {
onSelect(null);
}}
isSelected={selected === null}
/>
)}
{options.map((option, ind) => {
const isSelected = option.value === selected;
return (
<DefaultDropdownElement
key={option.value}
name={option.name}
description={option.description}
onSelect={() => onSelect(option.value)}
isSelected={isSelected}
/>
);
})}
</div>
}
>
<div
className={`
flex
text-sm
bg-background
px-3
py-1.5
rounded-lg
border
border-border
cursor-pointer`}
>
<p className="line-clamp-1">
{selectedOption?.name ||
(includeDefault ? "Default" : "Select an option...")}
</p>
<FiChevronDown className="my-auto ml-auto" />
</div>
</CustomDropdown>
<div onClick={() => setIsOpen(!isOpen)}>
<Popover
open={isOpen}
onOpenChange={(open) => setIsOpen(open)}
content={Content}
popover={Dropdown}
align="start"
side={side}
sideOffset={5}
matchWidth
/>
</div>
);
}

View File

@@ -233,7 +233,7 @@ interface SelectorFormFieldProps {
options: StringOrNumberOption[];
subtext?: string | JSX.Element;
includeDefault?: boolean;
direction?: "up" | "down";
side?: "top" | "right" | "bottom" | "left";
maxHeight?: string;
onSelect?: (selected: string | number | null) => void;
}
@@ -244,7 +244,7 @@ export function SelectorFormField({
options,
subtext,
includeDefault = false,
direction = "down",
side = "bottom",
maxHeight,
onSelect,
}: SelectorFormFieldProps) {
@@ -262,7 +262,7 @@ export function SelectorFormField({
selected={field.value}
onSelect={onSelect || ((selected) => setFieldValue(name, selected))}
includeDefault={includeDefault}
direction={direction}
side={side}
maxHeight={maxHeight}
/>
</div>

View File

@@ -1,5 +1,7 @@
"use client";
import "./styles.css";
import * as RadixPopover from "@radix-ui/react-popover";
export function Popover({
@@ -7,11 +9,21 @@ export function Popover({
onOpenChange,
content,
popover,
side,
align,
sideOffset,
matchWidth,
requiresContentPadding,
}: {
open: boolean;
onOpenChange: (open: boolean) => void;
content: JSX.Element;
popover: JSX.Element;
side?: "top" | "right" | "bottom" | "left";
align?: "start" | "center" | "end";
sideOffset?: number;
matchWidth?: boolean;
requiresContentPadding?: boolean;
}) {
/*
This Popover is needed when we want to put a popup / dropdown in a component
@@ -24,14 +36,30 @@ export function Popover({
return (
<RadixPopover.Root open={open} onOpenChange={onOpenChange}>
<RadixPopover.Trigger>
<RadixPopover.Trigger style={{ width: "100%" }}>
{/* NOTE: this weird `-mb-1.5` is needed to offset the Anchor, otherwise
the content will shift up by 1.5px when the Popover is open. */}
{open ? <div className="-mb-1.5">{content}</div> : content}
{open ? (
<div className={requiresContentPadding ? "-mb-1.5" : ""}>
{content}
</div>
) : (
content
)}
</RadixPopover.Trigger>
<RadixPopover.Anchor />
<RadixPopover.Portal>
<RadixPopover.Content>{popover}</RadixPopover.Content>
<RadixPopover.Content
className={
"PopoverContent z-[100] " +
(matchWidth ? " PopoverContentMatchWidth" : "")
}
asChild
side={side}
align={align}
sideOffset={sideOffset}
>
{popover}
</RadixPopover.Content>
</RadixPopover.Portal>
</RadixPopover.Root>
);

View File

@@ -0,0 +1,9 @@
/* styles.css */
.PopoverContentMatchWidth {
width: var(--radix-popover-trigger-width);
}
.PopoverContent[data-side="top"] {
transform: translateY(var(--radix-popover-trigger-height) px);
}