Prechádzať zdrojové kódy

enh: model workspace tag filter view

Timothy Jaeryang Baek 3 mesiacov pred
rodič
commit
f69db54b7e
1 zmenil súbory, kde vykonal 61 pridanie a 5 odobranie
  1. 61 5
      src/lib/components/workspace/Models.svelte

+ 61 - 5
src/lib/components/workspace/Models.svelte

@@ -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