Open-Greek-Financial-LLM-Leaderboard
/
frontend
/src
/pages
/LeaderboardPage
/components
/Leaderboard
/utils
/columnUtils.js
import React from "react"; | |
import { Box, Typography, Link, Tooltip, IconButton } from "@mui/material"; | |
import { getModelTypeIcon } from "../constants/modelTypes"; | |
import TrendingUpIcon from "@mui/icons-material/TrendingUp"; | |
import TrendingDownIcon from "@mui/icons-material/TrendingDown"; | |
import RemoveIcon from "@mui/icons-material/Remove"; | |
import PushPinIcon from "@mui/icons-material/PushPin"; | |
import PushPinOutlinedIcon from "@mui/icons-material/PushPinOutlined"; | |
import { TABLE_DEFAULTS, HIGHLIGHT_COLORS } from "../constants/defaults"; | |
import { looksLikeRegex, extractTextSearch } from "./searchUtils"; | |
import { commonStyles } from "../styles/common"; | |
import { typeColumnSort } from "../components/Table/hooks/useSorting"; | |
import { | |
COLUMN_TOOLTIPS, | |
getTooltipStyle, | |
TABLE_TOOLTIPS, | |
} from "../constants/tooltips"; | |
import OpenInNewIcon from "@mui/icons-material/OpenInNew"; | |
import { alpha } from "@mui/material/styles"; | |
import InfoIconWithTooltip from "../../../../../components/shared/InfoIconWithTooltip"; | |
const DatabaseIcon = () => ( | |
<svg | |
className="mr-1.5 text-gray-400 group-hover:text-red-500" | |
xmlns="http://www.w3.org/2000/svg" | |
aria-hidden="true" | |
focusable="false" | |
role="img" | |
width="1.4em" | |
height="1.4em" | |
preserveAspectRatio="xMidYMid meet" | |
viewBox="0 0 25 25" | |
> | |
<ellipse | |
cx="12.5" | |
cy="5" | |
fill="currentColor" | |
fillOpacity="0.25" | |
rx="7.5" | |
ry="2" | |
></ellipse> | |
<path | |
d="M12.5 15C16.6421 15 20 14.1046 20 13V20C20 21.1046 16.6421 22 12.5 22C8.35786 22 5 21.1046 5 20V13C5 14.1046 8.35786 15 12.5 15Z" | |
fill="currentColor" | |
opacity="0.5" | |
></path> | |
<path | |
d="M12.5 7C16.6421 7 20 6.10457 20 5V11.5C20 12.6046 16.6421 13.5 12.5 13.5C8.35786 13.5 5 12.6046 5 11.5V5C5 6.10457 8.35786 7 12.5 7Z" | |
fill="currentColor" | |
opacity="0.5" | |
></path> | |
<path | |
d="M5.23628 12C5.08204 12.1598 5 12.8273 5 13C5 14.1046 8.35786 15 12.5 15C16.6421 15 20 14.1046 20 13C20 12.8273 19.918 12.1598 19.7637 12C18.9311 12.8626 15.9947 13.5 12.5 13.5C9.0053 13.5 6.06886 12.8626 5.23628 12Z" | |
fill="currentColor" | |
></path> | |
</svg> | |
); | |
const HighlightedText = ({ text, searchValue }) => { | |
if (!searchValue) return text; | |
const searches = searchValue | |
.split(";") | |
.map((s) => s.trim()) | |
.filter(Boolean); | |
let result = text; | |
let fragments = [{ text: result, isMatch: false }]; | |
searches.forEach((search, searchIndex) => { | |
if (!search) return; | |
try { | |
let regex; | |
if (looksLikeRegex(search)) { | |
regex = new RegExp(search, "gi"); | |
} else { | |
regex = new RegExp(search.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi"); | |
} | |
const newFragments = []; | |
fragments.forEach((fragment) => { | |
if (fragment.isMatch) { | |
newFragments.push(fragment); | |
return; | |
} | |
const parts = fragment.text.split(regex); | |
const matches = fragment.text.match(regex); | |
if (!matches) { | |
newFragments.push(fragment); | |
return; | |
} | |
parts.forEach((part, i) => { | |
if (part) newFragments.push({ text: part, isMatch: false }); | |
if (i < parts.length - 1) { | |
newFragments.push({ | |
text: matches[i], | |
isMatch: true, | |
colorIndex: searchIndex % HIGHLIGHT_COLORS.length, | |
}); | |
} | |
}); | |
}); | |
fragments = newFragments; | |
} catch (e) { | |
console.warn("Invalid regex:", search); | |
} | |
}); | |
return ( | |
<> | |
{fragments.map((fragment, i) => | |
fragment.isMatch ? ( | |
<Box | |
key={i} | |
component="span" | |
sx={{ | |
backgroundColor: HIGHLIGHT_COLORS[fragment.colorIndex], | |
color: (theme) => | |
theme.palette.getContrastText( | |
HIGHLIGHT_COLORS[fragment.colorIndex] | |
), | |
fontWeight: 500, | |
px: 0.5, | |
py: "2px", | |
borderRadius: "3px", | |
mx: "1px", | |
overflow: "visible", | |
display: "inline-block", | |
}} | |
> | |
{fragment.text} | |
</Box> | |
) : ( | |
<React.Fragment key={i}>{fragment.text}</React.Fragment> | |
) | |
)} | |
</> | |
); | |
}; | |
const MEDAL_STYLES = { | |
1: { | |
color: "#B58A1B", | |
background: "linear-gradient(135deg, #FFF7E0 0%, #FFD700 100%)", | |
borderColor: "rgba(212, 160, 23, 0.35)", | |
shadowColor: "rgba(212, 160, 23, 0.8)", | |
}, | |
2: { | |
color: "#667380", | |
background: "linear-gradient(135deg, #FFFFFF 0%, #D8E3ED 100%)", | |
borderColor: "rgba(124, 139, 153, 0.35)", | |
shadowColor: "rgba(124, 139, 153, 0.8)", | |
}, | |
3: { | |
color: "#B85C2F", | |
background: "linear-gradient(135deg, #FDF0E9 0%, #FFBC8C 100%)", | |
borderColor: "rgba(204, 108, 61, 0.35)", | |
shadowColor: "rgba(204, 108, 61, 0.8)", | |
}, | |
}; | |
const getMedalStyle = (rank) => { | |
if (rank <= 3) { | |
const medalStyle = MEDAL_STYLES[rank]; | |
return { | |
color: medalStyle.color, | |
fontWeight: 900, | |
fontStretch: "150%", | |
fontFamily: '"Inter", -apple-system, sans-serif', | |
width: "24px", | |
height: "24px", | |
background: medalStyle.background, | |
border: "1px solid", | |
borderColor: medalStyle.borderColor, | |
borderRadius: "50%", | |
display: "flex", | |
alignItems: "center", | |
justifyContent: "center", | |
fontSize: "0.95rem", | |
lineHeight: 1, | |
padding: 0, | |
boxShadow: `1px 1px 0 ${medalStyle.shadowColor}`, | |
position: "relative", | |
}; | |
} | |
return { | |
color: "inherit", | |
fontWeight: rank <= 10 ? 600 : 400, | |
}; | |
}; | |
const getRankStyle = (rank) => getMedalStyle(rank); | |
const RankIndicator = ({ rank, previousRank, mode }) => { | |
const rankChange = previousRank ? previousRank - rank : 0; | |
const RankChangeIndicator = ({ change }) => { | |
if (!change || mode === "dynamic") return null; | |
const getChangeColor = (change) => { | |
if (change > 0) return "success.main"; | |
if (change < 0) return "error.main"; | |
return "grey.500"; | |
}; | |
const getChangeIcon = (change) => { | |
if (change > 0) return <TrendingUpIcon sx={{ fontSize: "1rem" }} />; | |
if (change < 0) return <TrendingDownIcon sx={{ fontSize: "1rem" }} />; | |
return <RemoveIcon sx={{ fontSize: "1rem" }} />; | |
}; | |
return ( | |
<Tooltip | |
title={`${Math.abs(change)} position${ | |
Math.abs(change) > 1 ? "s" : "" | |
} ${change > 0 ? "up" : "down"}`} | |
arrow | |
placement="right" | |
> | |
<Box | |
sx={{ | |
display: "flex", | |
alignItems: "center", | |
color: getChangeColor(change), | |
ml: 0.5, | |
fontSize: "0.75rem", | |
}} | |
> | |
{getChangeIcon(change)} | |
</Box> | |
</Tooltip> | |
); | |
}; | |
return ( | |
<Box | |
sx={{ | |
display: "flex", | |
alignItems: "center", | |
justifyContent: "center", | |
width: "100%", | |
}} | |
> | |
<Typography | |
sx={{ | |
...getRankStyle(rank), | |
display: "flex", | |
alignItems: "center", | |
lineHeight: 1, | |
position: "relative", | |
}} | |
> | |
{rank <= 3 ? ( | |
<> | |
<Box component="span" sx={{ position: "relative", zIndex: 1 }}> | |
{rank} | |
</Box> | |
<RankChangeIndicator change={rankChange} /> | |
</> | |
) : ( | |
<> | |
<Box component="span" sx={{ position: "relative", zIndex: 1 }}> | |
{rank} | |
</Box> | |
<RankChangeIndicator change={rankChange} /> | |
</> | |
)} | |
</Typography> | |
</Box> | |
); | |
}; | |
const getDetailsUrl = (modelName) => { | |
const formattedName = modelName.replace("/", "__"); | |
return `https://huggingface.co/datasets/TheFinAI/lm-eval-results-private`; | |
}; | |
const HeaderLabel = ({ label, tooltip, className, isSorted }) => ( | |
<Tooltip | |
title={label} | |
arrow | |
placement="top" | |
enterDelay={1000} | |
componentsProps={getTooltipStyle} | |
> | |
<Typography | |
className={className} | |
sx={{ | |
fontWeight: 600, | |
color: isSorted ? "primary.main" : "grey.700", | |
flex: 1, | |
transition: "max-width 0.2s ease", | |
maxWidth: "100%", | |
...(label === "Rank" || label === "Type" | |
? { | |
overflow: "visible", | |
whiteSpace: "normal", | |
textOverflow: "clip", | |
textAlign: "center", | |
} | |
: { | |
overflow: "hidden", | |
textOverflow: "ellipsis", | |
whiteSpace: "nowrap", | |
}), | |
"@media (hover: hover)": { | |
".MuiTableCell-root:hover &": { | |
maxWidth: tooltip ? "calc(100% - 48px)" : "100%", | |
}, | |
}, | |
}} | |
> | |
{label} | |
</Typography> | |
</Tooltip> | |
); | |
const InfoIcon = ({ tooltip }) => ( | |
<Box | |
component="span" | |
sx={{ | |
opacity: 0.5, | |
display: "flex", | |
alignItems: "center", | |
ml: 0.5, | |
}} | |
> | |
<InfoIconWithTooltip tooltip={tooltip} /> | |
</Box> | |
); | |
const createHeaderCell = (label, tooltip) => (header) => | |
( | |
<Box | |
className="header-content" | |
sx={{ | |
display: "flex", | |
alignItems: "center", | |
width: "100%", | |
position: "relative", | |
}} | |
> | |
<HeaderLabel | |
label={label} | |
tooltip={tooltip} | |
className="header-label" | |
isSorted={header?.column?.getIsSorted()} | |
/> | |
<Box | |
sx={{ | |
display: "flex", | |
alignItems: "center", | |
gap: 0.5, | |
ml: "auto", | |
flexShrink: 0, | |
}} | |
> | |
{tooltip && <InfoIcon tooltip={tooltip} />} | |
</Box> | |
</Box> | |
); | |
const createModelHeader = | |
(totalModels, officialProvidersCount = 0, isOfficialProviderActive = false) => | |
({ table }) => { | |
return ( | |
<Box | |
sx={{ | |
display: "flex", | |
alignItems: "center", | |
justifyContent: "space-between", | |
width: "100%", | |
}} | |
> | |
<Box | |
sx={{ | |
display: "flex", | |
alignItems: "center", | |
gap: 1, | |
}} | |
> | |
<Typography | |
sx={{ | |
fontWeight: 600, | |
color: "grey.700", | |
overflow: "hidden", | |
textOverflow: "ellipsis", | |
whiteSpace: "nowrap", | |
}} | |
> | |
Model | |
</Typography> | |
</Box> | |
</Box> | |
); | |
}; | |
const BooleanValue = ({ value }) => { | |
if (value === null || value === undefined) | |
return <Typography variant="body2">-</Typography>; | |
return ( | |
<Box | |
sx={(theme) => ({ | |
display: "flex", | |
alignItems: "center", | |
justifyContent: "center", | |
borderRadius: "4px", | |
px: 1, | |
py: 0.5, | |
backgroundColor: value | |
? theme.palette.mode === "dark" | |
? alpha(theme.palette.success.main, 0.1) | |
: alpha(theme.palette.success.main, 0.1) | |
: theme.palette.mode === "dark" | |
? alpha(theme.palette.error.main, 0.1) | |
: alpha(theme.palette.error.main, 0.1), | |
})} | |
> | |
<Typography | |
variant="body2" | |
sx={(theme) => ({ | |
color: value | |
? theme.palette.mode === "dark" | |
? theme.palette.success.light | |
: theme.palette.success.dark | |
: theme.palette.mode === "dark" | |
? theme.palette.error.light | |
: theme.palette.error.dark, | |
})} | |
> | |
{value ? "Yes" : "No"} | |
</Typography> | |
</Box> | |
); | |
}; | |
export const createColumns = ( | |
getColorForValue, | |
scoreDisplay = "normalized", | |
columnVisibility = {}, | |
totalModels, | |
averageMode = "all", | |
searchValue = "", | |
rankingMode = "static", | |
onTogglePin, | |
hasPinnedRows = false | |
) => { | |
// Ajuster les tailles des colonnes en fonction de la présence de lignes épinglées | |
const getColumnSize = (defaultSize) => | |
hasPinnedRows ? "auto" : `${defaultSize}px`; | |
const baseColumns = [ | |
{ | |
accessorKey: "isPinned", | |
header: () => null, | |
cell: ({ row }) => ( | |
<Box | |
sx={{ | |
display: "flex", | |
alignItems: "center", | |
justifyContent: "center", | |
height: "100%", | |
}} | |
> | |
<IconButton | |
size="small" | |
onClick={(e) => { | |
e.stopPropagation(); | |
e.preventDefault(); | |
onTogglePin(row.original.id); | |
}} | |
sx={{ | |
padding: 0.5, | |
color: row.original.isPinned ? "primary.main" : "grey.400", | |
"&:hover": { | |
color: "primary.main", | |
}, | |
}} | |
> | |
{row.original.isPinned ? ( | |
<PushPinIcon fontSize="small" /> | |
) : ( | |
<PushPinOutlinedIcon fontSize="small" /> | |
)} | |
</IconButton> | |
</Box> | |
), | |
enableSorting: false, | |
size: getColumnSize(40), | |
}, | |
{ | |
accessorKey: "rank", | |
header: createHeaderCell("Rank"), | |
cell: ({ row }) => { | |
const rank = | |
rankingMode === "static" | |
? row.original.static_rank | |
: row.original.dynamic_rank; | |
return ( | |
<RankIndicator | |
rank={rank} | |
previousRank={row.original.previous_rank} | |
mode="static" | |
/> | |
); | |
}, | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["rank"], | |
}, | |
{ | |
id: "model_type", | |
accessorFn: (row) => row.model.type, | |
header: createHeaderCell("Type"), | |
sortingFn: typeColumnSort, | |
cell: ({ row }) => ( | |
<Box | |
sx={{ | |
display: "flex", | |
alignItems: "center", | |
justifyContent: "center", | |
width: "100%", | |
}} | |
> | |
<Tooltip title={row.original.model.type}> | |
<Typography | |
sx={{ | |
fontSize: "1.2rem", | |
cursor: "help", | |
lineHeight: 1, | |
fontFamily: | |
'"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji", sans-serif', | |
}} | |
> | |
{getModelTypeIcon(row.original.model.type)} | |
</Typography> | |
</Tooltip> | |
</Box> | |
), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["model.type_icon"], | |
}, | |
{ | |
accessorKey: "id", | |
header: createModelHeader(totalModels), | |
cell: ({ row }) => { | |
const textSearch = extractTextSearch(searchValue); | |
const modelName = row.original.model.name; | |
return ( | |
<Box | |
sx={{ | |
width: "100%", | |
display: "flex", | |
alignItems: "center", | |
gap: 1, | |
}} | |
> | |
<Box | |
sx={{ | |
display: "flex", | |
alignItems: "center", | |
gap: 1, | |
minWidth: 0, | |
flex: 1, | |
}} | |
> | |
<Link | |
href={`https://huggingface.co/${modelName}`} | |
target="_blank" | |
rel="noopener noreferrer" | |
aria-label={`View ${modelName} on Hugging Face Hub`} | |
title={TABLE_TOOLTIPS.HUB_LINK(modelName)} | |
sx={{ | |
textDecoration: "none", | |
color: "info.main", | |
display: "flex", | |
alignItems: "center", | |
gap: 0.5, | |
"&:hover": { | |
textDecoration: "underline", | |
color: (theme) => | |
theme.palette.mode === "dark" | |
? theme.palette.info.light | |
: theme.palette.info.dark, | |
"& svg": { | |
opacity: 0.8, | |
}, | |
}, | |
overflow: "hidden", | |
textOverflow: "ellipsis", | |
whiteSpace: "nowrap", | |
flex: 1, | |
minWidth: 0, | |
fontWeight: row.original.static_rank <= 3 ? 600 : "inherit", | |
}} | |
> | |
<HighlightedText text={modelName} searchValue={textSearch} /> | |
<OpenInNewIcon | |
sx={{ | |
fontSize: "0.75rem", | |
opacity: 0.6, | |
transition: "opacity 0.2s ease-in-out", | |
ml: 0.5, | |
flexShrink: 0, | |
}} | |
/> | |
</Link> | |
<Link | |
href={getDetailsUrl(modelName)} | |
target="_blank" | |
rel="noopener noreferrer" | |
aria-label={`View detailed evaluation results for ${modelName}`} | |
title={TABLE_TOOLTIPS.EVAL_RESULTS(modelName)} | |
sx={{ | |
textDecoration: "none", | |
"&:hover": { | |
textDecoration: "underline", | |
"& svg": { | |
color: "text.primary", | |
}, | |
}, | |
display: "flex", | |
alignItems: "center", | |
color: "text.secondary", | |
flexShrink: 0, | |
mr: 0, | |
}} | |
> | |
<DatabaseIcon /> | |
</Link> | |
</Box> | |
</Box> | |
); | |
}, | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["id"], | |
}, | |
{ | |
accessorKey: "model.average_score", | |
header: createHeaderCell("Average", COLUMN_TOOLTIPS.AVERAGE), | |
cell: ({ row, getValue }) => | |
createScoreCell(getValue, row, "model.average_score"), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["model.average_score"], | |
meta: { | |
headerStyle: { | |
borderLeft: (theme) => | |
`2px solid ${alpha( | |
theme.palette.divider, | |
theme.palette.mode === "dark" ? 0.1 : 0.2 | |
)}`, | |
borderRight: (theme) => | |
`2px solid ${alpha( | |
theme.palette.divider, | |
theme.palette.mode === "dark" ? 0.1 : 0.2 | |
)}`, | |
}, | |
cellStyle: (value) => ({ | |
position: "relative", | |
overflow: "hidden", | |
padding: "8px 16px", | |
borderLeft: (theme) => | |
`2px solid ${alpha( | |
theme.palette.divider, | |
theme.palette.mode === "dark" ? 0.1 : 0.2 | |
)}`, | |
borderRight: (theme) => | |
`2px solid ${alpha( | |
theme.palette.divider, | |
theme.palette.mode === "dark" ? 0.1 : 0.2 | |
)}`, | |
}), | |
}, | |
}, | |
]; | |
const createScoreCell = (getValue, row, field) => { | |
const value = getValue(); | |
const rawValue = field.includes("normalized") | |
? row.original.evaluations[field.split(".")[1]]?.value | |
: value; | |
const isAverageColumn = field === "model.average_score"; | |
const hasNoValue = value === null || value === undefined; | |
return ( | |
<Box sx={commonStyles.cellContainer}> | |
{!hasNoValue && (scoreDisplay === "normalized" || isAverageColumn) && ( | |
<Box | |
sx={{ | |
position: "absolute", | |
left: -16, | |
top: -16, | |
height: "calc(100% + 32px)", | |
width: `calc(${value}% + 16px)`, | |
backgroundColor: getColorForValue(value), | |
opacity: (theme) => (theme.palette.mode === "light" ? 0.1 : 0.2), | |
transition: "width 0.3s ease", | |
zIndex: 0, | |
}} | |
/> | |
)} | |
<Box | |
sx={{ | |
position: "relative", | |
display: "flex", | |
alignItems: "center", | |
gap: 1, | |
zIndex: 1, | |
pl: isAverageColumn && !hasNoValue ? 1 : 0, | |
}} | |
> | |
{isAverageColumn && !hasNoValue && ( | |
<Box | |
sx={{ | |
width: 10, | |
height: 10, | |
borderRadius: "50%", | |
marginLeft: -1, | |
backgroundColor: getColorForValue(value), | |
}} | |
/> | |
)} | |
<Typography variant="body2"> | |
{hasNoValue ? ( | |
"-" | |
) : ( | |
<> | |
{isAverageColumn ? ( | |
<> | |
{value.toFixed(2)} | |
<span style={{ opacity: 0.5 }}> %</span> | |
</> | |
) : scoreDisplay === "normalized" ? ( | |
<> | |
{value.toFixed(2)} | |
<span style={{ opacity: 0.5 }}> %</span> | |
</> | |
) : ( | |
<>{rawValue.toFixed(2)}</> | |
)} | |
</> | |
)} | |
</Typography> | |
</Box> | |
</Box> | |
); | |
}; | |
const evaluationColumns = [ | |
{ | |
accessorKey: "evaluations.multifin.normalized_score", | |
header: createHeaderCell("MultiFin", COLUMN_TOOLTIPS.MULTIFIN), | |
cell: ({ row, getValue }) => | |
createScoreCell(getValue, row, "evaluations.multifin.normalized_score"), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES[ | |
"evaluations.multifin.normalized_score" | |
], | |
}, | |
{ | |
accessorKey: "evaluations.qa.normalized_score", | |
header: createHeaderCell("QA", COLUMN_TOOLTIPS.QA), | |
cell: ({ row, getValue }) => | |
createScoreCell(getValue, row, "evaluations.qa.normalized_score"), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES[ | |
"evaluations.qa.normalized_score" | |
], | |
}, | |
{ | |
accessorKey: "evaluations.fns.normalized_score", | |
header: createHeaderCell("FNS", COLUMN_TOOLTIPS.FNS), | |
cell: ({ row, getValue }) => | |
createScoreCell(getValue, row, "evaluations.fns.normalized_score"), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES[ | |
"evaluations.fns.normalized_score" | |
], | |
}, | |
{ | |
accessorKey: "evaluations.finnum.normalized_score", | |
header: createHeaderCell("FinNum", COLUMN_TOOLTIPS.FinNum), | |
cell: ({ row, getValue }) => | |
createScoreCell(getValue, row, "evaluations.finnum.normalized_score"), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES[ | |
"evaluations.finnum.normalized_score" | |
], | |
}, | |
{ | |
accessorKey: "evaluations.fintext.normalized_score", | |
header: createHeaderCell("FinText", COLUMN_TOOLTIPS.FinText), | |
cell: ({ row, getValue }) => | |
createScoreCell(getValue, row, "evaluations.fintext.normalized_score"), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES[ | |
"evaluations.fintext.normalized_score" | |
], | |
}, | |
]; | |
const optionalColumns = [ | |
{ | |
accessorKey: "model.architecture", | |
header: createHeaderCell("Architecture", COLUMN_TOOLTIPS.ARCHITECTURE), | |
accessorFn: (row) => row.model.architecture, | |
cell: ({ row }) => ( | |
<Tooltip title={row.original.model.architecture || "-"}> | |
<span>{row.original.model.architecture || "-"}</span> | |
</Tooltip> | |
), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["model.architecture"], | |
}, | |
{ | |
accessorKey: "model.precision", | |
header: createHeaderCell("Precision", COLUMN_TOOLTIPS.PRECISION), | |
accessorFn: (row) => row.model.precision, | |
cell: ({ row }) => ( | |
<Tooltip title={row.original.model.precision || "-"}> | |
<span>{row.original.model.precision || "-"}</span> | |
</Tooltip> | |
), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["model.precision"], | |
}, | |
{ | |
accessorKey: "metadata.params_billions", | |
header: createHeaderCell("Parameters", COLUMN_TOOLTIPS.PARAMETERS), | |
cell: ({ row }) => ( | |
<Box | |
sx={{ | |
display: "flex", | |
alignItems: "center", | |
justifyContent: "flex-start", | |
}} | |
> | |
<Typography variant="body2"> | |
{row.original.metadata.params_billions} | |
<span style={{ opacity: 0.6 }}>B</span> | |
</Typography> | |
</Box> | |
), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["metadata.params_billions"], | |
}, | |
{ | |
accessorKey: "metadata.hub_license", | |
header: createHeaderCell("License", COLUMN_TOOLTIPS.LICENSE), | |
cell: ({ row }) => ( | |
<Tooltip title={row.original.metadata.hub_license || "-"}> | |
<Typography | |
variant="body2" | |
sx={{ | |
overflow: "hidden", | |
textOverflow: "ellipsis", | |
whiteSpace: "nowrap", | |
}} | |
> | |
{row.original.metadata.hub_license || "-"} | |
</Typography> | |
</Tooltip> | |
), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["metadata.hub_license"], | |
}, | |
{ | |
accessorKey: "metadata.hub_hearts", | |
header: createHeaderCell( | |
"Hub ❤️", | |
"Number of likes received on the Hugging Face Hub" | |
), | |
cell: ({ row }) => ( | |
<Typography variant="body2"> | |
{row.original.metadata.hub_hearts} | |
</Typography> | |
), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["metadata.hub_hearts"], | |
}, | |
{ | |
accessorKey: "metadata.upload_date", | |
header: createHeaderCell( | |
"Upload Date", | |
"Date when the model was uploaded to the Hugging Face Hub" | |
), | |
cell: ({ row }) => ( | |
<Tooltip title={row.original.metadata.upload_date || "-"}> | |
<Typography | |
variant="body2" | |
sx={{ | |
overflow: "hidden", | |
textOverflow: "ellipsis", | |
whiteSpace: "nowrap", | |
}} | |
> | |
{row.original.metadata.upload_date || "-"} | |
</Typography> | |
</Tooltip> | |
), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["metadata.upload_date"], | |
}, | |
{ | |
accessorKey: "metadata.submission_date", | |
header: createHeaderCell( | |
"Submission Date", | |
"Date when the model was submitted to the leaderboard" | |
), | |
cell: ({ row }) => ( | |
<Tooltip title={row.original.metadata.submission_date || "-"}> | |
<Typography | |
variant="body2" | |
sx={{ | |
overflow: "hidden", | |
textOverflow: "ellipsis", | |
whiteSpace: "nowrap", | |
}} | |
> | |
{row.original.metadata.submission_date || "-"} | |
</Typography> | |
</Tooltip> | |
), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["metadata.submission_date"], | |
}, | |
{ | |
accessorKey: "metadata.generation", | |
header: createHeaderCell( | |
"Generation", | |
"The generation or version number of the model" | |
), | |
cell: ({ row }) => ( | |
<Typography variant="body2"> | |
{row.original.metadata.generation} | |
</Typography> | |
), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["metadata.generation"], | |
}, | |
{ | |
accessorKey: "metadata.base_model", | |
header: createHeaderCell( | |
"Base Model", | |
"The original model this model was derived from" | |
), | |
cell: ({ row }) => ( | |
<Tooltip title={row.original.metadata.base_model || "-"}> | |
<Typography | |
variant="body2" | |
sx={{ | |
overflow: "hidden", | |
textOverflow: "ellipsis", | |
whiteSpace: "nowrap", | |
}} | |
> | |
{row.original.metadata.base_model || "-"} | |
</Typography> | |
</Tooltip> | |
), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["metadata.base_model"], | |
}, | |
{ | |
accessorKey: "metadata.co2_cost", | |
header: createHeaderCell("CO₂ Cost", COLUMN_TOOLTIPS.CO2_COST), | |
cell: ({ row }) => ( | |
<Box | |
sx={{ | |
display: "flex", | |
alignItems: "center", | |
justifyContent: "flex-start", | |
}} | |
> | |
<Typography variant="body2"> | |
{row.original.metadata.co2_cost?.toFixed(2) || "0"} | |
<span style={{ opacity: 0.6 }}> kg</span> | |
</Typography> | |
</Box> | |
), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["metadata.co2_cost"], | |
}, | |
{ | |
accessorKey: "model.has_chat_template", | |
header: createHeaderCell( | |
"Chat Template", | |
"Whether this model has a chat template defined" | |
), | |
cell: ({ row }) => ( | |
<BooleanValue value={row.original.model.has_chat_template} /> | |
), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["model.has_chat_template"], | |
}, | |
{ | |
accessorKey: "features.is_not_available_on_hub", | |
header: createHeaderCell( | |
"Hub Availability", | |
"Whether the model is available on the Hugging Face Hub" | |
), | |
cell: ({ row }) => ( | |
<BooleanValue value={row.original.features.is_not_available_on_hub} /> | |
), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES[ | |
"features.is_not_available_on_hub" | |
], | |
}, | |
{ | |
accessorKey: "features.is_highlighted_by_maintainer", | |
header: createHeaderCell( | |
"Official Providers", | |
"Models that are officially provided and maintained by their original creators or organizations" | |
), | |
cell: ({ row }) => ( | |
<BooleanValue | |
value={row.original.features.is_highlighted_by_maintainer} | |
/> | |
), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES[ | |
"features.is_highlighted_by_maintainer" | |
], | |
enableSorting: true, | |
}, | |
{ | |
accessorKey: "features.is_moe", | |
header: createHeaderCell( | |
"Mixture of Experts", | |
"Whether this model uses a Mixture of Experts architecture" | |
), | |
cell: ({ row }) => <BooleanValue value={row.original.features.is_moe} />, | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["features.is_moe"], | |
}, | |
{ | |
accessorKey: "features.is_flagged", | |
header: createHeaderCell( | |
"Flag Status", | |
"Whether this model has been flagged for any issues" | |
), | |
cell: ({ row }) => ( | |
<BooleanValue value={row.original.features.is_flagged} /> | |
), | |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["features.is_flagged"], | |
}, | |
]; | |
// Utiliser directement columnVisibility | |
const finalColumns = [ | |
...baseColumns, | |
...evaluationColumns.filter((col) => columnVisibility[col.accessorKey]), | |
...optionalColumns | |
.filter((col) => columnVisibility[col.accessorKey]) | |
.sort((a, b) => { | |
// Définir l'ordre personnalisé des colonnes | |
const order = { | |
"model.architecture": 1, | |
"model.precision": 2, | |
"metadata.params_billions": 3, | |
"metadata.hub_license": 4, | |
"metadata.co2_cost": 5, | |
"metadata.hub_hearts": 6, | |
"metadata.upload_date": 7, | |
"metadata.submission_date": 8, | |
"metadata.generation": 9, | |
"metadata.base_model": 10, | |
"model.has_chat_template": 11, | |
"features.is_not_available_on_hub": 12, | |
"features.is_highlighted_by_maintainer": 13, | |
"features.is_moe": 14, | |
"features.is_flagged": 15, | |
}; | |
return order[a.accessorKey] - order[b.accessorKey]; | |
}), | |
]; | |
return finalColumns; | |
}; | |