Skip to content

Commit fa68f3b

Browse files
Fix UI white space issues and chat section layout
- Fixed chat section white space on right side by updating chatRoom.module.scss - Made OptionsPanel responsive with proper width constraints - Fixed HTTP client response consumption error using response.clone() - Resolved TypeScript compilation errors for React 19 - Updated DocDialog component signature for proper JSX usage - Improved chat container layout and removed excessive padding - Enhanced error handling with proper translation support
1 parent 6f24121 commit fa68f3b

16 files changed

Lines changed: 18961 additions & 1584 deletions

File tree

App/frontend-app/package-lock.json

Lines changed: 17697 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

App/frontend-app/public/locales/en/translation.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
"Search Results": "Search Results",
2929
"selected-documents": "Selected Documents",
3030
"fetching-answer": "Fetching answer, please wait...",
31+
"error-response": "Sorry, I received an invalid response. Please try asking your question again.",
32+
"error-occurred": "Sorry, an error occurred while processing your request. Please try again later.",
3133
"test-markdown": "# Dog Breed Comparison: Fluffy Golden Dog vs. Beagle\n\n## Fluffy Golden Dog\n- **Appearance**: Small, light-colored with a fluffy golden coat. Notable features include large brown eyes and prominent ears, one perked and one flopped.\n- **Temperament**: Curious and attentive, suggesting a friendly and engaging personality. The dog's posture indicates comfort and familiarity with its environment.\n- **Collar**: Wears a blue and purple collar with a red identification tag, indicating it is a pet with a caring owner.\n- **Environment**: Typically found in cozy indoor settings, reflecting a strong bond with human companions.\n\n## Beagle\n- **Appearance**: Medium-sized dog with a short, smooth coat that can come in various colors, including tri-color (black, white, and brown). Beagles have long ears and a distinctively expressive face.\n- **Temperament**: Known for being friendly, curious, and energetic. Beagles are often social and enjoy being part of family activities.\n- **Collar**: Commonly wear collars for identification, but styles vary widely.\n- **Environment**: Adaptable to both indoor and outdoor settings, Beagles thrive in active households where they can explore and play.\n\n## Summary\nWhile the fluffy golden dog is characterized by its small size, fluffy coat, and cozy indoor demeanor, the Beagle is a medium-sized, energetic breed known for its short coat and love for outdoor activities. Both breeds exhibit friendly and curious temperaments, making them great companions, but they differ in size, coat type, and typical living environments.",
3234
"new-topic": "New Topic",
3335
"input-placeholder": "Ask a question or request (ctrl + enter to submit)"

App/frontend-app/src/api/chatService.ts

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,18 @@ import { httpClient } from "../utils/httpClient/httpClient";
1010

