open-webui/src/lib/components/workspace/Models/Knowledge/Selector.svelte

122 lines
3.4 KiB
Svelte
Raw Normal View History

2024-06-10 00:17:35 +00:00
<script lang="ts">
import { DropdownMenu } from 'bits-ui';
2024-10-02 06:21:33 +00:00
import { onMount, getContext, createEventDispatcher } from 'svelte';
2024-06-10 00:17:35 +00:00
import { flyAndScale } from '$lib/utils/transitions';
2024-10-02 05:45:04 +00:00
import { knowledge } from '$lib/stores';
2024-06-10 00:17:35 +00:00
import Dropdown from '$lib/components/common/Dropdown.svelte';
const i18n = getContext('i18n');
2024-10-02 06:21:33 +00:00
const dispatch = createEventDispatcher();
2024-06-10 00:17:35 +00:00
export let onClose: Function = () => {};
let items = [];
onMount(() => {
2024-10-02 06:21:33 +00:00
let legacy_documents = $knowledge.filter((item) => item?.meta?.document);
let legacy_collections =
legacy_documents.length > 0
? [
{
name: 'All Documents',
legacy: true,
type: 'collection',
2024-10-02 13:19:09 +00:00
description: 'Deprecated (legacy collection), please create a new knowledge base.',
2024-10-02 06:21:33 +00:00
title: $i18n.t('All Documents'),
collection_names: legacy_documents.map((item) => item.id)
},
...legacy_documents
.reduce((a, item) => {
return [...new Set([...a, ...(item?.meta?.tags ?? []).map((tag) => tag.name)])];
}, [])
.map((tag) => ({
name: tag,
legacy: true,
type: 'collection',
2024-10-02 13:19:09 +00:00
description: 'Deprecated (legacy collection), please create a new knowledge base.',
2024-10-02 06:21:33 +00:00
collection_names: legacy_documents
.filter((item) => (item?.meta?.tags ?? []).map((tag) => tag.name).includes(tag))
.map((item) => item.id)
}))
]
: [];
2024-06-10 00:17:35 +00:00
2024-10-04 23:43:41 +00:00
items = [...$knowledge, ...legacy_collections].map((item) => {
return {
...item,
...(item?.legacy || item?.meta?.legacy || item?.meta?.document ? { legacy: true } : {})
};
});
2024-06-10 00:17:35 +00:00
});
</script>
<Dropdown
on:change={(e) => {
if (e.detail === false) {
onClose();
}
}}
>
<slot />
<div slot="content">
<DropdownMenu.Content
2024-10-02 06:21:33 +00:00
class="w-full max-w-80 rounded-lg px-1 py-1.5 border border-gray-300/30 dark:border-gray-700/50 z-50 bg-white dark:bg-gray-850 dark:text-white shadow-lg"
2024-06-10 00:17:35 +00:00
sideOffset={8}
side="bottom"
2024-06-10 00:55:23 +00:00
align="start"
2024-06-10 00:17:35 +00:00
transition={flyAndScale}
>
<div class="max-h-[10rem] overflow-y-scroll">
2024-06-10 00:55:23 +00:00
{#if items.length === 0}
<div class="text-center text-sm text-gray-500 dark:text-gray-400">
2024-10-02 06:21:33 +00:00
{$i18n.t('No knowledge found')}
2024-06-10 00:55:23 +00:00
</div>
{:else}
{#each items as item}
<DropdownMenu.Item
class="flex gap-2.5 items-center px-3 py-2 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
on:click={() => {
2024-10-02 06:21:33 +00:00
dispatch('select', item);
2024-06-10 00:55:23 +00:00
}}
>
<div class="flex items-center">
<div class="flex flex-col">
2024-10-02 06:21:33 +00:00
<div class=" w-fit mb-0.5">
{#if item.legacy}
<div
class="bg-gray-500/20 text-gray-700 dark:text-gray-200 rounded uppercase text-xs font-bold px-1"
>
Legacy
</div>
{:else if item?.meta?.document}
<div
class="bg-gray-500/20 text-gray-700 dark:text-gray-200 rounded uppercase text-xs font-bold px-1"
>
Document
</div>
{:else}
<div
class="bg-green-500/20 text-green-700 dark:text-green-200 rounded uppercase text-xs font-bold px-1"
>
Collection
</div>
{/if}
2024-06-10 00:55:23 +00:00
</div>
2024-06-10 00:17:35 +00:00
2024-06-10 00:55:23 +00:00
<div class="line-clamp-1 font-medium pr-0.5">
{item.name}
</div>
2024-06-10 00:17:35 +00:00
</div>
</div>
2024-06-10 00:55:23 +00:00
</DropdownMenu.Item>
{/each}
{/if}
2024-06-10 00:17:35 +00:00
</div>
</DropdownMenu.Content>
</div>
</Dropdown>