1
+ import { Box , Typography , Chip } from '@mui/material'
2
+ import { FileSearchCompletedData , FileSearchResultData } from '../../../shared/types'
3
+ import { useTranslation } from 'react-i18next'
4
+ import { useFileSearchResults } from './api'
5
+ import { GrayButton } from './generics/Buttons'
6
+ import { ShortText , Subject } from '@mui/icons-material'
7
+
8
+
9
+ const AnnotationBox = ( {
10
+ data,
11
+ relevanceOrder
12
+ } : {
13
+ data : FileSearchResultData ,
14
+ relevanceOrder : number // By default the backend returns the RAG results in most relevant results first
15
+ } ) => {
16
+ const lineNum = 3 ;
17
+ const multilineEllipsisTruncate = {
18
+ // This is a trick to achieve a multu-line ellipsis truncation for max 3 rows of text.
19
+ // -webkit-box is used to support legacy browsers and for WebkitBoxOrient
20
+ overflow : 'hidden' ,
21
+ flex : '1' ,
22
+ display : '-webkit-box' ,
23
+ WebkitLineClamp : lineNum ,
24
+ WebkitBoxOrient : 'vertical' ,
25
+ textOverflow : 'ellipsis' ,
26
+ lineHeight : '1.5' ,
27
+ maxHeight : `calc(1.5em * ${ lineNum } )` ,
28
+ }
29
+
30
+ return (
31
+ < Box sx = { { display : 'flex' , gap : 2 } } >
32
+ < Box sx = { {
33
+ color : 'black' ,
34
+ backgroundColor : 'rgba(0,0,0,0.12)' ,
35
+ width : 24 ,
36
+ height : 24 ,
37
+ display : 'flex' ,
38
+ justifyContent : 'center' ,
39
+ alignItems : 'center' ,
40
+ borderRadius : '100%' ,
41
+ fontSize : '0.8rem' ,
42
+ mt : '0.4rem'
43
+ } } >
44
+ { relevanceOrder }
45
+ </ Box >
46
+ < Typography sx = { multilineEllipsisTruncate } >
47
+ { data . text }
48
+ </ Typography >
49
+ </ Box >
50
+ )
51
+ }
52
+
53
+ const Queries = ( { queries } : { queries : string [ ] } ) => {
54
+ const { t } = useTranslation ( )
55
+
56
+ return ( < Box
57
+ sx = { {
58
+ display : 'flex' ,
59
+ flexDirection : 'row' ,
60
+ flexWrap : 'wrap' ,
61
+ gap : 1 ,
62
+ mb : 5 ,
63
+ } }
64
+ >
65
+ < Typography fontWeight = { 'bold' } > { t ( 'chat:searchTerms' ) } </ Typography >
66
+ { queries . map ( ( q , idx ) => (
67
+ < Chip
68
+ key = { idx }
69
+ label = { q }
70
+ sx = { {
71
+ width : 'fit-content' ,
72
+ p : 0.5 ,
73
+ borderRadius : 2 ,
74
+ fontWeight : '600' ,
75
+ height : 'auto' ,
76
+ '& .MuiChip-label' : {
77
+ display : 'block' ,
78
+ whiteSpace : 'normal' ,
79
+ } ,
80
+ } }
81
+ color = "info"
82
+ />
83
+ ) ) }
84
+ </ Box > )
85
+ }
86
+
87
+ const Annotations = ( { fileSearchResult } : { fileSearchResult : FileSearchCompletedData } ) => {
88
+ const { data : results , isSuccess : isResultsSuccess } = useFileSearchResults ( fileSearchResult . id )
89
+ const arrayResults = Array . isArray ( results ) ? results : [ ]
90
+ const { t } = useTranslation ( )
91
+
92
+
93
+ return (
94
+ < Box >
95
+ < Typography variant = "h6" fontWeight = { 'bold' } sx = { { mb : 2.5 } } >
96
+ { t ( 'chat:sources' ) }
97
+ </ Typography >
98
+ < Queries queries = { fileSearchResult . queries } />
99
+ { isResultsSuccess ?
100
+ < Box sx = { { display : 'flex' , flexDirection : 'column' , gap : '1.5rem' , minHeight : 400 } } >
101
+ { arrayResults . map ( ( result , i ) => (
102
+ < AnnotationBox key = { i } data = { result } relevanceOrder = { i + 1 } />
103
+ ) ) }
104
+ { /* <Box>
105
+ <GrayButton startIcon={<Subject />}>{t('chat:readMore')}</GrayButton>
106
+ </Box> */ }
107
+ </ Box > :
108
+ < Typography > Failed to display search results</ Typography >
109
+ }
110
+ </ Box >
111
+ )
112
+ }
113
+
114
+ export default Annotations
0 commit comments