1111
export async function Completion(request: ChatRequest): Promise<ChatApiResponse> {
1212
try {
13+
// Get API endpoint with fallback
14+
const apiEndpoint = import.meta.env.VITE_API_ENDPOINT || window.location.origin;
15+
16+
if (!apiEndpoint) {
17+
throw new Error('API endpoint not configured. Please check your environment variables.');
18+
}
19+
20+
console.log('Making API request to:', `${apiEndpoint}/chat`);
21+
1322
// Assuming httpClient is similar to Axios, we pass the request body and expect a ChatApiResponse
1423
const response: ChatApiResponse = await httpClient.post(
15-
`${import.meta.env.VITE_API_ENDPOINT}/chat`,
24+
`${apiEndpoint}/chat`,
1625
request,
1726
{
1827
headers: {
@@ -25,13 +34,34 @@ export async function Completion(request: ChatRequest): Promise<ChatApiResponse>
2534
return response;
2635
} catch (error) {
2736
console.error('Error during API request:', error);
28-
throw new Error('Failed to fetch the API response.');
37+
throw new Error(`Failed to fetch the API response: ${error instanceof Error ? error.message : String(error)}`);
2938
}
3039
}
3140

3241

33-
export async function PostFeedback(request: FeedbackRequest){
34-
const response: boolean = await httpClient.post(`${window.ENV.API_URL}/api/Chat/Feedback`, request);
42+
export async function PostFeedback(request: FeedbackRequest): Promise<boolean> {
43+
try {
44+
// Get API endpoint with fallback
45+
const apiEndpoint = import.meta.env.VITE_API_ENDPOINT || window.location.origin;
46+
47+
if (!apiEndpoint) {
48+
throw new Error('API endpoint not configured. Please check your environment variables.');
49+
}
3550

36-
return response;
51+
console.log('Making feedback API request to:', `${apiEndpoint}/api/Chat/Feedback`);
52+
53+
const response: boolean = await httpClient.post(
54+
`${apiEndpoint}/api/Chat/Feedback`,
55+
request,
56+
{
57+
headers: {
58+
'Content-Type': 'application/json',
59+
},
60+
}
61+
);
62+
return response;
63+
} catch (error) {
64+
console.error('Error during feedback submission:', error);
65+
throw new Error(`Failed to submit feedback: ${error instanceof Error ? error.message : String(error)}`);
66+
}
3767
}

App/frontend-app/src/assets/icons/azureIcon.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react";
22

3-
export function AzureIcon({ className }: { className?: string }): JSX.Element {
3+
export function AzureIcon({ className }: { className?: string }): React.JSX.Element {
44
return (
55
<svg className={className} fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
66
<path

App/frontend-app/src/assets/icons/gitHubLogoIcon.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react";
22

3-
export function GitHubIcon({ className }: { className?: string }): JSX.Element {
3+
export function GitHubIcon({ className }: { className?: string }): React.JSX.Element {
44
return (
55
<svg className={className} fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
66
<path d="M12 .3a11.97 11.97 0 0 1 6.05 1.63c.88.53 1.69 1.16 2.42 1.88.74.72 1.37 1.53 1.89 2.42a12.08 12.08 0 0 1-.62 13.08c-.73 1-1.6 1.88-2.6 2.63a11.8 11.8 0 0 1-3.45 1.76h-.1a.6.6 0 0 1-.45-.16.59.59 0 0 1-.16-.43v-3.29c0-.4-.05-.8-.17-1.21-.11-.4-.33-.75-.63-1.02.9-.1 1.7-.29 2.38-.55a4.6 4.6 0 0 0 2.74-2.88 8.2 8.2 0 0 0 .35-2.49 4.85 4.85 0 0 0-1.23-3.22 3.37 3.37 0 0 0 .25-1.38 4.37 4.37 0 0 0-.37-1.8.34.34 0 0 0-.12-.02h-.13c-.25 0-.51.04-.79.12-.27.08-.54.18-.8.3A10.73 10.73 0 0 0 15 6.5a11.07 11.07 0 0 0-6 0 12.97 12.97 0 0 0-1.44-.82 7.35 7.35 0 0 0-.82-.3 2.7 2.7 0 0 0-.79-.13h-.13c-.04 0-.09 0-.12.02a5.94 5.94 0 0 0-.37 1.8 4.27 4.27 0 0 0 .25 1.38 4.6 4.6 0 0 0-1.23 3.22c0 .95.11 1.78.34 2.47a4.56 4.56 0 0 0 2.74 2.9c.68.28 1.47.47 2.38.56a2 2 0 0 0-.52.73c-.11.28-.2.57-.24.88a3.22 3.22 0 0 1-1.37.31c-.5 0-.92-.11-1.25-.35a3.4 3.4 0 0 1-.88-.96 3.38 3.38 0 0 0-.77-.84 2.13 2.13 0 0 0-.5-.28c-.18-.07-.37-.11-.57-.12h-.14a.44.44 0 0 0-.17.03l-.17.07c-.05.03-.07.07-.07.12 0 .1.06.18.17.27l.27.21.03.03a6.17 6.17 0 0 1 .8.76c.1.14.2.29.27.44l.27.55c.26.61.64 1.05 1.11 1.33a3.5 3.5 0 0 0 1.72.42 5.32 5.32 0 0 0 1.22-.14v2.04a.6.6 0 0 1-.16.44c-.11.11-.26.17-.46.17h-.1a11.55 11.55 0 0 1-6.05-4.38A12.17 12.17 0 0 1 .43 9.1c.28-1.03.69-1.98 1.22-2.86.53-.89 1.16-1.7 1.88-2.43.71-.73 1.52-1.36 2.42-1.89A12.08 12.08 0 0 1 12 .3z" />

App/frontend-app/src/assets/icons/mailIcon.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react";
22

3-
export function MailIcon({ className }: { className?: string }): JSX.Element {
3+
export function MailIcon({ className }: { className?: string }): React.JSX.Element {
44
return (
55
<svg className={className} fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
66
<path d="M5.25 4h13.5a3.25 3.25 0 0 1 3.245 3.066L22 7.25v9.5a3.25 3.25 0 0 1-3.066 3.245L18.75 20H5.25a3.25 3.25 0 0 1-3.245-3.066L2 16.75v-9.5a3.25 3.25 0 0 1 3.066-3.245L5.25 4h13.5-13.5ZM20.5 9.373l-8.15 4.29a.75.75 0 0 1-.603.043l-.096-.042L3.5 9.374v7.376a1.75 1.75 0 0 0 1.606 1.744l.144.006h13.5a1.75 1.75 0 0 0 1.744-1.607l.006-.143V9.373ZM18.75 5.5H5.25a1.75 1.75 0 0 0-1.744 1.606L3.5 7.25v.429l8.5 4.473 8.5-4.474V7.25a1.75 1.75 0 0 0-1.607-1.744L18.75 5.5Z" />

App/frontend-app/src/components/chat/OptionsPanel.css

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
.options-panel-container {
22
padding-bottom: 20px; /* Add more padding below the toggle */
33
margin-top: 2px;
4+
width: 100%;
5+
display: flex;
6+
flex-direction: column;
7+
align-items: center;
48
}
59

610
.options-panel-container.sticky {
@@ -25,7 +29,8 @@
2529
position: relative;
2630
background-color: #ffffff;
2731
border-radius: 9999px;
28-
width: 300px;
32+
width: 100%;
33+
max-width: 320px;
2934
height: 40px;
3035
display: flex;
3136
align-items: center;

App/frontend-app/src/components/chat/chatRoom.module.scss

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@
2121
}
2222
}
2323

24+
/* Ensure no white space in chat area */
25+
.no-white-space {
26+
margin: 0 !important;
27+
padding: 0 !important;
28+
width: 100% !important;
29+
box-sizing: border-box !important;
30+
}
31+
2432
table {
2533
border-collapse: collapse;
2634
width: 100%;
@@ -40,19 +48,33 @@ table {
4048

4149
.grey-background {
4250
background-color: #f0f0f03d;
51+
width: 100%;
52+
overflow-x: hidden; /* Prevent horizontal overflow */
53+
margin: 0;
54+
padding: 0;
55+
box-sizing: border-box;
4356
}
4457

4558

4659
.attachment-tag-container {
4760
display: flex;
4861
flex-wrap: wrap;
62+
width: 100%;
4963
}
5064

5165
.chat-container {
5266
max-block-size: 75vh;
67+
width: 100%;
68+
overflow-x: hidden; /* Prevent horizontal overflow */
69+
margin: 0;
70+
padding: 0;
5371
}
5472

5573
.chatMessagesContainer, .questionContainer {
56-
padding-right: 1rem;
57-
padding-left: 1rem;
74+
padding-right: 0.25rem;
75+
padding-left: 0.25rem;
76+
width: 100%;
77+
box-sizing: border-box; /* Include padding in width calculation */
78+
max-width: 100%; /* Ensure it doesn't exceed container width */
79+
margin: 0;
5880
}

App/frontend-app/src/components/chat/chatRoom.tsx

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -205,53 +205,58 @@ export function ChatRoom({ searchResultDocuments, selectedDocuments, chatWithDoc
205205
}
206206

207207
try {
208-
209-
210-
211208
const request: ChatRequest = {
212209
Question: question,
213210
chatSessionId: currentSessionId,
214211
DocumentIds: button === "All Documents" ? [] : formattedDocuments
215-
// cha: history,
216-
// options: {
217-
// model: model,
218-
// source: source,
219-
// temperature: temperature,
220-
// maxTokens: maxTokens,
221-
// },
222-
// filterByDocumentIds: filterByDocumentIds,
223212
};
224213

225-
226214
const response: ChatApiResponse = await Completion(request);
227215

228-
229-
230216
setIsLoading(false);
231217

232218
const answerTimestamp = new Date();
233219

234-
try {
235-
if (response && response.answer) {
236-
237-
const formattedAnswer = removeNewlines(response.answer)
238-
const chatResp = await marked.parse(formattedAnswer) // Convert to HTML if Markdown detected
220+
if (response && response.answer) {
221+
const formattedAnswer = removeNewlines(response.answer);
222+
const chatResp = await marked.parse(formattedAnswer);
239223

240-
241-
242-
243-
// Update the conversation with the formatted answer
244-
setConversationAnswers((prevAnswers) => {
245-
const newAnswers = [...prevAnswers];
246-
newAnswers[newAnswers.length - 1] = [question, { ...response, answer: chatResp }, userTimestamp, answerTimestamp];
247-
return newAnswers;
248-
});
249-
}
250-
} catch (error) {
251-
console.error("Error parsing response body:", error);
224+
// Update the conversation with the formatted answer
225+
setConversationAnswers((prevAnswers) => {
226+
const newAnswers = [...prevAnswers];
227+
newAnswers[newAnswers.length - 1] = [question, { ...response, answer: chatResp }, userTimestamp, answerTimestamp];
228+
return newAnswers;
229+
});
230+
} else {
231+
console.error("Invalid response received:", response);
232+
// Update with error message
233+
setConversationAnswers((prevAnswers) => {
234+
const newAnswers = [...prevAnswers];
235+
newAnswers[newAnswers.length - 1] = [question, {
236+
answer: t('components.chat.error-response'),
237+
suggestingQuestions: [],
238+
documentIds: [],
239+
keywords: []
240+
}, userTimestamp, answerTimestamp];
241+
return newAnswers;
242+
});
252243
}
253244
} catch (error) {
254245
console.error("Error in makeApiRequest:", error);
246+
setIsLoading(false);
247+
248+
// Update conversation with error message
249+
const answerTimestamp = new Date();
250+
setConversationAnswers((prevAnswers) => {
251+
const newAnswers = [...prevAnswers];
252+
newAnswers[newAnswers.length - 1] = [question, {
253+
answer: t('components.chat.error-occurred'),
254+
suggestingQuestions: [],
255+
documentIds: [],
256+
keywords: []
257+
}, userTimestamp, answerTimestamp];
258+
return newAnswers;
259+
});
255260
} finally {
256261
setIsLoading(false);
257262
setTimeout(() => {
@@ -400,7 +405,7 @@ export function ChatRoom({ searchResultDocuments, selectedDocuments, chatWithDoc
400405
}, []);
401406

402407
return (
403-
<div className="mx-2 flex w-full flex-1 flex-col items-center grey-background">
408+
<div className="flex w-full flex-1 flex-col items-stretch grey-background">
404409
{isDialogOpen && (
405410
<DocDialog
406411
metadata={dialogMetadata as Document}
@@ -411,8 +416,7 @@ export function ChatRoom({ searchResultDocuments, selectedDocuments, chatWithDoc
411416
<div ref={chatContainerRef} className={`no-scrollbar flex w-full flex-1 flex-col overflow-auto ${styles["chat-container"]}`}>
412417
{!disableOptionsPanel && (
413418
<OptionsPanel
414-
// className="px-10 mx-auto my-10 flex flex-col items-center justify-center rounded-xl bg-neutral-500 bg-opacity-10 shadow-md outline outline-1 outline-transparent"
415-
className={`px-10 mx-auto my-10 flex flex-col items-center justify-center rounded-xl bg-neutral-500 bg-opacity-10 shadow-md outline outline-1 outline-transparent`}
419+
className={`px-4 mx-0 my-10 flex flex-col items-center justify-center rounded-xl bg-neutral-500 bg-opacity-10 shadow-md outline outline-1 outline-transparent w-full`}
416420
onModelChange={handleModelChange}
417421
onSourceChange={handleSourceChange}
418422
disabled={disableSources}
@@ -421,7 +425,7 @@ export function ChatRoom({ searchResultDocuments, selectedDocuments, chatWithDoc
421425
/>
422426
)}
423427
<div ref={optionsBottom}></div>
424-
<CopilotProvider className={styles.chatMessagesContainer}>
428+
<CopilotProvider className={`${styles.chatMessagesContainer} w-full`}>
425429
<CopilotChat>
426430
{conversationAnswers.map(([prompt, response], index) => (
427431
<Fragment key={index}>
@@ -564,7 +568,7 @@ export function ChatRoom({ searchResultDocuments, selectedDocuments, chatWithDoc
564568
</CopilotProvider>
565569
</div>
566570

567-
<div className={`${styles.questionContainer} mb-6 mt-6 flex w-full justify-center`}>
571+
<div className={`${styles.questionContainer} mb-6 mt-6 flex w-full justify-center px-2`}>
568572
<Button
569573
className={styles["new-topic"]}
570574
shape="circular"
@@ -587,7 +591,7 @@ export function ChatRoom({ searchResultDocuments, selectedDocuments, chatWithDoc
587591
key={textareaKey}
588592
ref={inputRef}
589593
value={textAreaValue}
590-
className="!ml-4 max-h-48 w-full !max-w-none"
594+
className="!ml-2 max-h-48 w-full !max-w-none"
591595
onChange={(_ev, newValue) => setTextAreaValue(newValue.value)}
592596
showCount
593597
aria-label="Chat input"

App/frontend-app/src/components/documentViewer/documentViewer.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ interface Cell {
6666
}
6767

6868
export function DocDialog(
69-
{ metadata, isOpen, allChunkTexts, clearChatFlag, onClose }: DocDialogProps,
70-
props: Partial<TabListProps>
69+
{ metadata, isOpen, allChunkTexts, clearChatFlag, onClose, ...props }: DocDialogProps & Partial<TabListProps>
7170
) {
7271
const {t} = useTranslation();
7372
const styles = useStyles();

0 commit comments

Comments
 (0)