11import React from 'react' ;
22import { useTranslation } from 'react-i18next'
33
4+ import Box from '@mui/material/Box'
5+ import Chip from '@mui/material/Chip'
46import Dialog from '@mui/material/Dialog'
5- import DialogTitle from '@mui/material/DialogTitle'
67import DialogContent from '@mui/material/DialogContent'
7- import DialogActions from '@mui/material/DialogActions'
8+ import Divider from '@mui/material/Divider'
9+ import Stack from '@mui/material/Stack'
810import Typography from '@mui/material/Typography'
9- import List from '@mui/material/List'
10- import ListItem from '@mui/material/ListItem'
11- import ListItemText from '@mui/material/ListItemText'
1211
13- import startCase from 'lodash/startCase '
12+ import isArray from 'lodash/isArray '
1413import map from 'lodash/map'
14+ import startCase from 'lodash/startCase'
1515
16- import Link from '../common/Link '
17-
16+ import { getScoreDetails , ScoreValueChip } from '../map-projects/Score '
17+ import CloseIconButton from '../common/CloseIconButton'
1818
19- const SearchHighlightsDialog = ( { onClose, highlight , score , raw_score , open} ) => {
19+ const SearchHighlightsDialog = ( { onClose, concept , rawScores , candidatesScore , open} ) => {
2020 const { t } = useTranslation ( )
21+ const highlight = concept ?. search_meta ?. search_highlight || { }
22+ const { hasPercentile, bucketColor, rerankScore } = getScoreDetails ( concept , candidatesScore )
23+
2124 return (
2225 < Dialog
2326 open = { Boolean ( open ) }
2427 onClose = { onClose }
2528 scroll = 'paper'
29+ fullWidth
30+ maxWidth = 'sm'
2631 sx = { {
2732 '& .MuiDialog-paper' : {
2833 backgroundColor : 'surface.n92' ,
@@ -33,81 +38,136 @@ const SearchHighlightsDialog = ({onClose, highlight, score, raw_score, open}) =>
3338 }
3439 } }
3540 >
36- < DialogTitle sx = { { p : 3 , color : 'surface.dark' , fontSize : '22px' , textAlign : 'left' } } >
37- { t ( 'search.search_highlight' ) }
38- </ DialogTitle >
39- < DialogContent style = { { padding : 0 } } >
40- < List dense sx = { { width : '100%' , bgcolor : 'surface.n92' , padding : '0 10px' , maxHeight : 700 } } >
41- {
42- map ( highlight , ( values , key ) => (
43- < React . Fragment key = { key } >
44- < ListItem >
45- < ListItemText
41+ < DialogContent sx = { { padding : 3 , maxHeight : 700 } } >
42+ < Stack spacing = { 2.5 } >
43+ < Stack direction = 'row' justifyContent = 'space-between' alignItems = 'center' spacing = { 2 } >
44+ < Typography sx = { { color : 'surface.dark' , fontSize : '22px' , lineHeight : 1.2 } } >
45+ { t ( 'search.search_highlight' ) }
46+ </ Typography >
47+ < CloseIconButton size = 'small' onClick = { onClose } sx = { { alignSelf : 'flex-start' } } />
48+ </ Stack >
49+
50+ < Stack
51+ spacing = { 1.25 }
52+ sx = { {
53+ alignSelf : 'flex-start' ,
54+ minWidth : { xs : '100%' , sm : 'auto' } ,
55+ maxWidth : '100%' ,
56+ padding : '12px 14px' ,
57+ borderRadius : '16px' ,
58+ backgroundColor : 'rgba(255, 255, 255, 0.4)' ,
59+ border : '1px solid rgba(0, 0, 0, 0.08)'
60+ } }
61+ >
62+ {
63+ hasPercentile &&
64+ < Stack
65+ direction = 'row'
66+ spacing = { 1.5 }
67+ alignItems = 'center'
68+ justifyContent = 'space-between'
69+ sx = { { minWidth : { sm : '260px' } } }
70+ >
71+ < Typography sx = { { fontSize : '12px' , color : 'surface.light' , fontWeight : 600 , whiteSpace : 'nowrap' } } >
72+ { t ( 'search.search_score' ) }
73+ </ Typography >
74+ < ScoreValueChip size = 'small' bucketColor = { bucketColor } label = { rerankScore } />
75+ </ Stack >
76+ }
77+
78+ < Stack spacing = { 0.75 } >
79+ < Stack
80+ direction = 'row'
81+ spacing = { 1.5 }
82+ alignItems = 'flex-start'
83+ justifyContent = 'space-between'
84+ sx = { { minWidth : { sm : '260px' } } }
85+ >
86+ < Typography sx = { { fontSize : '12px' , color : 'surface.light' , fontWeight : 600 , whiteSpace : 'nowrap' , paddingTop : '4px' } } >
87+ { t ( 'search.search_raw_score' ) }
88+ </ Typography >
89+ {
90+ rawScores ?. length ? (
91+ < Stack spacing = { 0.75 } alignItems = 'flex-end' >
92+ { map ( rawScores , ( rawScore , index ) => (
93+ < Stack
94+ key = { `${ rawScore . algorithm } -${ rawScore . score } -${ index } ` }
95+ direction = 'row'
96+ spacing = { 0.75 }
97+ alignItems = 'center'
98+ sx = { {
99+ flexWrap : 'nowrap' ,
100+ width : 'fit-content'
101+ } }
102+ >
103+ < Chip size = 'small' label = { rawScore . algorithm } variant = 'outlined' color = 'warning' />
104+ < ScoreValueChip
105+ size = 'small'
106+ showIndicator = { false }
107+ label = { rawScore . score }
108+ sx = { {
109+ backgroundColor : 'rgba(0, 0, 0, 0.08)' ,
110+ color : 'surface.dark' ,
111+ fontWeight : 600
112+ } }
113+ />
114+ </ Stack >
115+ ) ) }
116+ </ Stack >
117+ ) : (
118+ < Typography sx = { { fontSize : '13px' , color : 'surface.light' , textAlign : 'right' , paddingTop : '4px' } } >
119+ { t ( 'common.none' ) }
120+ </ Typography >
121+ )
122+ }
123+ </ Stack >
124+ </ Stack >
125+ </ Stack >
126+
127+ < Divider />
128+
129+ < Stack spacing = { 1.5 } >
130+ < Typography sx = { { fontSize : '16px' , color : 'surface.dark' , fontWeight : 700 } } >
131+ { t ( 'search.matched_attributes' ) }
132+ </ Typography >
133+ {
134+ map ( highlight , ( values , key ) => (
135+ < Box key = { key } >
136+ < Typography sx = { { fontSize : '12px' , color : 'surface.light' , fontWeight : 600 , marginBottom : 0.75 } } >
137+ { startCase ( key ) }
138+ </ Typography >
139+ < Stack
140+ spacing = { isArray ( values ) && key === 'synonyms' ? 1.25 : 0.75 }
46141 sx = { {
47- '.MuiListItemText-primary' : { color : 'surface.dark' , fontSize : '12px' } ,
48- '.MuiListItemText-secondary' : { color : 'default.light' , fontSize : '14px' }
142+ paddingLeft : 1 ,
143+ '& b' : {
144+ color : 'surface.dark'
145+ }
49146 } }
50- primary = { startCase ( key ) }
51- secondary = {
52- < React . Fragment >
53- {
54- map ( values , value => {
55- value = value . replaceAll ( '<em>' , '<b>' ) . replaceAll ( '</em>' , '</b>' )
56- return (
57- < Typography
58- key = { value }
59- component = "span"
60- sx = { { color : 'text.primary' , display : 'inline-block' } }
61- dangerouslySetInnerHTML = { { __html : value } }
62- />
63- ) } )
64- }
65- </ React . Fragment >
147+ >
148+ {
149+ map ( values , value => {
150+ const highlightedValue = value . replaceAll ( '<em>' , '<b>' ) . replaceAll ( '</em>' , '</b>' )
151+ return (
152+ < Typography
153+ key = { value }
154+ sx = { {
155+ color : 'text.primary' ,
156+ fontSize : key === 'synonyms' ? '12px' : '13px' ,
157+ lineHeight : key === 'synonyms' ? 0.95 : 1.3
158+ } }
159+ dangerouslySetInnerHTML = { { __html : highlightedValue } }
160+ />
161+ )
162+ } )
66163 }
67- />
68- </ ListItem >
69- </ React . Fragment >
70- ) )
71- }
72- < ListItem >
73- < ListItemText
74- sx = { {
75- '.MuiListItemText-primary' : { color : 'surface.dark' , fontSize : '12px' } ,
76- '.MuiListItemText-secondary' : { color : 'default.light' , fontSize : '14px' }
77- } }
78- primary = { t ( 'search.search_score' ) }
79- secondary = {
80- < Typography
81- component = "span"
82- sx = { { color : 'text.primary' , display : 'flex' , fontWeight : 'bold' } }
83- >
84- { score }
85- </ Typography >
86- }
87- />
88- </ ListItem >
89- < ListItem >
90- < ListItemText
91- sx = { {
92- '.MuiListItemText-primary' : { color : 'surface.dark' , fontSize : '12px' } ,
93- '.MuiListItemText-secondary' : { color : 'default.light' , fontSize : '14px' }
94- } }
95- primary = { t ( 'search.search_raw_score' ) }
96- secondary = {
97- < Typography
98- component = "span"
99- sx = { { color : 'text.primary' , display : 'flex' , fontWeight : 'bold' } }
100- >
101- { raw_score }
102- </ Typography >
103- }
104- />
105- </ ListItem >
106- </ List >
164+ </ Stack >
165+ </ Box >
166+ ) )
167+ }
168+ </ Stack >
169+ </ Stack >
107170 </ DialogContent >
108- < DialogActions sx = { { p : 3 } } >
109- < Link sx = { { fontSize : '14px' } } label = { t ( 'common.close' ) } onClick = { onClose } />
110- </ DialogActions >
111171 </ Dialog >
112172 )
113173}
0 commit comments