Skip to content

Commit 6628e40

Browse files
authored
feat: Chat UI updates (#433)
1 parent db8c1d2 commit 6628e40

File tree

4 files changed

+94
-43
lines changed

4 files changed

+94
-43
lines changed

plugins/genai/frontend/src/components/AgentPage/AgentPage.tsx

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import React from 'react';
1818
import { ChatHistoryComponent } from '../ChatHistoryComponent';
1919
import { ChatInputComponent } from '../ChatInputComponent';
2020
import { useParams } from 'react-router-dom';
21-
import { makeStyles } from '@material-ui/core';
21+
import { LinearProgress, makeStyles } from '@material-ui/core';
2222
import { useChatSession } from '../../hooks';
2323

2424
const useStyles = makeStyles({
@@ -34,6 +34,10 @@ const useStyles = makeStyles({
3434
maxHeight: '100%',
3535
marginBottom: '1rem',
3636
},
37+
38+
chatInputContainer: {
39+
margin: '1rem',
40+
},
3741
});
3842

3943
export const AgentPage = ({ title = 'Chat Assistant' }: { title?: string }) => {
@@ -50,28 +54,39 @@ export const AgentPage = ({ title = 'Chat Assistant' }: { title?: string }) => {
5054
throw new Error('agent name is not defined');
5155
}
5256

53-
const { messages, isLoading, onUserMessage, onClear } = useChatSession({
54-
agentName,
55-
});
57+
const { messages, isInitializing, isLoading, onUserMessage, onClear } =
58+
useChatSession({
59+
agentName,
60+
});
61+
62+
if (isInitializing) {
63+
return (
64+
<Content>
65+
<LinearProgress />
66+
</Content>
67+
);
68+
}
5669

5770
return (
5871
<Page themeId="tool">
5972
<Header title={title} />
60-
<Content>
73+
<Content noPadding>
6174
<div className={classes.flex}>
6275
<ChatHistoryComponent
6376
messages={messages}
6477
className={classes.grow}
6578
isStreaming={isLoading}
6679
showInformation={showInformation}
6780
/>
68-
<InfoCard>
69-
<ChatInputComponent
70-
onMessage={onUserMessage}
71-
disabled={isLoading}
72-
onClear={onClear}
73-
/>
74-
</InfoCard>
81+
<div className={classes.chatInputContainer}>
82+
<InfoCard>
83+
<ChatInputComponent
84+
onMessage={onUserMessage}
85+
disabled={isLoading}
86+
onClear={onClear}
87+
/>
88+
</InfoCard>
89+
</div>
7590
</div>
7691
</Content>
7792
</Page>

plugins/genai/frontend/src/components/ChatHistoryComponent/ChatHistoryComponent.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const useStyles = makeStyles(theme => ({
2727
container: {
2828
display: 'flex',
2929
flexDirection: 'column',
30+
margin: '0',
3031
},
3132

3233
markdownContainer: {
@@ -217,7 +218,9 @@ export const ChatHistoryComponent = ({
217218
<div className={`${classes.ChatItemChatText}`}>
218219
<MarkdownContent
219220
content={
220-
message.payload.length === 0 ? '...' : message.payload
221+
message.payload.length === 0
222+
? 'Working...'
223+
: message.payload
221224
}
222225
dialect="gfm"
223226
/>

plugins/genai/frontend/src/components/ChatInputComponent/ChatInputComponent.tsx

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
import React, { useEffect, useRef, useState } from 'react';
1515
import { Button, makeStyles, TextField } from '@material-ui/core';
16+
import SendIcon from '@material-ui/icons/Send';
17+
import DeleteIcon from '@material-ui/icons/Delete';
1618

1719
const useStyles = makeStyles({
1820
ChatInputLayout: {
@@ -25,14 +27,20 @@ const useStyles = makeStyles({
2527
},
2628

2729
ChatInputButtons: {
28-
marginLeft: '2rem',
30+
marginLeft: '0.5rem',
2931
display: 'flex',
3032
alignItems: 'center',
3133
},
34+
35+
ChatInputButton: {
36+
marginLeft: '0.5rem',
37+
minWidth: '36px',
38+
padding: '10px',
39+
},
3240
});
3341

3442
interface ChatInputComponentProps {
35-
onMessage?: (message: string) => void;
43+
onMessage: (message: string) => void;
3644
disabled?: boolean;
3745
onClear?: () => void;
3846
}
@@ -54,43 +62,63 @@ export const ChatInputComponent = ({
5462
}
5563
}, [disabled]);
5664

65+
const processMessage = () => {
66+
onMessage(message);
67+
setMessage('');
68+
};
69+
5770
const checkKeyPress = (evt: React.KeyboardEvent<HTMLInputElement>) => {
5871
if (evt.code === 'Enter') {
5972
if (!evt.shiftKey) {
60-
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
61-
onMessage && onMessage(message);
62-
setMessage('');
73+
processMessage();
6374
evt.preventDefault();
6475
}
6576
}
6677
};
6778

6879
return (
69-
<div className={classes.ChatInputLayout}>
70-
<div className={classes.ChatInputContainer}>
71-
<TextField
72-
id="outlined-multiline-flexible"
73-
label="Type a message"
74-
helperText="Hold <shift> when pressing <enter> for multiline"
75-
multiline
76-
variant="standard"
77-
value={message}
78-
style={{
79-
marginRight: '1rem',
80-
}}
81-
maxRows={8}
82-
minRows={1}
83-
onKeyDown={checkKeyPress}
84-
onChange={evt => setMessage(evt.target.value)}
85-
fullWidth
86-
disabled={disabled}
87-
ref={inputRef}
88-
/>
89-
</div>
90-
<div className={classes.ChatInputButtons}>
91-
<Button variant="outlined" onClick={onClear} disabled={disabled}>
92-
Clear Chat
93-
</Button>
80+
<div>
81+
<div className={classes.ChatInputLayout}>
82+
<div className={classes.ChatInputContainer}>
83+
<TextField
84+
id="outlined-multiline-flexible"
85+
label="Type a message"
86+
multiline
87+
variant="outlined"
88+
value={message}
89+
style={{
90+
marginRight: '1rem',
91+
}}
92+
maxRows={8}
93+
minRows={1}
94+
onKeyDown={checkKeyPress}
95+
onChange={evt => setMessage(evt.target.value)}
96+
fullWidth
97+
disabled={disabled}
98+
ref={inputRef}
99+
/>
100+
</div>
101+
<div className={classes.ChatInputButtons}>
102+
<Button
103+
title="Send"
104+
onClick={processMessage}
105+
disabled={disabled}
106+
variant="contained"
107+
color="primary"
108+
className={classes.ChatInputButton}
109+
>
110+
<SendIcon />
111+
</Button>
112+
<Button
113+
title="Clear"
114+
onClick={onClear}
115+
disabled={disabled}
116+
variant="text"
117+
className={classes.ChatInputButton}
118+
>
119+
<DeleteIcon />
120+
</Button>
121+
</div>
94122
</div>
95123
</div>
96124
);

plugins/genai/frontend/src/hooks/useChatSession.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ interface UseChatSessionProps {
2424
interface UseChatSessionResult {
2525
messages: ChatMessage[];
2626
isLoading: boolean;
27+
isInitializing: boolean;
2728
onUserMessage: (userMessage: string) => Promise<void>;
2829
onClear: () => void;
2930
}
@@ -34,6 +35,7 @@ export const useChatSession = ({
3435
const agentApi = useApi(agentApiRef);
3536
const [messages, setMessages] = useState<ChatMessage[]>([]);
3637
const [isLoading, setIsLoading] = useState(false);
38+
const [isInitializing, setIsInitializing] = useState(false);
3739

3840
const [chatManager] = useState(
3941
() =>
@@ -45,8 +47,10 @@ export const useChatSession = ({
4547
);
4648

4749
useEffect(() => {
50+
setIsInitializing(true);
4851
chatManager.loadFromStorage();
4952
setMessages(chatManager.getMessages());
53+
setIsInitializing(false);
5054
}, [chatManager]);
5155

5256
const onUserMessage = useCallback(
@@ -69,6 +73,7 @@ export const useChatSession = ({
6973
return {
7074
messages,
7175
isLoading,
76+
isInitializing,
7277
onUserMessage,
7378
onClear,
7479
};

0 commit comments

Comments
 (0)