mirror of
https://github.com/open-webui/open-webui
synced 2025-06-23 02:16:52 +00:00
Merge pull request #14944 from silentoplayz/sort-feedbacks
feat: Implement Client-Side Sorting for Feedback History Table
This commit is contained in:
commit
c2b4b76a90
@ -21,10 +21,16 @@
|
||||
import FeedbackModal from './FeedbackModal.svelte';
|
||||
import EllipsisHorizontal from '$lib/components/icons/EllipsisHorizontal.svelte';
|
||||
|
||||
import ChevronUp from '$lib/components/icons/ChevronUp.svelte';
|
||||
import ChevronDown from '$lib/components/icons/ChevronDown.svelte';
|
||||
|
||||
export let feedbacks = [];
|
||||
|
||||
let page = 1;
|
||||
$: paginatedFeedbacks = feedbacks.slice((page - 1) * 10, page * 10);
|
||||
$: paginatedFeedbacks = sortedFeedbacks.slice((page - 1) * 10, page * 10);
|
||||
|
||||
let orderBy: string = 'updated_at';
|
||||
let direction: 'asc' | 'desc' = 'desc';
|
||||
|
||||
type Feedback = {
|
||||
id: string;
|
||||
@ -49,6 +55,45 @@
|
||||
lost: number;
|
||||
};
|
||||
|
||||
function setSortKey(key: string) {
|
||||
if (orderBy === key) {
|
||||
direction = direction === 'asc' ? 'desc' : 'asc';
|
||||
} else {
|
||||
orderBy = key;
|
||||
if (key === 'user' || key === 'model_id') {
|
||||
direction = 'asc';
|
||||
} else {
|
||||
direction = 'desc';
|
||||
}
|
||||
}
|
||||
page = 1;
|
||||
}
|
||||
|
||||
$: sortedFeedbacks = [...feedbacks].sort((a, b) => {
|
||||
let aVal, bVal;
|
||||
|
||||
switch (orderBy) {
|
||||
case 'user':
|
||||
aVal = a.user?.name || '';
|
||||
bVal = b.user?.name || '';
|
||||
return direction === 'asc' ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal);
|
||||
case 'model_id':
|
||||
aVal = a.data.model_id || '';
|
||||
bVal = b.data.model_id || '';
|
||||
return direction === 'asc' ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal);
|
||||
case 'rating':
|
||||
aVal = a.data.rating;
|
||||
bVal = b.data.rating;
|
||||
return direction === 'asc' ? aVal - bVal : bVal - aVal;
|
||||
case 'updated_at':
|
||||
aVal = a.updated_at;
|
||||
bVal = b.updated_at;
|
||||
return direction === 'asc' ? aVal - bVal : bVal - aVal;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
let showFeedbackModal = false;
|
||||
let selectedFeedback = null;
|
||||
|
||||
@ -162,20 +207,96 @@
|
||||
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 text-right cursor-pointer select-none w-0">
|
||||
{$i18n.t('User')}
|
||||
<th
|
||||
scope="col"
|
||||
class="px-3 py-1.5 cursor-pointer select-none w-3"
|
||||
on:click={() => setSortKey('user')}
|
||||
>
|
||||
<div class="flex gap-1.5 items-center justify-end">
|
||||
{$i18n.t('User')}
|
||||
{#if orderBy === 'user'}
|
||||
<span class="font-normal">
|
||||
{#if direction === 'asc'}
|
||||
<ChevronUp className="size-2" />
|
||||
{:else}
|
||||
<ChevronDown className="size-2" />
|
||||
{/if}
|
||||
</span>
|
||||
{:else}
|
||||
<span class="invisible">
|
||||
<ChevronUp className="size-2" />
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
</th>
|
||||
|
||||
<th scope="col" class="px-3 pr-1.5 cursor-pointer select-none">
|
||||
{$i18n.t('Models')}
|
||||
<th
|
||||
scope="col"
|
||||
class="px-3 pr-1.5 cursor-pointer select-none"
|
||||
on:click={() => setSortKey('model_id')}
|
||||
>
|
||||
<div class="flex gap-1.5 items-center">
|
||||
{$i18n.t('Models')}
|
||||
{#if orderBy === 'model_id'}
|
||||
<span class="font-normal">
|
||||
{#if direction === 'asc'}
|
||||
<ChevronUp className="size-2" />
|
||||
{:else}
|
||||
<ChevronDown className="size-2" />
|
||||
{/if}
|
||||
</span>
|
||||
{:else}
|
||||
<span class="invisible">
|
||||
<ChevronUp className="size-2" />
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
</th>
|
||||
|
||||
<th scope="col" class="px-3 py-1.5 text-right cursor-pointer select-none w-fit">
|
||||
{$i18n.t('Result')}
|
||||
<th
|
||||
scope="col"
|
||||
class="px-3 py-1.5 text-right cursor-pointer select-none w-fit"
|
||||
on:click={() => setSortKey('rating')}
|
||||
>
|
||||
<div class="flex gap-1.5 items-center justify-end">
|
||||
{$i18n.t('Result')}
|
||||
{#if orderBy === 'rating'}
|
||||
<span class="font-normal">
|
||||
{#if direction === 'asc'}
|
||||
<ChevronUp className="size-2" />
|
||||
{:else}
|
||||
<ChevronDown className="size-2" />
|
||||
{/if}
|
||||
</span>
|
||||
{:else}
|
||||
<span class="invisible">
|
||||
<ChevronUp className="size-2" />
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
</th>
|
||||
|
||||
<th scope="col" class="px-3 py-1.5 text-right cursor-pointer select-none w-0">
|
||||
{$i18n.t('Updated At')}
|
||||
<th
|
||||
scope="col"
|
||||
class="px-3 py-1.5 text-right cursor-pointer select-none w-0"
|
||||
on:click={() => setSortKey('updated_at')}
|
||||
>
|
||||
<div class="flex gap-1.5 items-center justify-end">
|
||||
{$i18n.t('Updated At')}
|
||||
{#if orderBy === 'updated_at'}
|
||||
<span class="font-normal">
|
||||
{#if direction === 'asc'}
|
||||
<ChevronUp className="size-2" />
|
||||
{:else}
|
||||
<ChevronDown className="size-2" />
|
||||
{/if}
|
||||
</span>
|
||||
{:else}
|
||||
<span class="invisible">
|
||||
<ChevronUp className="size-2" />
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
</th>
|
||||
|
||||
<th scope="col" class="px-3 py-1.5 text-right cursor-pointer select-none w-0"> </th>
|
||||
|
Loading…
Reference in New Issue
Block a user