diff --git a/src/lib/components/workspace/Models.svelte b/src/lib/components/workspace/Models.svelte index 19bad070b2..24a8eff919 100644 --- a/src/lib/components/workspace/Models.svelte +++ b/src/lib/components/workspace/Models.svelte @@ -24,6 +24,8 @@ import { getModels } from '$lib/apis'; import { getGroups } from '$lib/apis/groups'; + import { capitalizeFirstLetter, copyToClipboard } from '$lib/utils'; + import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte'; import ModelMenu from './Models/ModelMenu.svelte'; import ModelDeleteConfirmDialog from '../common/ConfirmDialog.svelte'; @@ -34,10 +36,11 @@ import ChevronRight from '../icons/ChevronRight.svelte'; import Switch from '../common/Switch.svelte'; import Spinner from '../common/Spinner.svelte'; - import { capitalizeFirstLetter, copyToClipboard } from '$lib/utils'; import XMark from '../icons/XMark.svelte'; import EyeSlash from '../icons/EyeSlash.svelte'; import Eye from '../icons/Eye.svelte'; + import ViewSelector from './common/ViewSelector.svelte'; + import TagSelector from './common/TagSelector.svelte'; let shiftKey = false; @@ -49,6 +52,8 @@ let models = []; let tags = []; + + let viewOption = ''; let selectedTag = ''; let filteredModels = []; @@ -58,22 +63,28 @@ let group_ids = []; - $: if (models) { + $: if (models && query !== undefined && selectedTag !== undefined && viewOption !== undefined) { + setFilteredModels(); + } + + const setFilteredModels = async () => { filteredModels = models.filter((m) => { - if (query === '' && selectedTag === '') return true; + if (query === '' && selectedTag === '' && viewOption === '') 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 (selectedTag === '' || - m?.meta?.tags?.some((tag) => tag.name.toLowerCase() === selectedTag.toLowerCase())) + m?.meta?.tags?.some((tag) => tag.name.toLowerCase() === selectedTag.toLowerCase())) && + (viewOption === '' || + (viewOption === 'created' && m.user_id === $user?.id) || + (viewOption === 'shared' && m.user_id !== $user?.id)) ); }); - } + }; let query = ''; - const deleteModelHandler = async (model) => { const res = await deleteModelById(localStorage.token, model.id).catch((e) => { toast.error(`${e}`); @@ -173,11 +184,7 @@ saveAs(blob, `${model.id}-${Date.now()}.json`); }; - onMount(async () => { - models = await getWorkspaceModels(localStorage.token); - let groups = await getGroups(localStorage.token); - group_ids = groups.map((group) => group.id); - + const setTags = () => { if (models) { tags = models .filter((model) => !(model?.meta?.hidden ?? false)) @@ -187,7 +194,16 @@ // Remove duplicates and sort tags = Array.from(new Set(tags)).sort((a, b) => a.localeCompare(b)); } + }; + onMount(async () => { + viewOption = localStorage.workspaceViewOption ?? ''; + + models = await getWorkspaceModels(localStorage.token); + let groups = await getGroups(localStorage.token); + group_ids = groups.map((group) => group.id); + + setTags(); loaded = true; const onKeyDown = (event) => { @@ -232,7 +248,7 @@ }} /> -
+
- {#if tags.length > 0} +
{ + if (e.deltaY !== 0) { + e.preventDefault(); + e.currentTarget.scrollLeft += e.deltaY; + } + }} + >
{ - if (e.deltaY !== 0) { - e.preventDefault(); - e.currentTarget.scrollLeft += e.deltaY; - } - }} + class="flex gap-1 w-fit text-center text-sm rounded-full bg-transparent px-1.5 whitespace-nowrap" + bind:this={tagsContainerElement} > -
- + { + localStorage.workspaceViewOption = value; - {#each tags as tag} - - - - {/each} -
+ await tick(); + setTags(); + }} + /> + + {#if (tags ?? []).length > 0} + { + return { value: tag, label: tag }; + })} + /> + {/if}
- {/if} +
+
{#each filteredModels as model (model.id)}
+ import { Select } from 'bits-ui'; + import { getContext } from 'svelte'; + + import ChevronDown from '$lib/components/icons/ChevronDown.svelte'; + import Check from '$lib/components/icons/Check.svelte'; + import XMark from '$lib/components/icons/XMark.svelte'; + + const i18n = getContext('i18n'); + + export let value = ''; + export let placeholder = $i18n.t('Tag'); + export let onChange: (value: string) => void = () => {}; + + export let items = []; + + + item.value === value) : null} + {items} + onSelectedChange={(selectedItem) => { + value = selectedItem.value; + onChange(value); + }} +> + + + + {#if value} + + {:else} + + {/if} + + + + + {#each items as item} + + {item.label.length > 32 ? `${item.label.slice(0, 32)}...` : item.label} + + {#if value === item.value} +
+ +
+ {/if} +
+ {/each} +
+
+
+ + diff --git a/src/lib/components/workspace/common/ViewSelector.svelte b/src/lib/components/workspace/common/ViewSelector.svelte new file mode 100644 index 0000000000..a2f8f538a6 --- /dev/null +++ b/src/lib/components/workspace/common/ViewSelector.svelte @@ -0,0 +1,96 @@ + + + item.value === value)} + {items} + onSelectedChange={(selectedItem) => { + value = selectedItem.value; + onChange(value); + }} +> + + + + + + + + {#each items as item} + + {item.label} + + {#if value === item.value} +
+ +
+ {/if} +
+ {/each} +
+
+
+ +