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 = () => ( ); 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 ? ( 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} ) : ( {fragment.text} ) )} ); }; 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 ; if (change < 0) return ; return ; }; return ( 1 ? "s" : "" } ${change > 0 ? "up" : "down"}`} arrow placement="right" > {getChangeIcon(change)} ); }; return ( {rank <= 3 ? ( <> {rank} ) : ( <> {rank} )} ); }; const getDetailsUrl = (modelName) => { const formattedName = modelName.replace("/", "__"); return `https://huggingface.co/datasets/TheFinAI/lm-eval-results-private`; }; const HeaderLabel = ({ label, tooltip, className, isSorted }) => ( {label} ); const InfoIcon = ({ tooltip }) => ( ); const createHeaderCell = (label, tooltip) => (header) => ( {tooltip && } ); const createModelHeader = (totalModels, officialProvidersCount = 0, isOfficialProviderActive = false) => ({ table }) => { return ( Model ); }; const BooleanValue = ({ value }) => { if (value === null || value === undefined) return -; return ( ({ 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), })} > ({ 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"} ); }; 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 }) => ( { 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 ? ( ) : ( )} ), 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 ( ); }, size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["rank"], }, { id: "model_type", accessorFn: (row) => row.model.type, header: createHeaderCell("Type"), sortingFn: typeColumnSort, cell: ({ row }) => ( {getModelTypeIcon(row.original.model.type)} ), 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 ( 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", }} > ); }, 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 ( {!hasNoValue && (scoreDisplay === "normalized" || isAverageColumn) && ( (theme.palette.mode === "light" ? 0.1 : 0.2), transition: "width 0.3s ease", zIndex: 0, }} /> )} {isAverageColumn && !hasNoValue && ( )} {hasNoValue ? ( "-" ) : ( <> {isAverageColumn ? ( <> {value.toFixed(2)} % ) : scoreDisplay === "normalized" ? ( <> {value.toFixed(2)} % ) : ( <>{rawValue.toFixed(2)} )} )} ); }; 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 }) => ( {row.original.model.architecture || "-"} ), size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["model.architecture"], }, { accessorKey: "model.precision", header: createHeaderCell("Precision", COLUMN_TOOLTIPS.PRECISION), accessorFn: (row) => row.model.precision, cell: ({ row }) => ( {row.original.model.precision || "-"} ), size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["model.precision"], }, { accessorKey: "metadata.params_billions", header: createHeaderCell("Parameters", COLUMN_TOOLTIPS.PARAMETERS), cell: ({ row }) => ( {row.original.metadata.params_billions} B ), size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["metadata.params_billions"], }, { accessorKey: "metadata.hub_license", header: createHeaderCell("License", COLUMN_TOOLTIPS.LICENSE), cell: ({ row }) => ( {row.original.metadata.hub_license || "-"} ), 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 }) => ( {row.original.metadata.hub_hearts} ), 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 }) => ( {row.original.metadata.upload_date || "-"} ), 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 }) => ( {row.original.metadata.submission_date || "-"} ), 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 }) => ( {row.original.metadata.generation} ), 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 }) => ( {row.original.metadata.base_model || "-"} ), size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["metadata.base_model"], }, { accessorKey: "metadata.co2_cost", header: createHeaderCell("CO₂ Cost", COLUMN_TOOLTIPS.CO2_COST), cell: ({ row }) => ( {row.original.metadata.co2_cost?.toFixed(2) || "0"} kg ), 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 }) => ( ), 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 }) => ( ), 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 }) => ( ), 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 }) => , 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 }) => ( ), 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; };