1- import { ReactElement , RefObject , useMemo , useState } from "react" ;
1+ import { ReactElement , RefObject , useEffect , useMemo , useRef , useState } from "react" ;
22import './prompt.scss' ;
33import UserIcon from '@/app/[locale]/svgs/chatbot/user.svg' ;
44import BotIcon from "@/app/[locale]/svgs/chatbot/bot.svg" ;
55import LocationIcon from "@/app/[locale]/svgs/location.svg" ;
66import ArrowDown from "@/app/[locale]/svgs/arrowDown.svg" ;
7+ import DownloadIcon from "@/app/[locale]/svgs/download.svg" ;
78import parse from 'html-react-parser' ;
89import { formatDate } from "@/utils/formatterUtils" ;
910import { FileData , MessageType } from "@/lib/api/api.types" ;
@@ -13,11 +14,13 @@ import { DsFlashingDotsLoader } from "../../dsComponents/dsFlashingDotsLoader/ds
1314import { useOutsideClick } from "@/app/[locale]/hooks/useOutsideClick" ;
1415import { _Classes } from "@/utils/cssHelper.util" ;
1516import { DsPopover } from "../../dsComponents/dsPopover/dsPopover" ;
16- import CopyToClipboard from "../../copyToClipboard/copyToClipboard" ;
17+ import DsCopyToClipboard from "../../copyToClipboard/copyToClipboard" ;
1718import { DsCellProps } from "../../dsComponents/dsTable/dsCell/dsCell" ;
1819import { DsColumn , DsRow , DsTable } from "../../dsComponents/dsTable/dsTable" ;
1920import { 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
2225export 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 || '' } ` } >
0 commit comments