refac: knowledge selector

This commit is contained in:
Timothy Jaeryang Baek 2025-07-11 01:41:40 +04:00
parent 84bf1892bb
commit 249b12e44f
2 changed files with 111 additions and 38 deletions

View file

@ -7,6 +7,8 @@
import { knowledge } from '$lib/stores'; import { knowledge } from '$lib/stores';
import Dropdown from '$lib/components/common/Dropdown.svelte'; import Dropdown from '$lib/components/common/Dropdown.svelte';
import Search from '$lib/components/icons/Search.svelte'; import Search from '$lib/components/icons/Search.svelte';
import { getNoteList } from '$lib/apis/notes';
import dayjs from 'dayjs';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
@ -27,8 +29,35 @@
: items; : items;
} }
onMount(() => { const decodeString = (str: string) => {
let legacy_documents = $knowledge.filter((item) => item?.meta?.document); try {
return decodeURIComponent(str);
} catch (e) {
return str;
}
};
onMount(async () => {
let notes = await getNoteList(localStorage.token).catch(() => {
return [];
});
notes = notes.map((note) => {
return {
...note,
type: 'note',
name: note.title,
description: dayjs(note.updated_at / 1000000).fromNow()
};
});
let legacy_documents = $knowledge
.filter((item) => item?.meta?.document)
.map((item) => ({
...item,
type: 'file'
}));
let legacy_collections = let legacy_collections =
legacy_documents.length > 0 legacy_documents.length > 0
? [ ? [
@ -37,7 +66,6 @@
legacy: true, legacy: true,
type: 'collection', type: 'collection',
description: 'Deprecated (legacy collection), please create a new knowledge base.', description: 'Deprecated (legacy collection), please create a new knowledge base.',
title: $i18n.t('All Documents'), title: $i18n.t('All Documents'),
collection_names: legacy_documents.map((item) => item.id) collection_names: legacy_documents.map((item) => item.id)
}, },
@ -51,7 +79,6 @@
legacy: true, legacy: true,
type: 'collection', type: 'collection',
description: 'Deprecated (legacy collection), please create a new knowledge base.', description: 'Deprecated (legacy collection), please create a new knowledge base.',
collection_names: legacy_documents collection_names: legacy_documents
.filter((item) => (item?.meta?.tags ?? []).map((tag) => tag.name).includes(tag)) .filter((item) => (item?.meta?.tags ?? []).map((tag) => tag.name).includes(tag))
.map((item) => item.id) .map((item) => item.id)
@ -59,11 +86,46 @@
] ]
: []; : [];
items = [...$knowledge, ...legacy_collections].map((item) => { let collections = $knowledge
.filter((item) => !item?.meta?.document)
.map((item) => ({
...item,
type: 'collection'
}));
let collection_files =
$knowledge.length > 0
? [
...$knowledge
.reduce((a, item) => {
return [
...new Set([
...a,
...(item?.files ?? []).map((file) => ({
...file,
collection: { name: item.name, description: item.description } // DO NOT REMOVE, USED IN FILE DESCRIPTION/ATTACHMENT
}))
])
];
}, [])
.map((file) => ({
...file,
name: file?.meta?.name,
description: `${file?.collection?.name} - ${file?.collection?.description}`,
type: 'file'
}))
]
: [];
items = [
...notes,
...collections,
...collection_files,
...legacy_collections,
...legacy_documents
].map((item) => {
return { return {
...item, ...item,
...(item?.legacy || item?.meta?.legacy || item?.meta?.document ? { legacy: true } : {}), ...(item?.legacy || item?.meta?.legacy || item?.meta?.document ? { legacy: true } : {})
type: item?.meta?.document ? 'document' : 'collection'
}; };
}); });
@ -85,7 +147,7 @@
<div slot="content"> <div slot="content">
<DropdownMenu.Content <DropdownMenu.Content
class="w-full max-w-80 rounded-xl 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" class="w-full max-w-96 rounded-xl 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"
sideOffset={8} sideOffset={8}
side="bottom" side="bottom"
align="start" align="start"
@ -104,7 +166,7 @@
</div> </div>
</div> </div>
<div class="max-h-48 overflow-y-scroll"> <div class="max-h-56 overflow-y-scroll">
{#if filteredItems.length === 0} {#if filteredItems.length === 0}
<div class="text-center text-sm text-gray-500 dark:text-gray-400"> <div class="text-center text-sm text-gray-500 dark:text-gray-400">
{$i18n.t('No knowledge found')} {$i18n.t('No knowledge found')}
@ -117,34 +179,48 @@
dispatch('select', item); dispatch('select', item);
}} }}
> >
<div class="flex items-center"> <div>
<div class="flex flex-col"> <div class=" font-medium text-black dark:text-gray-100 flex items-center gap-1">
<div class=" w-fit mb-0.5"> {#if item.legacy}
{#if item.legacy} <div
<div class="bg-gray-500/20 text-gray-700 dark:text-gray-200 rounded-sm uppercase text-xs font-bold px-1 shrink-0"
class="bg-gray-500/20 text-gray-700 dark:text-gray-200 rounded-sm uppercase text-xs font-bold px-1" >
> Legacy
Legacy </div>
</div> {:else if item?.meta?.document}
{:else if item?.meta?.document} <div
<div class="bg-gray-500/20 text-gray-700 dark:text-gray-200 rounded-sm uppercase text-xs font-bold px-1 shrink-0"
class="bg-gray-500/20 text-gray-700 dark:text-gray-200 rounded-sm uppercase text-xs font-bold px-1" >
> Document
Document </div>
</div> {:else if item?.type === 'file'}
{:else} <div
<div class="bg-gray-500/20 text-gray-700 dark:text-gray-200 rounded-sm uppercase text-xs font-bold px-1 shrink-0"
class="bg-green-500/20 text-green-700 dark:text-green-200 rounded-sm uppercase text-xs font-bold px-1" >
> File
Collection </div>
</div> {:else if item?.type === 'note'}
{/if} <div
</div> class="bg-blue-500/20 text-blue-700 dark:text-blue-200 rounded-sm uppercase text-xs font-bold px-1 shrink-0"
>
Note
</div>
{:else}
<div
class="bg-green-500/20 text-green-700 dark:text-green-200 rounded-sm uppercase text-xs font-bold px-1 shrink-0"
>
Collection
</div>
{/if}
<div class="line-clamp-1 font-medium pr-0.5"> <div class="line-clamp-1">
{item.name} {decodeString(item?.name)}
</div> </div>
</div> </div>
<div class=" text-xs text-gray-600 dark:text-gray-100 line-clamp-1">
{item?.description}
</div>
</div> </div>
</DropdownMenu.Item> </DropdownMenu.Item>
{/each} {/each}

View file

@ -183,10 +183,7 @@
onMount(async () => { onMount(async () => {
await tools.set(await getTools(localStorage.token)); await tools.set(await getTools(localStorage.token));
await functions.set(await getFunctions(localStorage.token)); await functions.set(await getFunctions(localStorage.token));
await knowledgeCollections.set([ await knowledgeCollections.set([...(await getKnowledgeBases(localStorage.token))]);
...(await getNoteList(localStorage.token)),
...(await getKnowledgeBases(localStorage.token))
]);
// Scroll to top 'workspace-container' element // Scroll to top 'workspace-container' element
const workspaceContainer = document.getElementById('workspace-container'); const workspaceContainer = document.getElementById('workspace-container');