mirror of
https://github.com/open-webui/open-webui
synced 2025-06-26 18:26:48 +00:00
feat: leaderboard
This commit is contained in:
@@ -1,27 +1,126 @@
|
||||
<script lang="ts">
|
||||
import { onMount, getContext } from 'svelte';
|
||||
import Tooltip from '../common/Tooltip.svelte';
|
||||
import Plus from '../icons/Plus.svelte';
|
||||
import Collapsible from '../common/Collapsible.svelte';
|
||||
import Switch from '../common/Switch.svelte';
|
||||
import ChevronUp from '../icons/ChevronUp.svelte';
|
||||
import ChevronDown from '../icons/ChevronDown.svelte';
|
||||
|
||||
import { models } from '$lib/stores';
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
let rankedModels = [];
|
||||
let loaded = false;
|
||||
let evaluationEnabled = true;
|
||||
|
||||
let showModels = false;
|
||||
|
||||
onMount(() => {
|
||||
loaded = true;
|
||||
|
||||
rankedModels = $models
|
||||
.filter((m) => m?.owned_by !== 'arena' && (m?.info?.meta?.hidden ?? false) !== true)
|
||||
.map((model) => {
|
||||
return {
|
||||
...model,
|
||||
rating: '-',
|
||||
stats: {
|
||||
won: '-',
|
||||
draw: '-',
|
||||
lost: '-'
|
||||
}
|
||||
};
|
||||
})
|
||||
.sort((a, b) => {
|
||||
// Handle sorting by rating ('-' goes to the end)
|
||||
if (a.rating === '-' && b.rating !== '-') return 1;
|
||||
if (b.rating === '-' && a.rating !== '-') return -1;
|
||||
|
||||
// If both have ratings (non '-'), sort by rating numerically (descending)
|
||||
if (a.rating !== '-' && b.rating !== '-') return b.rating - a.rating;
|
||||
|
||||
// If both ratings are '-', sort alphabetically (by 'name')
|
||||
return a.name.localeCompare(b.name);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if loaded}
|
||||
<div class="my-0.5 gap-1 flex flex-col md:flex-row justify-between">
|
||||
<div class="mt-0.5 mb-3 gap-1 flex flex-col md:flex-row justify-between">
|
||||
<div class="flex md:self-center text-lg font-medium px-0.5">
|
||||
{$i18n.t('Leaderboard')}
|
||||
|
||||
<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-50 dark:bg-gray-850" />
|
||||
|
||||
<span class="text-lg font-medium text-gray-500 dark:text-gray-300">{rankedModels.length}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="scrollbar-hidden relative whitespace-nowrap overflow-x-auto max-w-full rounded pt-0.5"
|
||||
>
|
||||
<table
|
||||
class="w-full text-sm text-left text-gray-500 dark:text-gray-400 table-auto max-w-full rounded"
|
||||
>
|
||||
<thead
|
||||
class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-850 dark:text-gray-400 -translate-y-0.5"
|
||||
>
|
||||
<tr class="">
|
||||
<th scope="col" class="px-3 py-1.5 cursor-pointer select-none">
|
||||
{$i18n.t('Model')}
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-1.5 text-right cursor-pointer select-none">
|
||||
{$i18n.t('Rating')}
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-1.5 text-right cursor-pointer select-none w-fit">
|
||||
{$i18n.t('Won')}
|
||||
</th>
|
||||
|
||||
<th scope="col" class="px-3 py-1.5 text-right cursor-pointer select-none w-fit">
|
||||
{$i18n.t('Draw')}
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-1.5 text-right cursor-pointer select-none w-fit">
|
||||
{$i18n.t('Lost')}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="">
|
||||
{#each rankedModels as model (model.id)}
|
||||
<tr class="bg-white dark:bg-gray-900 dark:border-gray-850 text-xs">
|
||||
<td class="px-3 py-1 flex flex-col justify-center">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex-shrink-0">
|
||||
<img
|
||||
src={model?.info?.meta?.profile_image_url ?? '/favicon.png'}
|
||||
alt={model.name}
|
||||
class="size-6 rounded-full object-cover shrink-0"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="font-medium text-gray-600 dark:text-gray-400 pr-4">
|
||||
{model.name}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-3 py-1 text-right font-medium text-gray-900 dark:text-white w-max">
|
||||
{model.rating}
|
||||
</td>
|
||||
|
||||
<td class=" px-3 py-1 text-right font-semibold text-green-500"> {model.stats.won} </td>
|
||||
|
||||
<td class=" px-3 py-1 text-right font-semibold">
|
||||
{model.stats.draw}
|
||||
</td>
|
||||
|
||||
<td class="px-3 py-1 text-right font-semibold text-red-500">
|
||||
{model.stats.lost}
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="pb-4"></div>
|
||||
|
||||
<div class="mt-0.5 mb-3 gap-1 flex flex-col md:flex-row justify-between">
|
||||
<div class="flex md:self-center text-lg font-medium px-0.5">
|
||||
{$i18n.t('Rating History')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pb-8"></div>
|
||||
{/if}
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-2 gap-1.5 flex justify-end">
|
||||
{#if $config?.features.enable_community_sharing}
|
||||
{#if $config?.features.enable_community_sharing && selectedModel}
|
||||
<button
|
||||
class=" self-center px-3.5 py-2 rounded-xl text-sm font-medium bg-gray-50 hover:bg-gray-100 text-gray-800 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-white transition"
|
||||
type="button"
|
||||
|
||||
@@ -228,7 +228,7 @@
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex md:self-center text-base font-medium px-0.5">
|
||||
{$i18n.t('Functions')}
|
||||
<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-200 dark:bg-gray-700" />
|
||||
<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-50 dark:bg-gray-850" />
|
||||
<span class="text-base font-medium text-gray-500 dark:text-gray-300"
|
||||
>{filteredItems.length}</span
|
||||
>
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex md:self-center text-base font-medium px-0.5">
|
||||
{$i18n.t('Knowledge')}
|
||||
<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-200 dark:bg-gray-700" />
|
||||
<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-50 dark:bg-gray-850" />
|
||||
<span class="text-base font-medium text-gray-500 dark:text-gray-300"
|
||||
>{filteredItems.length}</span
|
||||
>
|
||||
|
||||
@@ -348,7 +348,7 @@
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex md:self-center text-base font-medium px-0.5">
|
||||
{$i18n.t('Models')}
|
||||
<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-200 dark:bg-gray-850" />
|
||||
<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-50 dark:bg-gray-850" />
|
||||
<span class="text-base font-medium text-gray-500 dark:text-gray-300"
|
||||
>{filteredModels.length}</span
|
||||
>
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex md:self-center text-base font-medium px-0.5">
|
||||
{$i18n.t('Prompts')}
|
||||
<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-200 dark:bg-gray-700" />
|
||||
<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-50 dark:bg-gray-850" />
|
||||
<span class="text-base font-medium text-gray-500 dark:text-gray-300"
|
||||
>{filteredItems.length}</span
|
||||
>
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex md:self-center text-base font-medium px-0.5">
|
||||
{$i18n.t('Tools')}
|
||||
<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-200 dark:bg-gray-700" />
|
||||
<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-50 dark:bg-gray-850" />
|
||||
<span class="text-base font-medium text-gray-500 dark:text-gray-300"
|
||||
>{filteredItems.length}</span
|
||||
>
|
||||
|
||||
@@ -141,7 +141,8 @@
|
||||
<div class="mt-0.5 mb-3 gap-1 flex flex-col md:flex-row justify-between">
|
||||
<div class="flex md:self-center text-lg font-medium px-0.5">
|
||||
{$i18n.t('Users')}
|
||||
<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-200 dark:bg-gray-700" />
|
||||
<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-50 dark:bg-gray-850" />
|
||||
|
||||
<span class="text-lg font-medium text-gray-500 dark:text-gray-300">{users.length}</span>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user