enh: model workspace tag filter view

This commit is contained in:
Timothy Jaeryang Baek 2025-07-08 23:05:39 +04:00
parent 0765f6c230
commit f69db54b7e

View file

@ -42,9 +42,13 @@
let importFiles;
let modelsImportInputElement: HTMLInputElement;
let tagsContainerElement: HTMLDivElement;
let loaded = false;
let models = [];
let tags = [];
let selectedTag = '';
let filteredModels = [];
let selectedModel = null;
@ -55,12 +59,14 @@
$: if (models) {
filteredModels = models.filter((m) => {
if (query === '') return true;
if (query === '' && selectedTag === '') return true;
const lowerQuery = query.toLowerCase();
return (
(m.name || '').toLowerCase().includes(lowerQuery) ||
(m.user?.name || '').toLowerCase().includes(lowerQuery) || // Search by user name
(m.user?.email || '').toLowerCase().includes(lowerQuery) // Search by user email
((m.name || '').toLowerCase().includes(lowerQuery) ||
(m.user?.name || '').toLowerCase().includes(lowerQuery) || // Search by user name
(m.user?.email || '').toLowerCase().includes(lowerQuery)) && // Search by user email
(selectedTag === '' ||
m?.meta?.tags?.some((tag) => tag.name.toLowerCase() === selectedTag.toLowerCase()))
);
});
}
@ -171,6 +177,16 @@
let groups = await getGroups(localStorage.token);
group_ids = groups.map((group) => group.id);
if (models) {
tags = models
.filter((model) => !(model?.meta?.hidden ?? false))
.flatMap((model) => model?.meta?.tags ?? [])
.map((tag) => tag.name);
// Remove duplicates and sort
tags = Array.from(new Set(tags)).sort((a, b) => a.localeCompare(b));
}
loaded = true;
const onKeyDown = (event) => {
@ -215,7 +231,7 @@
}}
/>
<div class="flex flex-col gap-1 my-1.5">
<div class="flex flex-col gap-1 mt-1.5">
<div class="flex justify-between items-center">
<div class="flex items-center md:self-center text-xl font-medium px-0.5">
{$i18n.t('Models')}
@ -262,6 +278,46 @@
</div>
</div>
{#if tags.length > 0}
<div
class=" flex w-full bg-transparent overflow-x-auto scrollbar-none"
on:wheel={(e) => {
if (e.deltaY !== 0) {
e.preventDefault();
e.currentTarget.scrollLeft += e.deltaY;
}
}}
>
<div
class="flex gap-1 w-fit text-center text-sm font-medium rounded-full"
bind:this={tagsContainerElement}
>
<button
class="min-w-fit outline-none p-1.5 {selectedTag === ''
? ''
: 'text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition capitalize"
on:click={() => {
selectedTag = '';
}}
>
{$i18n.t('All')}
</button>
{#each tags as tag}
<button
class="min-w-fit outline-none p-1.5 {selectedTag === tag
? ''
: 'text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition capitalize"
on:click={() => {
selectedTag = tag;
}}
>
{tag}
</button>
{/each}
</div>
</div>
{/if}
<div class=" my-2 mb-5 gap-2 grid lg:grid-cols-2 xl:grid-cols-3" id="model-list">
{#each filteredModels as model (model.id)}
<div