Skip to content

Commit d7ce6dc

Browse files
more UI fixes including buffer messages ui fix
1 parent c702314 commit d7ce6dc

File tree

12 files changed

+176
-171
lines changed

12 files changed

+176
-171
lines changed

src/frontend/src/components/content/HomeInput.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ const HomeInput: React.FC<HomeInputProps> = ({
237237
</div>
238238

239239
<div className="home-input-quick-tasks">
240+
<div>
240241
{tasksToDisplay.map((task) => (
241242
<PromptCard
242243
key={task.id}
@@ -245,9 +246,11 @@ const HomeInput: React.FC<HomeInputProps> = ({
245246
description={task.description}
246247
onClick={() => handleQuickTaskClick(task)}
247248
disabled={submitting}
249+
248250
/>
249251
))}
250252
</div>
253+
</div>
251254
</>
252255
)}
253256
{tasksToDisplay.length === 0 && selectedTeam && (

src/frontend/src/components/content/PlanChat.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ const PlanChat: React.FC<SimplifiedPlanChatProps> = ({
9292
display: 'flex',
9393
flexDirection: 'column',
9494
height: '100vh',
95-
backgroundColor: 'var(--colorNeutralBackground1)'
95+
9696
}}>
9797
{/* Messages Container */}
9898
<InlineToaster />
@@ -132,6 +132,7 @@ const PlanChat: React.FC<SimplifiedPlanChatProps> = ({
132132
OnChatSubmit={OnChatSubmit}
133133
waitingForPlan={waitingForPlan}
134134
loading={false} />
135+
135136
</div>
136137
);
137138
};

src/frontend/src/components/content/PlanChatBody.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,17 @@ const PlanChatBody: React.FC<SimplifiedPlanChatProps> = ({
2323
return (
2424
<div
2525
style={{
26-
position: 'sticky',
26+
// position: 'sticky',
2727
bottom: 0,
28-
backgroundColor: 'var(--colorNeutralBackground1)',
28+
// backgroundColor: 'var(--colorNeutralBackground1)',
2929
// borderTop: '1px solid var(--colorNeutralStroke2)',
3030
padding: '16px 24px',
3131
maxWidth: '800px',
3232
margin: '0 auto',
33+
marginBottom: '40px',
3334
width: '100%',
3435
boxSizing: 'border-box',
35-
zIndex: 10,
36+
zIndex: 10
3637
}}
3738
>
3839
<ChatInput
@@ -49,7 +50,7 @@ const PlanChatBody: React.FC<SimplifiedPlanChatProps> = ({
4950
fontSize: '16px',
5051
borderRadius: '8px',
5152
// border: '1px solid var(--colorNeutralStroke1)',
52-
backgroundColor: 'var(--colorNeutralBackground1)',
53+
// backgroundColor: 'var(--colorNeutralBackground1)',
5354
width: '100%',
5455
boxSizing: 'border-box',
5556
}}

src/frontend/src/components/content/PlanPanelRight.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ const PlanPanelRight: React.FC<PlanDetailsProps> = ({
187187
fontWeight: 600,
188188
color: 'var(--colorNeutralForeground1)'
189189
}}>
190-
Agents
190+
Agent Team
191191
</Body1>
192192

193193
{agents.length === 0 ? (
@@ -250,7 +250,8 @@ const PlanPanelRight: React.FC<PlanDetailsProps> = ({
250250
display: 'flex',
251251
flexDirection: 'column',
252252
overflow: 'hidden',
253-
backgroundColor: 'var(--colorNeutralBackground1)'
253+
borderLeft: '1px solid var(--colorNeutralStroke1)',
254+
// backgroundColor: 'var(--colorNeutralBackground1)'
254255
}}>
255256
{/* Plan section on top */}
256257
{renderPlanSection()}

src/frontend/src/components/content/streaming/StreamingAgentMessage.tsx

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,6 @@ const useStyles = makeStyles({
5959
color: 'var(--colorNeutralForeground1)',
6060
lineHeight: '20px'
6161
},
62-
botBadge: {
63-
fontSize: '11px',
64-
fontWeight: '600',
65-
textTransform: 'uppercase',
66-
letterSpacing: '0.5px',
67-
backgroundColor: 'var(--colorNeutralBackground3)',
68-
color: 'var(--colorNeutralForeground1)',
69-
border: '1px solid var(--colorNeutralStroke2)',
70-
padding: '2px 8px',
71-
borderRadius: '4px'
72-
},
7362
messageBubble: {
7463
padding: '12px 16px',
7564
borderRadius: '8px',
@@ -200,10 +189,7 @@ const renderAgentMessages = (agentMessages: AgentMessageData[]) => {
200189
{TaskService.cleanTextToSpaces(msg.agent)}
201190
</Body1>
202191
<Tag
203-
size="extra-small"
204-
shape="rounded"
205-
appearance="filled"
206-
className={styles.botBadge}
192+
appearance="brand"
207193
>
208194
AI Agent
209195
</Tag>

src/frontend/src/components/content/streaming/StreamingBufferMessage.tsx

Lines changed: 129 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from 'react';
1+
import React, { useState, useEffect, useRef } from 'react';
22
import {
33
Button,
44
} from '@fluentui/react-components';
@@ -7,15 +7,36 @@ import ReactMarkdown from "react-markdown";
77
import remarkGfm from "remark-gfm";
88
import rehypePrism from "rehype-prism";
99

10-
const renderBufferMessage = (streamingMessageBuffer: string) => {
10+
interface StreamingBufferMessageProps {
11+
streamingMessageBuffer: string;
12+
isStreaming?: boolean;
13+
}
14+
15+
const renderBufferMessage = (streamingMessageBuffer: string, isStreaming: boolean = false) => {
1116
const [isExpanded, setIsExpanded] = useState<boolean>(false);
17+
const [shouldFade, setShouldFade] = useState<boolean>(false);
18+
const contentRef = useRef<HTMLDivElement>(null);
19+
const prevBufferLength = useRef<number>(0);
1220

13-
if (!streamingMessageBuffer || streamingMessageBuffer.trim() === "") return null;
21+
// Trigger fade effect when new content is being streamed
22+
useEffect(() => {
23+
if (isStreaming && streamingMessageBuffer.length > prevBufferLength.current) {
24+
setShouldFade(true);
25+
const timer = setTimeout(() => setShouldFade(false), 300);
26+
prevBufferLength.current = streamingMessageBuffer.length;
27+
return () => clearTimeout(timer);
28+
}
29+
prevBufferLength.current = streamingMessageBuffer.length;
30+
}, [streamingMessageBuffer, isStreaming]);
1431

15-
const start = Math.max(0, streamingMessageBuffer.length - 500);
16-
const previewText = start === 0
17-
? streamingMessageBuffer
18-
: "..." + streamingMessageBuffer.substring(start);
32+
// Auto-scroll to bottom when streaming
33+
useEffect(() => {
34+
if (isStreaming && !isExpanded && contentRef.current) {
35+
contentRef.current.scrollTop = contentRef.current.scrollHeight;
36+
}
37+
}, [streamingMessageBuffer, isStreaming, isExpanded]);
38+
39+
if (!streamingMessageBuffer || streamingMessageBuffer.trim() === "") return null;
1940

2041
return (
2142
<div style={{
@@ -29,14 +50,20 @@ const renderBufferMessage = (streamingMessageBuffer: string) => {
2950
borderRadius: '8px',
3051
padding: '16px',
3152
fontSize: '14px',
32-
lineHeight: '1.5'
53+
lineHeight: '1.5',
54+
height: isExpanded ? 'auto' : '256px', // Auto height when expanded
55+
display: 'flex',
56+
flexDirection: 'column',
57+
position: 'relative',
58+
overflow: isExpanded ? 'visible' : 'hidden' // Allow overflow when expanded
3359
}}>
3460
{/* Header */}
3561
<div style={{
3662
display: 'flex',
3763
justifyContent: 'space-between',
3864
alignItems: 'center',
39-
marginBottom: isExpanded ? '16px' : '8px'
65+
marginBottom: isExpanded ? '16px' : '16px',
66+
flexShrink: 0
4067
}}>
4168
<div style={{
4269
display: 'flex',
@@ -72,57 +99,93 @@ const renderBufferMessage = (streamingMessageBuffer: string) => {
7299
fontSize: '14px'
73100
}}
74101
>
75-
Details
102+
{isExpanded ? 'Hide' : 'Details'}
76103
</Button>
77104
</div>
78105

79-
{/* Preview content when collapsed */}
106+
{/* Content area - collapsed state */}
80107
{!isExpanded && (
81-
<div style={{
82-
display: 'flex',
83-
alignItems: 'flex-start',
84-
gap: '8px',
85-
marginLeft: '32px'
86-
}}>
87-
<ArrowTurnDownRightRegular style={{
88-
color: 'var(--colorNeutralForeground3)',
89-
fontSize: '14px',
90-
marginTop: '2px',
91-
flexShrink: 0
108+
<div
109+
ref={contentRef}
110+
style={{
111+
flex: 1,
112+
position: 'relative',
113+
overflowY: 'hidden',
114+
overflowX: 'hidden',
115+
paddingLeft: '32px',
116+
transition: 'opacity 0.3s ease-in-out',
117+
opacity: shouldFade ? 0.6 : 1
118+
}}
119+
>
120+
{/* Top fade overlay for collapsed state */}
121+
<div style={{
122+
position: 'absolute',
123+
top: 0,
124+
left: 0,
125+
right: 0,
126+
height: '40px',
127+
background: 'linear-gradient(to bottom, var(--colorNeutralBackground2), transparent)',
128+
pointerEvents: 'none',
129+
zIndex: 1
92130
}} />
131+
93132
<div style={{
94-
color: 'var(--colorNeutralForeground2)',
95-
fontSize: '14px',
96-
lineHeight: '1.4'
133+
display: 'flex',
134+
alignItems: 'flex-end',
135+
gap: '8px',
136+
height: '100%'
97137
}}>
98-
<ReactMarkdown
99-
remarkPlugins={[remarkGfm]}
100-
rehypePlugins={[rehypePrism]}
101-
components={{
102-
a: ({ node, ...props }) => (
103-
<a
104-
{...props}
105-
style={{
106-
color: 'var(--colorNeutralBrandForeground1)',
107-
textDecoration: 'none'
108-
}}
109-
onMouseEnter={(e) => {
110-
e.currentTarget.style.textDecoration = 'underline';
111-
}}
112-
onMouseLeave={(e) => {
113-
e.currentTarget.style.textDecoration = 'none';
114-
}}
115-
/>
116-
)
117-
}}
118-
>
119-
{previewText}
120-
</ReactMarkdown>
138+
<ArrowTurnDownRightRegular style={{
139+
color: 'var(--colorNeutralForeground3)',
140+
fontSize: '14px',
141+
marginBottom: '2px',
142+
flexShrink: 0
143+
}} />
144+
<div style={{
145+
color: 'var(--colorNeutralForeground2)',
146+
fontSize: '14px',
147+
lineHeight: '1.4',
148+
height: '100%',
149+
overflow: 'hidden',
150+
wordWrap: 'break-word',
151+
display: 'flex',
152+
flexDirection: 'column',
153+
justifyContent: 'flex-end',
154+
maskImage: 'linear-gradient(to bottom, transparent 0%, black 30%, black 100%)',
155+
WebkitMaskImage: 'linear-gradient(to bottom, transparent 0%, black 30%, black 100%)'
156+
}}>
157+
<ReactMarkdown
158+
remarkPlugins={[remarkGfm]}
159+
rehypePlugins={[rehypePrism]}
160+
components={{
161+
a: ({ node, ...props }) => (
162+
<a
163+
{...props}
164+
style={{
165+
color: 'var(--colorNeutralBrandForeground1)',
166+
textDecoration: 'none'
167+
}}
168+
onMouseEnter={(e) => {
169+
e.currentTarget.style.textDecoration = 'underline';
170+
}}
171+
onMouseLeave={(e) => {
172+
e.currentTarget.style.textDecoration = 'none';
173+
}}
174+
/>
175+
),
176+
p: ({ node, ...props }) => (
177+
<p {...props} style={{ margin: '0 0 8px 0' }} />
178+
)
179+
}}
180+
>
181+
{streamingMessageBuffer}
182+
</ReactMarkdown>
183+
</div>
121184
</div>
122185
</div>
123186
)}
124187

125-
{/* Full content when expanded */}
188+
{/* Content area - expanded state (original behavior) */}
126189
{isExpanded && (
127190
<div style={{
128191
padding: '12px',
@@ -131,6 +194,23 @@ const renderBufferMessage = (streamingMessageBuffer: string) => {
131194
<ReactMarkdown
132195
remarkPlugins={[remarkGfm]}
133196
rehypePlugins={[rehypePrism]}
197+
components={{
198+
a: ({ node, ...props }) => (
199+
<a
200+
{...props}
201+
style={{
202+
color: 'var(--colorNeutralBrandForeground1)',
203+
textDecoration: 'none'
204+
}}
205+
onMouseEnter={(e) => {
206+
e.currentTarget.style.textDecoration = 'underline';
207+
}}
208+
onMouseLeave={(e) => {
209+
e.currentTarget.style.textDecoration = 'none';
210+
}}
211+
/>
212+
)
213+
}}
134214
>
135215
{streamingMessageBuffer}
136216
</ReactMarkdown>

0 commit comments

Comments
 (0)