mirror of
				https://github.com/open-webui/open-webui
				synced 2025-06-26 18:26:48 +00:00 
			
		
		
		
	enh: model selector tag filter
This commit is contained in:
		
							parent
							
								
									811e1f92b1
								
							
						
					
					
						commit
						5f89c1b137
					
				| @ -52,12 +52,17 @@ | ||||
| 	export let className = 'w-[32rem]'; | ||||
| 	export let triggerClassName = 'text-lg'; | ||||
| 
 | ||||
| 	let tagsContainerElement; | ||||
| 
 | ||||
| 	let show = false; | ||||
| 	let tags = []; | ||||
| 
 | ||||
| 	let selectedModel = ''; | ||||
| 	$: selectedModel = items.find((item) => item.value === value) ?? ''; | ||||
| 
 | ||||
| 	let searchValue = ''; | ||||
| 	let selectedTag = ''; | ||||
| 
 | ||||
| 	let ollamaVersion = null; | ||||
| 
 | ||||
| 	let selectedModelIdx = 0; | ||||
| @ -79,10 +84,23 @@ | ||||
| 	); | ||||
| 
 | ||||
| 	$: filteredItems = searchValue | ||||
| 		? fuse.search(searchValue).map((e) => { | ||||
| 				return e.item; | ||||
| 			}) | ||||
| 		: items; | ||||
| 		? fuse | ||||
| 				.search(searchValue) | ||||
| 				.map((e) => { | ||||
| 					return e.item; | ||||
| 				}) | ||||
| 				.filter((item) => { | ||||
| 					if (selectedTag === '') { | ||||
| 						return true; | ||||
| 					} | ||||
| 					return item.model?.info?.meta?.tags?.map((tag) => tag.name).includes(selectedTag); | ||||
| 				}) | ||||
| 		: items.filter((item) => { | ||||
| 				if (selectedTag === '') { | ||||
| 					return true; | ||||
| 				} | ||||
| 				return item.model?.info?.meta?.tags?.map((tag) => tag.name).includes(selectedTag); | ||||
| 			}); | ||||
| 
 | ||||
| 	const pullModelHandler = async () => { | ||||
| 		const sanitizedModelTag = searchValue.trim().replace(/^ollama\s+(run|pull)\s+/, ''); | ||||
| @ -214,6 +232,11 @@ | ||||
| 
 | ||||
| 	onMount(async () => { | ||||
| 		ollamaVersion = await getOllamaVersion(localStorage.token).catch((error) => false); | ||||
| 
 | ||||
| 		if (items) { | ||||
| 			tags = items.flatMap((item) => item.model?.info?.meta?.tags ?? []); | ||||
| 			tags = [...new Set(tags)].map((tag) => tag.name).sort(); | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	const cancelModelPullHandler = async (model: string) => { | ||||
| @ -298,10 +321,43 @@ | ||||
| 					/> | ||||
| 				</div> | ||||
| 
 | ||||
| 				<hr class="border-gray-100 dark:border-gray-850" /> | ||||
| 				<hr class="border-gray-100 dark:border-gray-800" /> | ||||
| 			{/if} | ||||
| 
 | ||||
| 			<div class="px-3 my-2 max-h-64 overflow-y-auto scrollbar-hidden group"> | ||||
| 			<div class="px-3 my-2 max-h-64 overflow-y-auto scrollbar-hidden group relative"> | ||||
| 				{#if tags} | ||||
| 					<div class=" flex w-full sticky"> | ||||
| 						<div | ||||
| 							class="flex gap-1 scrollbar-none overflow-x-auto w-fit text-center text-sm font-medium rounded-full bg-transparent px-1.5 pb-0.5" | ||||
| 							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" | ||||
| 								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" | ||||
| 									on:click={() => { | ||||
| 										selectedTag = tag; | ||||
| 									}} | ||||
| 								> | ||||
| 									{tag} | ||||
| 								</button> | ||||
| 							{/each} | ||||
| 						</div> | ||||
| 					</div> | ||||
| 				{/if} | ||||
| 
 | ||||
| 				{#each filteredItems as item, index} | ||||
| 					<button | ||||
| 						aria-label="model-item" | ||||
| @ -441,11 +497,13 @@ | ||||
| 								{/if} | ||||
| 
 | ||||
| 								{#if !$mobile && (item?.model?.info?.meta?.tags ?? []).length > 0} | ||||
| 									<div class="flex gap-0.5 self-center items-center h-full translate-y-[0.5px]"> | ||||
| 									<div | ||||
| 										class="flex gap-0.5 self-center items-center h-full translate-y-[0.5px] overflow-x-auto scrollbar-none" | ||||
| 									> | ||||
| 										{#each item.model?.info?.meta.tags as tag} | ||||
| 											<Tooltip content={tag.name}> | ||||
| 											<Tooltip content={tag.name} className="flex-shrink-0"> | ||||
| 												<div | ||||
| 													class=" text-xs font-bold px-1 rounded-sm uppercase line-clamp-1 bg-gray-500/20 text-gray-700 dark:text-gray-200" | ||||
| 													class=" text-xs font-bold px-1 rounded-sm uppercase bg-gray-500/20 text-gray-700 dark:text-gray-200" | ||||
| 												> | ||||
| 													{tag.name} | ||||
| 												</div> | ||||
| @ -575,7 +633,7 @@ | ||||
| 			</div> | ||||
| 
 | ||||
| 			{#if showTemporaryChatControl} | ||||
| 				<hr class="border-gray-100 dark:border-gray-850" /> | ||||
| 				<hr class="border-gray-100 dark:border-gray-800" /> | ||||
| 
 | ||||
| 				<div class="flex items-center mx-2 my-2"> | ||||
| 					<button | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user