diff --git a/src/components/map-projects/MapProject.jsx b/src/components/map-projects/MapProject.jsx index 22d5242..622ae4a 100644 --- a/src/components/map-projects/MapProject.jsx +++ b/src/components/map-projects/MapProject.jsx @@ -2216,6 +2216,24 @@ const MapProject = () => { const getAllCandidatesForRow = index => flatten(map(allCandidatesRef.current, candidates => getCandidatesForRow(index, candidates))) + const getRawScoresForConcept = (index, concept) => { + if(!concept || !isNumber(index)) + return [] + + return compact(map(allCandidates, (candidates, algorithm) => { + const rowCandidates = getCandidatesForRow(index, candidates) + const matchingConcept = find( + rowCandidates, + candidate => candidate?.url === concept?.url || ( + candidate?.id === concept?.id && + (candidate?.source || candidate?.repo?.id || candidate?.repo?.short_code) === (concept?.source || concept?.repo?.id || concept?.repo?.short_code) + ) + ) + const score = parseFloat(matchingConcept?.search_meta?.search_score) + return Number.isFinite(score) ? {algorithm, score: score.toFixed(2)} : null + })) + } + const isReadyForRerank = _index => { const index = isNumber(_index) ? _index : rowIndex if(isNumber(index) && get(rowStageRef.current, `${index}.rerank`) !== 0) { @@ -2607,7 +2625,7 @@ const MapProject = () => { return permissionDenied ? : (
{ - Boolean(repoVersion?.url) && CIELMappedSources.length && + Boolean(repoVersion?.url) && CIELMappedSources.length > 0 && { setShowHighlights(false)} - highlight={showHighlights?.search_meta?.search_highlight || []} - score={parseFloat(showHighlights?.search_meta?.search_normalized_score || 0).toFixed(2)} - raw_score={parseFloat(showHighlights?.search_meta?.search_score || 0).toFixed(2)} + concept={showHighlights} + rawScores={getRawScoresForConcept(rowIndex, showHighlights)} + candidatesScore={candidatesScore} /> : setShowProjectLogs(false) } logs={projectLogs} project={project} /> diff --git a/src/components/map-projects/Score.jsx b/src/components/map-projects/Score.jsx index 6771ee5..399ec8c 100644 --- a/src/components/map-projects/Score.jsx +++ b/src/components/map-projects/Score.jsx @@ -15,17 +15,16 @@ import isNaN from 'lodash/isNaN' import ConceptIcon from '../concepts/ConceptIcon' - -const Score = ({concept, setShowHighlights, sx, isAIRecommended, candidatesScore, algoScoreFirst, size}) => { - const { t } = useTranslation(); +export const getScoreDetails = (concept, candidatesScore) => { let percentile = concept?.search_meta?.search_normalized_score || ((concept?.search_meta?.search_rerank_score || concept?.search_meta?.search_score) * 100) if(percentile && !isNumber(percentile)) percentile = parseFloat(percentile) + const score = concept?.search_meta?.search_score const hasPercentile = isNumber(percentile) - const { color } = MATCH_TYPES[concept?.search_meta?.match_type || 'no_match'] const recommendedScore = candidatesScore?.recommended const availableScore = candidatesScore?.available + let qualityBucket; if(hasPercentile) { if (percentile >= recommendedScore) @@ -35,10 +34,49 @@ const Score = ({concept, setShowHighlights, sx, isAIRecommended, candidatesScore else qualityBucket = 'low_ranked' } - let bucketColor = qualityBucket ? SCORES_COLOR[qualityBucket] : false - const rerankScore = `${parseFloat(hasPercentile ? percentile : score).toFixed(2)}%` - const algoScore = `${parseFloat(score).toFixed(2)}` + return { + score, + percentile, + hasPercentile, + qualityBucket, + bucketColor: qualityBucket ? SCORES_COLOR[qualityBucket] : false, + rerankScore: `${parseFloat(hasPercentile ? percentile : score).toFixed(2)}%`, + algoScore: `${parseFloat(score).toFixed(2)}` + } +} + +export const ScoreValueChip = ({ bucketColor, label, size='medium', showIndicator=true, sx }) => ( + + + + ) : undefined + } + label={label} + sx={sx} + /> +) + +const Score = ({concept, setShowHighlights, sx, isAIRecommended, candidatesScore, algoScoreFirst, size}) => { + const { t } = useTranslation(); + const { + score, + hasPercentile, + bucketColor, + rerankScore, + algoScore + } = getScoreDetails(concept, candidatesScore) + const { color } = MATCH_TYPES[concept?.search_meta?.match_type || 'no_match'] + return ( - - - } + bucketColor={bucketColor} label={ {algoScoreFirst ? algoScore : rerankScore} diff --git a/src/components/search/SearchHighlightsDialog.jsx b/src/components/search/SearchHighlightsDialog.jsx index 257d2ac..8eb933e 100644 --- a/src/components/search/SearchHighlightsDialog.jsx +++ b/src/components/search/SearchHighlightsDialog.jsx @@ -1,28 +1,33 @@ import React from 'react'; import { useTranslation } from 'react-i18next' +import Box from '@mui/material/Box' +import Chip from '@mui/material/Chip' import Dialog from '@mui/material/Dialog' -import DialogTitle from '@mui/material/DialogTitle' import DialogContent from '@mui/material/DialogContent' -import DialogActions from '@mui/material/DialogActions' +import Divider from '@mui/material/Divider' +import Stack from '@mui/material/Stack' import Typography from '@mui/material/Typography' -import List from '@mui/material/List' -import ListItem from '@mui/material/ListItem' -import ListItemText from '@mui/material/ListItemText' -import startCase from 'lodash/startCase' +import isArray from 'lodash/isArray' import map from 'lodash/map' +import startCase from 'lodash/startCase' -import Link from '../common/Link' - +import { getScoreDetails, ScoreValueChip } from '../map-projects/Score' +import CloseIconButton from '../common/CloseIconButton' -const SearchHighlightsDialog = ({onClose, highlight, score, raw_score, open}) => { +const SearchHighlightsDialog = ({onClose, concept, rawScores, candidatesScore, open}) => { const { t } = useTranslation() + const highlight = concept?.search_meta?.search_highlight || {} + const { hasPercentile, bucketColor, rerankScore } = getScoreDetails(concept, candidatesScore) + return ( } }} > - - {t('search.search_highlight')} - - - - { - map(highlight, (values, key) => ( - - - + + + + {t('search.search_highlight')} + + + + + + { + hasPercentile && + + + {t('search.search_score')} + + + + } + + + + + {t('search.search_raw_score')} + + { + rawScores?.length ? ( + + {map(rawScores, (rawScore, index) => ( + + + + + ))} + + ) : ( + + {t('common.none')} + + ) + } + + + + + + + + + {t('search.matched_attributes')} + + { + map(highlight, (values, key) => ( + + + {startCase(key)} + + - { - map(values, value => { - value = value.replaceAll('', '').replaceAll('', '') - return ( - - )}) - } - + > + { + map(values, value => { + const highlightedValue = value.replaceAll('', '').replaceAll('', '') + return ( + + ) + }) } - /> - - - )) - } - - - {score} - - } - /> - - - - {raw_score} - - } - /> - - + + + )) + } + + - - - ) } diff --git a/src/i18n/locales/en/translations.json b/src/i18n/locales/en/translations.json index e61f3d3..6663504 100644 --- a/src/i18n/locales/en/translations.json +++ b/src/i18n/locales/en/translations.json @@ -332,10 +332,11 @@ "url_registry": "entries", "confidence": "Confidence", "score": "Score", - "search_highlight": "Search Highlight", + "search_highlight": "Match Details", "search_results": "Search Results", - "search_score": "Search Score", - "search_raw_score": "Search Raw Score", + "search_score": "Unified Score", + "search_raw_score": "Raw Scores", + "matched_attributes": "Matched Attributes", "list_view": "List View", "table_view": "Table View" }, diff --git a/src/i18n/locales/es/translations.json b/src/i18n/locales/es/translations.json index 3836f97..5f830d6 100644 --- a/src/i18n/locales/es/translations.json +++ b/src/i18n/locales/es/translations.json @@ -319,15 +319,16 @@ "search_this_repository": "Buscar en este repositorio", "search_all_concepts": "Buscar todos los conceptos", "search_results": "Resultados de Búsqueda", - "search_score": "Puntuación de Búsqueda", - "search_raw_score": "Puntuación Bruta de Búsqueda", + "search_score": "Puntuación Unificada", + "search_raw_score": "Puntuaciones Brutas", "mappings": "Mapeos", "input_placeholder_drawer": "Ingrese un término de búsqueda o pulse / para ver opciones", "search_this_url_registry": "Buscar en este registro de URL ", "url_registry": "entradas", "confidence": "Confianza", "score": "Puntaje", - "search_highlight": "Resaltado de búsqueda", + "search_highlight": "Detalles de Coincidencia", + "matched_attributes": "Atributos Coincidentes", "list_view": "Vista de lista", "table_view": "Vista de tabla" }, diff --git a/src/i18n/locales/zh/translations.json b/src/i18n/locales/zh/translations.json index 5c0ee70..dc27381 100644 --- a/src/i18n/locales/zh/translations.json +++ b/src/i18n/locales/zh/translations.json @@ -332,10 +332,11 @@ "url_registry": "条目", "confidence": "置信度", "score": "评分", - "search_highlight": "搜索亮点", + "search_highlight": "匹配详情", "search_results": "搜索结果", - "search_score": "搜索评分", - "search_raw_score": "原始搜索评分", + "search_score": "统一评分", + "search_raw_score": "原始评分", + "matched_attributes": "匹配属性", "list_view": "列表视图", "table_view": "表格视图" },