|
import { useMemo } from "react"; |
|
import { |
|
looksLikeRegex, |
|
parseSearchQuery, |
|
getValueByPath, |
|
} from "../utils/searchUtils"; |
|
|
|
|
|
export const useAverageRange = (data) => { |
|
return useMemo(() => { |
|
const averages = data.map((item) => item.model.average_score); |
|
return { |
|
minAverage: Math.min(...averages), |
|
maxAverage: Math.max(...averages), |
|
}; |
|
}, [data]); |
|
}; |
|
|
|
|
|
export const useColorGenerator = (minAverage, maxAverage) => { |
|
return useMemo(() => { |
|
const colorCache = new Map(); |
|
return (value) => { |
|
const cached = colorCache.get(value); |
|
if (cached) return cached; |
|
|
|
const normalizedValue = |
|
(value - minAverage) / (maxAverage - minAverage); |
|
const red = Math.round(255 * (1 - normalizedValue) * 1); |
|
const green = Math.round(255 * normalizedValue) * 1; |
|
|
|
const color = `rgba(${red}, 0, ${green}, 1)`; |
|
colorCache.set(value, color); |
|
return color; |
|
}; |
|
}, [minAverage, maxAverage]); |
|
}; |
|
|
|
|
|
export const useProcessedData = (data, averageMode, visibleColumns) => { |
|
return useMemo(() => { |
|
let processed = data.map((item) => { |
|
const evaluationScores = Object.entries(item.evaluations) |
|
.filter(([key]) => { |
|
if (averageMode === "all") return true; |
|
return visibleColumns.includes( |
|
`evaluations.${key}.normalized_score` |
|
); |
|
}) |
|
.flatMap(([, value]) => |
|
Object.entries(value.normalized_score || {}) |
|
.filter(([metric]) => metric !== "bert") |
|
.map(([, val]) => val) |
|
); |
|
|
|
|
|
const standardizedFeatures = { |
|
...item.features, |
|
is_moe: Boolean(item.features.is_moe), |
|
is_flagged: Boolean(item.features.is_flagged), |
|
is_highlighted_by_maintainer: Boolean( |
|
item.features.is_highlighted_by_maintainer |
|
), |
|
is_merged: Boolean(item.features.is_merged), |
|
is_not_available_on_hub: Boolean( |
|
item.features.is_not_available_on_hub |
|
), |
|
}; |
|
|
|
return { |
|
...item, |
|
features: standardizedFeatures, |
|
model: { |
|
...item.model, |
|
has_chat_template: Boolean(item.model.has_chat_template), |
|
average_score: item.model.average_score, |
|
}, |
|
}; |
|
}); |
|
|
|
processed.sort((a, b) => { |
|
if ( |
|
a.model.average_score === null && |
|
b.model.average_score === null |
|
) |
|
return 0; |
|
if (a.model.average_score === null) return 1; |
|
if (b.model.average_score === null) return -1; |
|
return b.model.average_score - a.model.average_score; |
|
}); |
|
|
|
return processed.map((item, index) => ({ |
|
...item, |
|
static_rank: index + 1, |
|
})); |
|
}, [data, averageMode, visibleColumns]); |
|
}; |
|
|
|
|
|
export const useFilteredData = ( |
|
processedData, |
|
selectedPrecisions, |
|
selectedTypes, |
|
paramsRange, |
|
searchValue, |
|
selectedBooleanFilters, |
|
rankingMode, |
|
pinnedModels = [], |
|
isOfficialProviderActive = false |
|
) => { |
|
return useMemo(() => { |
|
const pinnedData = processedData.filter((row) => { |
|
return pinnedModels.includes(row.id); |
|
}); |
|
const unpinnedData = processedData.filter((row) => { |
|
return !pinnedModels.includes(row.id); |
|
}); |
|
|
|
let filteredUnpinned = unpinnedData; |
|
|
|
|
|
if (isOfficialProviderActive) { |
|
filteredUnpinned = filteredUnpinned.filter( |
|
(row) => |
|
row.features?.is_highlighted_by_maintainer || |
|
row.metadata?.is_highlighted_by_maintainer |
|
); |
|
} |
|
|
|
|
|
if (selectedPrecisions.length > 0) { |
|
filteredUnpinned = filteredUnpinned.filter((row) => |
|
selectedPrecisions.includes(row.model.precision) |
|
); |
|
} |
|
|
|
|
|
if (selectedTypes.length > 0) { |
|
filteredUnpinned = filteredUnpinned.filter((row) => { |
|
const modelType = row.model.type?.toLowerCase().trim(); |
|
return selectedTypes.some((type) => modelType?.includes(type)); |
|
}); |
|
} |
|
|
|
|
|
filteredUnpinned = filteredUnpinned.filter((row) => { |
|
|
|
if (paramsRange[0] === -1 && paramsRange[1] === 140) return true; |
|
|
|
const params = |
|
row.metadata?.params_billions || row.features?.params_billions; |
|
if (params === undefined || params === null) return false; |
|
return params >= paramsRange[0] && params < paramsRange[1]; |
|
}); |
|
|
|
|
|
if (searchValue) { |
|
const searchQueries = searchValue |
|
.split(";") |
|
.map((q) => q.trim()) |
|
.filter((q) => q); |
|
if (searchQueries.length > 0) { |
|
filteredUnpinned = filteredUnpinned.filter((row) => { |
|
return searchQueries.some((query) => { |
|
const { specialSearches, textSearch } = |
|
parseSearchQuery(query); |
|
|
|
const specialSearchMatch = specialSearches.every( |
|
({ field, value }) => { |
|
const fieldValue = getValueByPath(row, field) |
|
?.toString() |
|
.toLowerCase(); |
|
return fieldValue?.includes( |
|
value.toLowerCase() |
|
); |
|
} |
|
); |
|
|
|
if (!specialSearchMatch) return false; |
|
if (!textSearch) return true; |
|
|
|
const modelName = row.model.name.toLowerCase(); |
|
const searchLower = textSearch.toLowerCase(); |
|
|
|
if (looksLikeRegex(textSearch)) { |
|
try { |
|
const regex = new RegExp(textSearch, "i"); |
|
return regex.test(modelName); |
|
} catch (e) { |
|
return modelName.includes(searchLower); |
|
} |
|
} else { |
|
return modelName.includes(searchLower); |
|
} |
|
}); |
|
}); |
|
} |
|
} |
|
|
|
|
|
if (selectedBooleanFilters.length > 0) { |
|
filteredUnpinned = filteredUnpinned.filter((row) => { |
|
return selectedBooleanFilters.every((filter) => { |
|
const filterValue = |
|
typeof filter === "object" ? filter.value : filter; |
|
|
|
|
|
if (filterValue === "is_highlighted_by_maintainer") { |
|
return row.features[filterValue]; |
|
} |
|
|
|
|
|
if (filterValue === "is_not_available_on_hub") { |
|
return row.features[filterValue]; |
|
} |
|
|
|
return !row.features[filterValue]; |
|
}); |
|
}); |
|
} |
|
|
|
|
|
const orderedPinnedData = pinnedModels |
|
.map((pinnedModelId) => |
|
pinnedData.find((item) => item.id === pinnedModelId) |
|
) |
|
.filter(Boolean); |
|
|
|
|
|
const allFilteredData = [...filteredUnpinned, ...orderedPinnedData]; |
|
|
|
|
|
const sortedByScore = [...allFilteredData].sort((a, b) => { |
|
|
|
if (a.model.average_score !== b.model.average_score) { |
|
if ( |
|
a.model.average_score === null && |
|
b.model.average_score === null |
|
) |
|
return 0; |
|
if (a.model.average_score === null) return 1; |
|
if (b.model.average_score === null) return -1; |
|
return b.model.average_score - a.model.average_score; |
|
} |
|
|
|
|
|
if (a.model.name === b.model.name) { |
|
|
|
const dateA = new Date(a.metadata?.submission_date || 0); |
|
const dateB = new Date(b.metadata?.submission_date || 0); |
|
return dateB - dateA; |
|
} |
|
|
|
|
|
return a.model.name.localeCompare(b.model.name); |
|
}); |
|
|
|
|
|
const dynamicRankMap = new Map(); |
|
sortedByScore.forEach((item, index) => { |
|
dynamicRankMap.set(item.id, index + 1); |
|
}); |
|
|
|
|
|
const finalData = [...orderedPinnedData, ...filteredUnpinned].map( |
|
(item) => { |
|
return { |
|
...item, |
|
dynamic_rank: dynamicRankMap.get(item.id), |
|
rank: item.isPinned |
|
? pinnedModels.indexOf(item.id) + 1 |
|
: rankingMode === "static" |
|
? item.static_rank |
|
: dynamicRankMap.get(item.id), |
|
isPinned: pinnedModels.includes(item.id), |
|
}; |
|
} |
|
); |
|
|
|
return finalData; |
|
}, [ |
|
processedData, |
|
selectedPrecisions, |
|
selectedTypes, |
|
paramsRange, |
|
searchValue, |
|
selectedBooleanFilters, |
|
rankingMode, |
|
pinnedModels, |
|
isOfficialProviderActive, |
|
]); |
|
}; |
|
|
|
|
|
export const useColumnVisibility = (visibleColumns = []) => { |
|
|
|
const columnVisibility = useMemo(() => { |
|
|
|
const safeVisibleColumns = Array.isArray(visibleColumns) |
|
? visibleColumns |
|
: []; |
|
|
|
const visibility = {}; |
|
try { |
|
safeVisibleColumns.forEach((columnKey) => { |
|
if (typeof columnKey === "string") { |
|
visibility[columnKey] = true; |
|
} |
|
}); |
|
} catch (error) { |
|
console.warn("Error in useColumnVisibility:", error); |
|
} |
|
return visibility; |
|
}, [visibleColumns]); |
|
|
|
return columnVisibility; |
|
}; |
|
|