Make chat page layout cleaner + fix updating assistant images (#1973)

* ux updates for clarity
- [x] 'folders' -> 'chat folders'
- [x] sidebar to bottom left and smaller
- [x] Sidebar -> smaller logo
- [x] Align things properly
- [x] Expliti Pin: immediate + "Pin / Unpin"
- [x] Logo size smaller
- [x] Align things properly
- [x] Optionally fix gradient in sidebar
- [x] Upload logo to existing assistants

* remove unneeded logs

* run pretty

* actually run pretty!

* fix web file type

* fix very minor typo

* clean type for buildPersonaAPIBody

* fix span formatting

* HUGE ui change
This commit is contained in:
pablodanswer 2024-07-29 20:44:35 -07:00 committed by GitHub
parent fb6695a983
commit 7932e764d6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 70 additions and 42 deletions

View File

@ -571,7 +571,6 @@ export function AssistantEditor({
)}
</div>
</div>
<div className="mb-6">
<div className="flex gap-x-2 items-center">
<div className="block font-medium text-base">

View File

@ -105,7 +105,7 @@ function updatePrompt({
function buildPersonaAPIBody(
creationRequest: PersonaCreationRequest | PersonaUpdateRequest,
promptId: number,
uploaded_image_id?: string //
uploaded_image_id: string | null
) {
const {
name,
@ -190,7 +190,7 @@ export async function createPersona(
"Content-Type": "application/json",
},
body: JSON.stringify(
buildPersonaAPIBody(personaCreationRequest, promptId, fileId!)
buildPersonaAPIBody(personaCreationRequest, promptId, fileId)
),
})
: null;
@ -225,6 +225,14 @@ export async function updatePersona(
promptId = promptResponse.ok ? (await promptResponse.json()).id : null;
}
let fileId = null;
if (personaUpdateRequest.uploaded_image) {
fileId = await uploadFile(personaUpdateRequest.uploaded_image);
if (!fileId) {
return [promptResponse, null];
}
}
const updatePersonaResponse =
promptResponse.ok && promptId
? await fetch(`/api/persona/${id}`, {
@ -233,7 +241,7 @@ export async function updatePersona(
"Content-Type": "application/json",
},
body: JSON.stringify(
buildPersonaAPIBody(personaUpdateRequest, promptId)
buildPersonaAPIBody(personaUpdateRequest, promptId, fileId)
),
})
: null;

View File

@ -183,7 +183,7 @@ export default function AddConnector({
const { message, isSuccess, response } = await submitConnector<any>(
{
connector_specific_config: values,
input_type: "poll",
input_type: connector == "web" ? "load_state" : "poll", // single case
name: name,
source: connector,
refresh_freq: (refreshFreq || defaultRefresh) * 60,

View File

@ -90,7 +90,7 @@ export function ChatSessionDisplay({
/>
)}
<Link
className="flex my-1 relative"
className="flex my-1 group relative"
key={chatSession.id}
href={
search
@ -126,10 +126,15 @@ export function ChatSessionDisplay({
className="-my-px px-1 mr-2 w-full rounded"
/>
) : (
<p className="break-all overflow-hidden whitespace-nowrap mr-3 text-emphasis">
<p className="break-all overflow-hidden whitespace-nowrap w-full mr-3 relative">
{chatName || `Chat ${chatSession.id}`}
<span
className={`absolute right-0 top-0 h-full w-8 bg-gradient-to-r from-transparent
${isSelected ? "to-background-200" : " to-background-100 group-hover:to-background-200"} `}
/>
</p>
)}
{isSelected &&
(isRenamingChat ? (
<div className="ml-auto my-auto flex">
@ -199,12 +204,6 @@ export function ChatSessionDisplay({
</div>
))}
</div>
{isSelected && !isRenamingChat && !delayedSkipGradient && (
<div className="absolute bottom-0 right-0 top-0 bg-gradient-to-l to-transparent from-hover w-20 from-60% rounded" />
)}
{!isSelected && !delayedSkipGradient && (
<div className="absolute bottom-0 right-0 top-0 bg-gradient-to-l to-transparent from-background-100 w-8 from-0% rounded" />
)}
</>
</BasicSelectable>
</Link>

View File

@ -101,7 +101,7 @@ export const HistorySidebar = forwardRef<HTMLDivElement, HistorySidebarProps>(
transition-transform`}
>
<div className="max-w-full ml-3 mr-3 mt-2 flex flex gap-x-1 items-center my-auto text-text-700 text-xl">
<div className="mr-1 mb-auto h-6 w-6">
<div className="mr-1 invisible mb-auto h-6 w-6">
<Logo height={24} width={24} />
</div>
@ -120,8 +120,11 @@ export const HistorySidebar = forwardRef<HTMLDivElement, HistorySidebarProps>(
)}
</div>
{toggleSidebar && (
<Tooltip delayDuration={1000} content={`${commandSymbol}E show`}>
<button className="mb-auto ml-auto" onClick={toggleSidebar}>
<Tooltip
delayDuration={0}
content={toggled ? `Unpin sidebar` : "Pin sidebar"}
>
<button className="my-auto ml-auto" onClick={toggleSidebar}>
{!toggled ? <RightToLineIcon /> : <LefToLineIcon />}
</button>
</Tooltip>

View File

@ -62,7 +62,7 @@ export function PagesTab({
{folders && folders.length > 0 && (
<div className="py-2 border-b border-border">
<div className="text-xs text-subtle flex pb-0.5 mb-1.5 mt-2 font-bold">
Folders
Chat Folders
</div>
<FolderList
folders={folders}

View File

@ -5,6 +5,7 @@ import { Logo } from "@/components/Logo";
import { SettingsContext } from "@/components/settings/SettingsProvider";
import { NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED } from "@/lib/constants";
import { useContext } from "react";
import { FiSidebar } from "react-icons/fi";
export default function FixedLogo() {
const combinedSettings = useContext(SettingsContext);
@ -12,24 +13,29 @@ export default function FixedLogo() {
const enterpriseSettings = combinedSettings?.enterpriseSettings;
return (
<div className="absolute flex z-40 left-2.5 top-2">
<div className="max-w-[200px] flex gap-x-1 my-auto">
<div className="flex-none invisible mb-auto">
<Logo />
</div>
<div className="">
{enterpriseSettings && enterpriseSettings.application_name ? (
<div>
<HeaderTitle>{enterpriseSettings.application_name}</HeaderTitle>
{!NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED && (
<p className="text-xs text-subtle">Powered by Danswer</p>
)}
</div>
) : (
<HeaderTitle>Danswer</HeaderTitle>
)}
<>
<div className="absolute flex z-40 left-2.5 top-2">
<div className="max-w-[200px] flex items-center gap-x-1 my-auto">
<div className="flex-none my-auto">
<Logo height={24} width={24} />
</div>
<div className="">
{enterpriseSettings && enterpriseSettings.application_name ? (
<div>
<HeaderTitle>{enterpriseSettings.application_name}</HeaderTitle>
{!NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED && (
<p className="text-xs text-subtle">Powered by Danswer</p>
)}
</div>
) : (
<HeaderTitle>Danswer</HeaderTitle>
)}
</div>
</div>
</div>
</div>
<div className="absolute left-2.5 bottom-4">
<FiSidebar />
</div>
</>
);
}

View File

@ -41,6 +41,7 @@ export const IconImageSelection = ({
</div>
);
};
export function IconImageUpload({
selectedFile,
updateFile,

View File

@ -5,7 +5,10 @@ import { FiShare2, FiSidebar } from "react-icons/fi";
import { SetStateAction, useContext, useEffect } from "react";
import { Logo } from "../Logo";
import { ChatIcon, NewChatIcon, PlusCircleIcon } from "../icons/icons";
import { NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA } from "@/lib/constants";
import {
NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED,
NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA,
} from "@/lib/constants";
import { ChatSession } from "@/app/chat/interfaces";
import { HeaderTitle } from "../header/Header";
import { Tooltip } from "../tooltip/Tooltip";
@ -60,13 +63,20 @@ export default function FunctionalHeader({
<div className="pb-6 left-0 sticky top-0 z-10 w-full relative flex">
<div className="mt-2 mx-4 text-text-700 flex w-full">
<div className="absolute z-[100] my-auto flex items-center text-xl font-bold">
<div className="pt-[2px] mb-auto">
<div className="pt-[2px] invisible mb-auto">
<FiSidebar size={20} />
</div>
<div className="break-words inline-block w-fit ml-2 text-text-700 text-xl">
<div className="invisible break-words inline-block w-fit ml-2 text-text-700 text-xl">
<div className="max-w-[200px]">
{enterpriseSettings && enterpriseSettings.application_name ? (
<HeaderTitle>{enterpriseSettings.application_name}</HeaderTitle>
<div>
<HeaderTitle>
{enterpriseSettings.application_name}
</HeaderTitle>
{!NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED && (
<p className="text-xs text-subtle">Powered by Danswer</p>
)}
</div>
) : (
<HeaderTitle>Danswer</HeaderTitle>
)}
@ -76,7 +86,7 @@ export default function FunctionalHeader({
{page == "chat" && (
<Tooltip delayDuration={1000} content={`${commandSymbol}U`}>
<Link
className="mb-auto pt-[2px]"
className="my-auto"
href={
`/${page}` +
(NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA &&
@ -86,7 +96,7 @@ export default function FunctionalHeader({
}
>
<div className="cursor-pointer ml-2 flex-none text-text-700 hover:text-text-600 transition-colors duration-300">
<NewChatIcon size={20} className="" />
<NewChatIcon size={20} />
</div>
</Link>
</Tooltip>

View File

@ -12,13 +12,15 @@ import { NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED } from "@/lib/constan
import { pageType } from "@/app/chat/sessionSidebar/types";
export function HeaderTitle({ children }: { children: JSX.Element | string }) {
const isString = typeof children === "string";
const textSize = isString && children.length > 10 ? "text-xl" : "text-2xl";
return (
<h1 className="flex text-2xl text-strong leading-none font-bold">
<h1 className={`flex ${textSize} text-strong leading-none font-bold`}>
{children}
</h1>
);
}
interface HeaderProps {
user: User | null;
page?: pageType;