Skip to content

Commit 10bd1c7

Browse files
authored
Merge branch 'main' into add_ec2_user_data_scripts
2 parents 6fc491e + 2d4d5eb commit 10bd1c7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1773
-1134
lines changed

AI/GenAI-ChatBot-application-sample/src/app/[locale]/ErrorBoundary.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client';
22

3-
import { Component, ErrorInfo, ReactNode } from "react";
3+
import React, { Component, ErrorInfo, ReactNode } from "react";
44

55
interface Props {
66
children?: ReactNode;

AI/GenAI-ChatBot-application-sample/src/app/[locale]/components/chatbot/chatbot.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const Chatbot = () => {
4242
const { getState } = useAppStore();
4343
const { isSuccess: isSuccessAuth } = useAppSelector(rootSelector.auth);
4444
const { messages: newMessages, chatId } = useAppSelector(rootSelector.chat);
45+
4546
const { id: knowledgebaseId } = useAppSelector(rootSelector.knowledgeBase);
4647

4748
const { data: knowledgebase, error } = useGetKnowledgebasesQuery({ knowledgebaseId, isSelfHandleErrors: true }, { skip: skip(getState(), !isSuccessAuth || !knowledgebaseId) });
@@ -338,6 +339,7 @@ const Chatbot = () => {
338339
<div className="chatList">
339340
{promptList.filter(message => message.chatId === chatId).map((prompt, index) => {
340341
return <Prompt id={generateUniqueId(index, prompt.user)} key={index} prompt={prompt}
342+
knowledgeBaseId={knowledgebaseId}
341343
className='prompt' chatAreaRef={chatAreaRef} />
342344
})}
343345
</div>

AI/GenAI-ChatBot-application-sample/src/app/[locale]/components/chatbot/prompt/prompt.scss

Lines changed: 67 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -88,46 +88,97 @@
8888
display: flex;
8989
flex-direction: row;
9090
align-items: center;
91+
gap: 16px;
92+
93+
.section {
94+
overflow-wrap: initial;
95+
&:not(:last-child) {
96+
padding-right: 16px;
97+
border-right: 1px solid var(--border);
98+
}
99+
}
100+
101+
.promptDateTime {
102+
color: var(--text-secondary);
103+
@include ellipsis(100%);
104+
}
105+
106+
.copyToClipboard {
107+
height: 16px;
108+
path {
109+
fill: var(--text-button-primary);
110+
}
111+
}
91112

92113
.copyPrompt {
93-
border-left: 1px solid var(--browser-bg-stroke);
94-
padding-left: 16px;
95-
margin-left: 16px;
114+
display: flex;
115+
flex-direction: row;
116+
.copyToClipboardContainer {
117+
.childContainer {
118+
&:hover {
119+
.copyToClipboard,
120+
.copyLabel {
121+
color: var(--text-button-primary-hover);
122+
}
123+
}
124+
.copyToClipboardText {
125+
@include ellipsis(100%);
126+
}
127+
}
128+
}
129+
}
96130

97-
&.copyToClipboardContainer {
98-
&:hover {
131+
.copyLabel {
132+
color: var(--text-button-primary);
133+
}
99134

100-
.copyToClipboard,
101-
.copyLabel {
102-
color: var(--text-button-primary-hover);
135+
.downloadComplexAnswerLayoutContainer {
136+
text-decoration: none;
137+
&.isDisabled {
138+
pointer-events: none;
103139

140+
.downloadComplexAnswerLayout {
141+
.downloadComplexAnswerIcon {
104142
path {
105-
fill: var(--text-button-primary-hover);
143+
fill: var(--text-secondary);
106144
}
107145
}
108-
}
109146

110-
.copyToClipboard {
147+
.downloadComplexAnswerLabel {
148+
@include ellipsis(100%);
149+
color: var(--text-secondary);
150+
}
151+
}
152+
}
153+
154+
.downloadComplexAnswerLayout {
155+
display: flex;
156+
flex-direction: row;
157+
align-items: center;
158+
gap: 8px;
159+
cursor: pointer;
160+
161+
.downloadComplexAnswerIcon {
111162
width: 16px;
112163
height: 16px;
113-
114164
path {
115165
fill: var(--text-button-primary);
116166
}
117167
}
168+
169+
.downloadComplexAnswerLabel{
170+
color: var(--text-button-primary);
171+
}
118172
}
119173
}
120-
121-
.copyLabel {
122-
color: var(--text-button-primary);
123-
}
124174
}
125175

126176
.citationsLayout {
127177
display: flex;
128178
flex-direction: column;
129179
gap: 8px;
130180
height: 100%;
181+
margin-top: 8px;
131182

132183
.sourcesLayout {
133184
display: flex;

AI/GenAI-ChatBot-application-sample/src/app/[locale]/components/chatbot/prompt/prompt.tsx

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { ReactElement, RefObject, useMemo, useState } from "react";
1+
import { ReactElement, RefObject, useEffect, useMemo, useRef, useState } from "react";
22
import './prompt.scss';
33
import UserIcon from '@/app/[locale]/svgs/chatbot/user.svg';
44
import BotIcon from "@/app/[locale]/svgs/chatbot/bot.svg";
55
import LocationIcon from "@/app/[locale]/svgs/location.svg";
66
import ArrowDown from "@/app/[locale]/svgs/arrowDown.svg";
7+
import DownloadIcon from "@/app/[locale]/svgs/download.svg";
78
import parse from 'html-react-parser';
89
import { formatDate } from "@/utils/formatterUtils";
910
import { FileData, MessageType } from "@/lib/api/api.types";
@@ -13,11 +14,13 @@ import { DsFlashingDotsLoader } from "../../dsComponents/dsFlashingDotsLoader/ds
1314
import { useOutsideClick } from "@/app/[locale]/hooks/useOutsideClick";
1415
import { _Classes } from "@/utils/cssHelper.util";
1516
import { DsPopover } from "../../dsComponents/dsPopover/dsPopover";
16-
import CopyToClipboard from "../../copyToClipboard/copyToClipboard";
17+
import DsCopyToClipboard from "../../copyToClipboard/copyToClipboard";
1718
import { DsCellProps } from "../../dsComponents/dsTable/dsCell/dsCell";
1819
import { DsColumn, DsRow, DsTable } from "../../dsComponents/dsTable/dsTable";
1920
import { useTranslation } from "react-i18next";
20-
21+
import { useCreatePreSignUrlMutation } from "@/lib/api/chatApi.slice";
22+
import { useDispatch } from "react-redux";
23+
import { addNotification, removeNotification } from "@/lib/slices/notifications.slice";
2124

2225
export type UserType = 'USER' | 'BOT';
2326

@@ -37,15 +40,28 @@ interface PromptProps {
3740
id: string,
3841
className?: string,
3942
prompt: PromptItem,
43+
knowledgeBaseId: string,
4044
chatAreaRef: RefObject<HTMLDivElement | null>
4145
}
4246

43-
const Prompt = ({ className, prompt, id, chatAreaRef }: PromptProps) => {
47+
const Prompt = ({ className, prompt, id, chatAreaRef, knowledgeBaseId }: PromptProps) => {
4448
const { t } = useTranslation();
45-
const { user, isWriting, message, date, filesData, type } = prompt;
49+
const { chatId, user, isWriting, message, date, filesData = [], type } = prompt;
50+
const dispetch = useDispatch();
51+
52+
const complexAnswerDownloadRef = useRef<HTMLAnchorElement>(null);
4653

4754
const [isExpandCitations, setIsExpandCitations] = useState<boolean>(false)
4855
const [expandCitationsId, setExpandCitationsId] = useState<number>()
56+
const [isDownloadStarted, setIsDownloadStarted] = useState<boolean>(false);
57+
58+
const [createPreSignUrl, { data: { url: preSignUrl } = {} }] = useCreatePreSignUrlMutation();
59+
60+
useEffect(() => {
61+
if (preSignUrl && complexAnswerDownloadRef?.current) {
62+
complexAnswerDownloadRef.current.click()
63+
}
64+
}, [preSignUrl]);
4965

5066
const clickOutsideRef = useOutsideClick(() => {
5167
setExpandCitationsId(undefined)
@@ -101,7 +117,7 @@ const Prompt = ({ className, prompt, id, chatAreaRef }: PromptProps) => {
101117
<div className="content">
102118
<div className="titleLayout">
103119
<DsTypography variant="Semibold_13" className="nameTitle">{name}</DsTypography>
104-
<CopyToClipboard
120+
<DsCopyToClipboard
105121
tooltipTitle="Response"
106122
value={`${name}\n\n${fileData.text}\n\nPath: ${path}`}
107123
className="citationCopyIcon" monitorPosition="off"
@@ -214,6 +230,32 @@ const Prompt = ({ className, prompt, id, chatAreaRef }: PromptProps) => {
214230
<DsTypography variant="Regular_14" className={`promptMessage ${isWriting && !!htmlString ? 'textWriting' : ''}`} >{generatePromptString()}</DsTypography>
215231
)
216232
}
233+
const downlowedFinished = () => {
234+
setIsDownloadStarted(false);
235+
}
236+
237+
const clickDownload = () => {
238+
dispetch(addNotification({
239+
id: 'downloadingComplexAnswer',
240+
type: 'info',
241+
children: t('genAI.chatBot.downloadStarted'),
242+
onClose: downlowedFinished
243+
}));
244+
setIsDownloadStarted(true);
245+
246+
setTimeout(() => {
247+
dispetch(removeNotification(
248+
'downloadingComplexAnswer'
249+
))
250+
setIsDownloadStarted(false);
251+
}, 8000); // delay to show the notification
252+
253+
return createPreSignUrl({
254+
knowledgeBaseId,
255+
chatId,
256+
questionDate: (date!),
257+
})
258+
}
217259

218260
return (
219261
<div className="baloonContainer">
@@ -224,15 +266,26 @@ const Prompt = ({ className, prompt, id, chatAreaRef }: PromptProps) => {
224266
</div>
225267
{isWriting && <DsFlashingDotsLoader className={`${isWriting && !!htmlString ? 'flashingDots' : ''}`} />}
226268
{(user === 'BOT' && !isWriting) && <div className="dateAndCopyLayout" id={id}>
227-
{!!date && <DsTypography variant="Regular_12" className="promptDateTime">{formatDate(date)}</DsTypography>}
228-
<CopyToClipboard
269+
{!!date && <DsTypography variant="Regular_12" className="promptDateTime section">{formatDate(date)}</DsTypography>}
270+
<DsCopyToClipboard
229271
tooltipTitle="Response"
230272
value={message ? message : ""}
231273
monitorPosition="off"
232274
offset={{ top: -80, left: 20 }}
233-
className="copyPrompt">
234-
<DsTypography variant="Semibold_14" className="copyLabel">{t('genAI.general.copy')}</DsTypography>
235-
</CopyToClipboard>
275+
className="copyPrompt section">
276+
<DsTypography variant="Semibold_13" className="copyLabel">{t('genAI.general.copy')}</DsTypography>
277+
</DsCopyToClipboard>
278+
{filesData && filesData.length > 0 && filesData[0]?.sqlQuery && filesData[0]?.bucket && <a href={preSignUrl}
279+
download
280+
rel="noreferrer"
281+
ref={complexAnswerDownloadRef}
282+
className={_Classes('downloadComplexAnswerLayoutContainer', { isDisabled: isDownloadStarted })}
283+
>
284+
<div className="downloadComplexAnswerLayout section" onClick={clickDownload}>
285+
<DownloadIcon className="downloadComplexAnswerIcon" />
286+
<DsTypography variant="Semibold_13" className="downloadComplexAnswerLabel">{t(`genAI.chatBot.downloadLabel`)}</DsTypography>
287+
</div>
288+
</a>}
236289
</div>}
237290
{(user === 'BOT' && !isWriting) && filesData && filesData.length > 0 && <div className="citationsLayout">
238291
<div
@@ -249,7 +302,7 @@ const Prompt = ({ className, prompt, id, chatAreaRef }: PromptProps) => {
249302
</div>
250303
</div>
251304
)
252-
}, [message, user, type, isWriting, id, date, t, filesData, isExpandCitations, clickOutsideRef, expandCitationsId, chatAreaRef]);
305+
}, [message, user, type, isWriting, id, date, t, filesData, isExpandCitations, clickOutsideRef, expandCitationsId, chatAreaRef, preSignUrl, isDownloadStarted]);
253306

254307
return (
255308
<div className={`promptItem fadeIn ${className || ''}`}>

AI/GenAI-ChatBot-application-sample/src/app/[locale]/components/copyToClipboard/copyToClipboard.scss

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,53 @@
1-
.copyToClipboard {
1+
.dsCopyToClipboard {
2+
&.isDisabled {
3+
pointer-events: none;
4+
5+
.copyToClipboard {
6+
path {
7+
fill: var(--icon-primary-disabled);
8+
}
9+
}
10+
}
211

312
.copyToClipboardContainer {
4-
display: flex;
5-
gap: 8px;
6-
align-items: center;
713
position: relative;
8-
cursor: pointer;
914

1015
.contentForCopy {
1116
position: absolute;
1217
top: 0;
1318
left: 0;
14-
width: 100%;
15-
height: 0;
19+
width: 1px;
20+
height: 1px;
1621
border: none;
1722
padding: 0;
1823
opacity: 0;
24+
z-index: 0;
1925
}
2026

21-
.copyToClipboard {
22-
width: 24px;
23-
height: 24px;
24-
color: var(--icon-secondary);
27+
.childContainer {
28+
display: flex;
29+
gap: 8px;
30+
align-items: center;
31+
cursor: pointer;
32+
33+
&:hover {
34+
.copyToClipboard {
35+
path {
36+
fill: var(--icon-secondary-hover);
37+
}
38+
}
39+
40+
.copyToClipboardText {
41+
color: var(--icon-secondary-hover);
42+
}
43+
}
44+
45+
.copyToClipboard {
46+
width: 24px;
47+
height: 24px;
48+
color: var(--icon-secondary);
49+
z-index: 1;
50+
}
2551
}
2652
}
2753

0 commit comments

Comments
 (0)