mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-05-07 18:30:25 +02:00
Improve shared chat page (#2066)
* improve look of shared chat page * remove log * cleaner display * add initializing loader to shared chat page * updated danswer loaders (for prism) * remove default share
This commit is contained in:
parent
291e6c4198
commit
d2e16a599d
@ -129,7 +129,6 @@ def get_chat_session(
|
||||
db_session: Session = Depends(get_session),
|
||||
) -> ChatSessionDetailResponse:
|
||||
user_id = user.id if user is not None else None
|
||||
|
||||
try:
|
||||
chat_session = get_chat_session_by_id(
|
||||
chat_session_id=session_id,
|
||||
|
@ -15,8 +15,8 @@ import {
|
||||
ToolCallMetadata,
|
||||
} from "./interfaces";
|
||||
|
||||
import Prism from "prismjs";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
import { HistorySidebar } from "./sessionSidebar/HistorySidebar";
|
||||
import { Persona } from "../admin/assistants/interfaces";
|
||||
import { HealthCheckBanner } from "@/components/health/healthcheck";
|
||||
@ -193,6 +193,12 @@ export function ChatPage({
|
||||
existingChatSessionId !== null
|
||||
);
|
||||
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
useEffect(() => {
|
||||
Prism.highlightAll();
|
||||
setIsReady(true);
|
||||
}, []);
|
||||
|
||||
// this is triggered every time the user switches which chat
|
||||
// session they are using
|
||||
useEffect(() => {
|
||||
@ -1233,7 +1239,7 @@ export function ChatPage({
|
||||
/>
|
||||
)}
|
||||
|
||||
{documentSidebarInitialWidth !== undefined ? (
|
||||
{documentSidebarInitialWidth !== undefined && isReady ? (
|
||||
<Dropzone onDrop={handleImageUpload} noClick>
|
||||
{({ getRootProps }) => (
|
||||
<div className="flex h-full w-full">
|
||||
@ -1241,15 +1247,15 @@ export function ChatPage({
|
||||
<div
|
||||
style={{ transition: "width 0.30s ease-out" }}
|
||||
className={`
|
||||
flex-none
|
||||
overflow-y-hidden
|
||||
bg-background-100
|
||||
transition-all
|
||||
bg-opacity-80
|
||||
duration-300
|
||||
ease-in-out
|
||||
h-full
|
||||
${toggledSidebar ? "w-[250px]" : "w-[0px]"}
|
||||
flex-none
|
||||
overflow-y-hidden
|
||||
bg-background-100
|
||||
transition-all
|
||||
bg-opacity-80
|
||||
duration-300
|
||||
ease-in-out
|
||||
h-full
|
||||
${toggledSidebar ? "w-[250px]" : "w-[0px]"}
|
||||
`}
|
||||
></div>
|
||||
)}
|
||||
|
@ -19,6 +19,7 @@ export function InMessageImage({ fileId }: { fileId: string }) {
|
||||
{!imageLoaded && (
|
||||
<div className="absolute inset-0 bg-gray-200 animate-pulse rounded-lg" />
|
||||
)}
|
||||
|
||||
<Image
|
||||
width={1200}
|
||||
height={1200}
|
||||
|
@ -1,11 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
FiCpu,
|
||||
FiImage,
|
||||
FiThumbsDown,
|
||||
FiThumbsUp,
|
||||
FiUser,
|
||||
FiEdit2,
|
||||
FiChevronRight,
|
||||
FiChevronLeft,
|
||||
@ -37,9 +32,6 @@ import { InMessageImage } from "../files/images/InMessageImage";
|
||||
import { CodeBlock } from "./CodeBlock";
|
||||
import rehypePrism from "rehype-prism-plus";
|
||||
|
||||
// Prism stuff
|
||||
import Prism from "prismjs";
|
||||
|
||||
import "prismjs/themes/prism-tomorrow.css";
|
||||
import "./custom-code-styles.css";
|
||||
import { Persona } from "@/app/admin/assistants/interfaces";
|
||||
@ -110,6 +102,7 @@ function FileDisplay({
|
||||
}
|
||||
|
||||
export const AIMessage = ({
|
||||
shared,
|
||||
isActive,
|
||||
toggleDocumentSelection,
|
||||
alternativeAssistant,
|
||||
@ -132,6 +125,7 @@ export const AIMessage = ({
|
||||
retrievalDisabled,
|
||||
currentPersona,
|
||||
}: {
|
||||
shared?: boolean;
|
||||
isActive?: boolean;
|
||||
selectedDocuments?: DanswerDocument[] | null;
|
||||
toggleDocumentSelection?: () => void;
|
||||
@ -175,19 +169,10 @@ export const AIMessage = ({
|
||||
|
||||
const finalContent = processContent(content as string);
|
||||
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
useEffect(() => {
|
||||
Prism.highlightAll();
|
||||
setIsReady(true);
|
||||
}, []);
|
||||
|
||||
const { isHovering, trackedElementRef, hoverElementRef } = useMouseTracking();
|
||||
|
||||
const settings = useContext(SettingsContext);
|
||||
// this is needed to give Prism a chance to load
|
||||
if (!isReady) {
|
||||
return <div />;
|
||||
}
|
||||
|
||||
const selectedDocumentIds =
|
||||
selectedDocuments?.map((document) => document.document_id) || [];
|
||||
@ -247,8 +232,10 @@ export const AIMessage = ({
|
||||
|
||||
return (
|
||||
<div ref={trackedElementRef} className={"py-5 px-2 lg:px-5 relative flex "}>
|
||||
<div className="mx-auto w-[90%] max-w-message-max">
|
||||
<div className="mobile:ml-4 xl:ml-8">
|
||||
<div
|
||||
className={`mx-auto ${shared ? "w-full" : "w-[90%]"} max-w-message-max`}
|
||||
>
|
||||
<div className={`${!shared && "mobile:ml-4 xl:ml-8"}`}>
|
||||
<div className="flex">
|
||||
<AssistantIcon
|
||||
size="small"
|
||||
@ -622,7 +609,9 @@ export const HumanMessage = ({
|
||||
otherMessagesCanSwitchTo,
|
||||
onEdit,
|
||||
onMessageSelection,
|
||||
shared,
|
||||
}: {
|
||||
shared?: boolean;
|
||||
content: string;
|
||||
files?: FileDescriptor[];
|
||||
messageId?: number | null;
|
||||
@ -669,7 +658,9 @@ export const HumanMessage = ({
|
||||
onMouseEnter={() => setIsHovered(true)}
|
||||
onMouseLeave={() => setIsHovered(false)}
|
||||
>
|
||||
<div className="mx-auto w-[90%] max-w-searchbar-max">
|
||||
<div
|
||||
className={`mx-auto ${shared ? "w-full" : "w-[90%]"} max-w-searchbar-max`}
|
||||
>
|
||||
<div className="xl:ml-8">
|
||||
<div className="flex flex-col mr-4">
|
||||
<FileDisplay alignBubble files={files || []} />
|
||||
|
@ -63,13 +63,6 @@ export function ShareChatSessionModal({
|
||||
<h2 className="text-2xl text-emphasis font-bold flex my-auto">
|
||||
Share link to Chat
|
||||
</h2>
|
||||
|
||||
<div
|
||||
onClick={onClose}
|
||||
className="my-auto ml-auto p-2 hover:bg-hover rounded cursor-pointer"
|
||||
>
|
||||
<FiX size={20} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{linkGenerating && <Spinner />}
|
||||
|
@ -1,14 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { FiArrowDown, FiEdit, FiFolderPlus } from "react-icons/fi";
|
||||
import {
|
||||
Dispatch,
|
||||
ForwardedRef,
|
||||
forwardRef,
|
||||
SetStateAction,
|
||||
useContext,
|
||||
useEffect,
|
||||
} from "react";
|
||||
import { FiEdit, FiFolderPlus } from "react-icons/fi";
|
||||
import { ForwardedRef, forwardRef, useContext, useEffect } from "react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { ChatSession } from "../interfaces";
|
||||
@ -26,10 +19,7 @@ import {
|
||||
ClosedBookIcon,
|
||||
} from "@/components/icons/icons";
|
||||
import { PagesTab } from "./PagesTab";
|
||||
import { Tooltip } from "@/components/tooltip/Tooltip";
|
||||
import KeyboardSymbol from "@/lib/browserUtilities";
|
||||
import { pageType } from "./types";
|
||||
import { usePaidEnterpriseFeaturesEnabled } from "@/components/settings/usePaidEnterpriseFeaturesEnabled";
|
||||
import LogoType from "@/components/header/LogoType";
|
||||
|
||||
interface HistorySidebarProps {
|
||||
|
@ -1 +1 @@
|
||||
export type pageType = "search" | "chat" | "assistants" | "admin";
|
||||
export type pageType = "search" | "chat" | "assistants" | "admin" | "shared";
|
||||
|
@ -1,4 +1,5 @@
|
||||
"use client";
|
||||
import Prism from "prismjs";
|
||||
|
||||
import { humanReadableFormat } from "@/lib/time";
|
||||
import { BackendChatSession } from "../../interfaces";
|
||||
@ -11,20 +12,22 @@ import { AIMessage, HumanMessage } from "../../message/Messages";
|
||||
import { Button, Callout, Divider } from "@tremor/react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Persona } from "@/app/admin/assistants/interfaces";
|
||||
import { useContext } from "react";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { SettingsContext } from "@/components/settings/SettingsProvider";
|
||||
import { DanswerInitializingLoader } from "@/components/DanswerInitializingLoader";
|
||||
|
||||
function BackToDanswerButton() {
|
||||
const router = useRouter();
|
||||
const enterpriseSettings = useContext(SettingsContext)?.enterpriseSettings;
|
||||
|
||||
return (
|
||||
<div className="absolute bottom-4 w-full flex border-t border-border pt-4">
|
||||
<div className="absolute bottom-0 bg-background w-full flex border-t border-border py-4">
|
||||
<div className="mx-auto">
|
||||
<Button onClick={() => router.push("/chat")}>
|
||||
Back to {enterpriseSettings?.application_name || "Danswer Chat"}
|
||||
</Button>
|
||||
</div>
|
||||
pr
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -36,6 +39,11 @@ export function SharedChatDisplay({
|
||||
chatSession: BackendChatSession | null;
|
||||
availableAssistants: Persona[];
|
||||
}) {
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
useEffect(() => {
|
||||
Prism.highlightAll();
|
||||
setIsReady(true);
|
||||
}, []);
|
||||
if (!chatSession) {
|
||||
return (
|
||||
<div className="min-h-full w-full">
|
||||
@ -44,12 +52,10 @@ export function SharedChatDisplay({
|
||||
Did not find a shared chat with the specified ID.
|
||||
</Callout>
|
||||
</div>
|
||||
|
||||
<BackToDanswerButton />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const currentPersona = availableAssistants.find(
|
||||
(persona) => persona.id === chatSession.persona_id
|
||||
);
|
||||
@ -59,10 +65,10 @@ export function SharedChatDisplay({
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="w-full overflow-hidden">
|
||||
<div className="w-full h-[100dvh] overflow-hidden">
|
||||
<div className="flex max-h-full overflow-hidden pb-[72px]">
|
||||
<div className="flex w-full overflow-hidden overflow-y-scroll">
|
||||
<div className="mx-auto">
|
||||
<div className="w-full h-full flex-col flex max-w-message-max mx-auto">
|
||||
<div className="px-5 pt-8">
|
||||
<h1 className="text-3xl text-strong font-bold">
|
||||
{chatSession.description ||
|
||||
@ -74,32 +80,42 @@ export function SharedChatDisplay({
|
||||
|
||||
<Divider />
|
||||
</div>
|
||||
|
||||
<div className="pb-16">
|
||||
{messages.map((message) => {
|
||||
if (message.type === "user") {
|
||||
return (
|
||||
<HumanMessage
|
||||
key={message.messageId}
|
||||
content={message.message}
|
||||
files={message.files}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<AIMessage
|
||||
currentPersona={currentPersona!}
|
||||
key={message.messageId}
|
||||
messageId={message.messageId}
|
||||
content={message.message}
|
||||
personaName={chatSession.persona_name}
|
||||
citedDocuments={getCitedDocumentsFromMessage(message)}
|
||||
isComplete
|
||||
/>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
{isReady ? (
|
||||
<div className="w-full pb-16">
|
||||
{messages.map((message) => {
|
||||
if (message.type === "user") {
|
||||
return (
|
||||
<HumanMessage
|
||||
shared
|
||||
key={message.messageId}
|
||||
content={message.message}
|
||||
files={message.files}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<AIMessage
|
||||
shared
|
||||
currentPersona={currentPersona!}
|
||||
key={message.messageId}
|
||||
messageId={message.messageId}
|
||||
content={message.message}
|
||||
files={message.files || []}
|
||||
personaName={chatSession.persona_name}
|
||||
citedDocuments={getCitedDocumentsFromMessage(message)}
|
||||
isComplete
|
||||
/>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
) : (
|
||||
<div className="grow flex-0 h-screen w-full flex items-center justify-center">
|
||||
<div className="mb-[33vh]">
|
||||
<DanswerInitializingLoader />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -57,7 +57,7 @@ export default async function Page({ params }: { params: { chatId: string } }) {
|
||||
return (
|
||||
<div>
|
||||
<div className="absolute top-0 z-40 w-full">
|
||||
<FunctionalHeader page="chat" toggleSidebar={() => null} user={user} />
|
||||
<FunctionalHeader page="shared" user={user} />
|
||||
</div>
|
||||
|
||||
<div className="flex relative bg-background text-default overflow-hidden pt-16 h-screen">
|
||||
|
@ -18,7 +18,7 @@ export default function FunctionalHeader({
|
||||
page,
|
||||
currentChatSession,
|
||||
setSharingModalVisible,
|
||||
toggleSidebar,
|
||||
toggleSidebar = () => null,
|
||||
reset = () => null,
|
||||
sidebarToggled,
|
||||
}: {
|
||||
@ -28,7 +28,7 @@ export default function FunctionalHeader({
|
||||
sidebarToggled?: boolean;
|
||||
currentChatSession?: ChatSession | null | undefined;
|
||||
setSharingModalVisible?: (value: SetStateAction<boolean>) => void;
|
||||
toggleSidebar: () => void;
|
||||
toggleSidebar?: () => void;
|
||||
}) {
|
||||
const combinedSettings = useContext(SettingsContext);
|
||||
const enterpriseSettings = combinedSettings?.enterpriseSettings;
|
||||
|
Loading…
x
Reference in New Issue
Block a user