diff --git a/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/Citation/index.jsx b/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/Citation/index.jsx index 4a1afe3f4de..a28e859218f 100644 --- a/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/Citation/index.jsx +++ b/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/Citation/index.jsx @@ -10,15 +10,17 @@ import { Info, ArrowSquareOut, GithubLogo, - Link, X, YoutubeLogo, + LinkSimple, GitlabLogo, } from "@phosphor-icons/react"; import ConfluenceLogo from "@/media/dataConnectors/confluence.png"; import DrupalWikiLogo from "@/media/dataConnectors/drupalwiki.png"; import ObsidianLogo from "@/media/dataConnectors/obsidian.png"; import { toPercentString } from "@/utils/numbers"; +import pluralize from "pluralize"; +import useTextSize from "@/hooks/useTextSize"; function combineLikeSources(sources) { const combined = {}; @@ -42,29 +44,33 @@ export default function Citations({ sources = [] }) { if (sources.length === 0) return null; const [open, setOpen] = useState(false); const [selectedSource, setSelectedSource] = useState(null); + const { textSizeClass } = useTextSize(); return (
{open && ( -
+
{combineLikeSources(sources).map((source) => ( setSelectedSource(source)} + textSizeClass={textSizeClass} /> ))}
@@ -79,8 +85,8 @@ export default function Citations({ sources = [] }) { ); } -const Citation = memo(({ source, onClick }) => { - const { title } = source; +const Citation = memo(({ source, onClick, textSizeClass }) => { + const { title, references = 1 } = source; if (!title) return null; const chunkSourceInfo = parseChunkSource(source); const truncatedTitle = chunkSourceInfo?.text ?? middleTruncate(title, 25); @@ -89,13 +95,25 @@ const Citation = memo(({ source, onClick }) => { : ICONS.file; return ( -
- -

{truncatedTitle}

-
+
+ +
+
+

+ {truncatedTitle} +

+

{`${references} ${pluralize("Reference", Number(references) || 1)}`}

+
+ ); }); @@ -118,12 +136,14 @@ function CitationDetailModal({ source, onClose }) { href={linkTo} target="_blank" rel="noreferrer" - className="text-xl font-semibold text-white overflow-hidden overflow-ellipsis whitespace-nowrap hover:underline hover:text-blue-300 flex items-center gap-x-1" + className="text-xl w-[90%] font-semibold text-white whitespace-nowrap hover:underline hover:text-blue-300 flex items-center gap-x-1" > -

- {webpageUrl} - -

+
+

+ {webpageUrl} +

+ +
) : (

@@ -222,7 +242,6 @@ function parseChunkSource({ title = "", chunks = [] }) { const sourceID = supportedSources.find((source) => chunks[0].chunkSource?.startsWith(source) ); - console.log({ sourceID }); let url, text, icon; // Try to parse the URL from the chunk source @@ -286,21 +305,19 @@ function parseChunkSource({ title = "", chunks = [] }) { return nullResponse; } -// Patch to render Confluence icon as a element like we do with Phosphor -const ConfluenceIcon = ({ ...props }) => ( - +const ConfluenceIcon = ({ size = 16, ...props }) => ( + ); - -// Patch to render DrupalWiki icon as a element like we do with Phosphor -const DrupalWikiIcon = ({ ...props }) => ( - +const DrupalWikiIcon = ({ size = 16, ...props }) => ( + +); +const ObsidianIcon = ({ size = 16, ...props }) => ( + ); - -const ObsidianIcon = ({ ...props }) => ; const ICONS = { file: FileText, - link: Link, + link: LinkSimple, youtube: YoutubeLogo, github: GithubLogo, gitlab: GitlabLogo, diff --git a/frontend/src/components/WorkspaceChat/ChatContainer/ChatTooltips/index.jsx b/frontend/src/components/WorkspaceChat/ChatContainer/ChatTooltips/index.jsx index 56ad1b8c4e5..97fc0c5c628 100644 --- a/frontend/src/components/WorkspaceChat/ChatContainer/ChatTooltips/index.jsx +++ b/frontend/src/components/WorkspaceChat/ChatContainer/ChatTooltips/index.jsx @@ -1,4 +1,5 @@ import { Tooltip } from "react-tooltip"; +import { createPortal } from "react-dom"; /** * Set the tooltips for the chat container in bulk. @@ -53,14 +54,6 @@ export function ChatTooltips() { delayShow={300} className="tooltip !text-xs" /> - + ); } + +/** + * This is a document level tooltip that is rendered at the top most level of the document + * to ensure it is rendered above the chat history and other elements. Anytime we have tooltips + * in modals the z-indexing can be recalculated and we need to ensure it is rendered at the top most level + * so it positions correctly. + */ +function DocumentLevelTooltip() { + return createPortal( + <> + + , + document.body + ); +} diff --git a/frontend/src/index.css b/frontend/src/index.css index 3a07acde0e3..38ddf1a158b 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -277,25 +277,22 @@ a { } .doc__source { - transform-origin: 0 100%; - transform: scale(0); - animation: message2 0.15s ease-out 0s forwards; + opacity: 0; animation-delay: 50ms; + animation: citationAnimation 0.15s ease-out 0s forwards; } -@keyframes message2 { +@keyframes citationAnimation { 0% { - max-height: 100%; + opacity: 0; } 80% { - transform: scale(1.1); + opacity: 0.5; } 100% { - transform: scale(1); - max-height: 100%; - overflow: visible; + opacity: 1; } }