mirror of
https://github.com/open-webui/open-webui
synced 2025-01-31 06:49:03 +00:00
enh: sync directory
This commit is contained in:
parent
e3889522d6
commit
a909aa1c20
@ -313,6 +313,25 @@ def remove_file_from_knowledge_by_id(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
############################
|
||||||
|
# ResetKnowledgeById
|
||||||
|
############################
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/{id}/reset", response_model=Optional[KnowledgeResponse])
|
||||||
|
async def reset_knowledge_by_id(id: str, user=Depends(get_admin_user)):
|
||||||
|
try:
|
||||||
|
VECTOR_DB_CLIENT.delete_collection(collection_name=id)
|
||||||
|
except Exception as e:
|
||||||
|
log.debug(e)
|
||||||
|
pass
|
||||||
|
|
||||||
|
knowledge = Knowledges.update_knowledge_by_id(
|
||||||
|
id=id, form_data=KnowledgeUpdateForm(data={"file_ids": []})
|
||||||
|
)
|
||||||
|
return knowledge
|
||||||
|
|
||||||
|
|
||||||
############################
|
############################
|
||||||
# DeleteKnowledgeById
|
# DeleteKnowledgeById
|
||||||
############################
|
############################
|
||||||
|
@ -243,6 +243,38 @@ export const removeFileFromKnowledgeById = async (token: string, id: string, fil
|
|||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const resetKnowledgeById = async (token: string, id: string) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/knowledge/${id}/reset`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
authorization: `Bearer ${token}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
return json;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
error = err.detail;
|
||||||
|
|
||||||
|
console.log(err);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
export const deleteKnowledgeById = async (token: string, id: string) => {
|
export const deleteKnowledgeById = async (token: string, id: string) => {
|
||||||
let error = null;
|
let error = null;
|
||||||
|
|
||||||
|
19
src/lib/components/icons/ArrowPath.svelte
Normal file
19
src/lib/components/icons/ArrowPath.svelte
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let className = 'size-4';
|
||||||
|
export let strokeWidth = '1.5';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width={strokeWidth}
|
||||||
|
stroke="currentColor"
|
||||||
|
class={className}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99"
|
||||||
|
/>
|
||||||
|
</svg>
|
@ -14,6 +14,7 @@
|
|||||||
addFileToKnowledgeById,
|
addFileToKnowledgeById,
|
||||||
getKnowledgeById,
|
getKnowledgeById,
|
||||||
removeFileFromKnowledgeById,
|
removeFileFromKnowledgeById,
|
||||||
|
resetKnowledgeById,
|
||||||
updateFileFromKnowledgeById,
|
updateFileFromKnowledgeById,
|
||||||
updateKnowledgeById
|
updateKnowledgeById
|
||||||
} from '$lib/apis/knowledge';
|
} from '$lib/apis/knowledge';
|
||||||
@ -70,10 +71,12 @@
|
|||||||
let selectedFileId = null;
|
let selectedFileId = null;
|
||||||
|
|
||||||
$: if (selectedFileId) {
|
$: if (selectedFileId) {
|
||||||
const file = knowledge.files.find((file) => file.id === selectedFileId);
|
const file = (knowledge?.files ?? []).find((file) => file.id === selectedFileId);
|
||||||
if (file) {
|
if (file) {
|
||||||
file.data = file.data ?? { content: '' };
|
file.data = file.data ?? { content: '' };
|
||||||
selectedFile = file;
|
selectedFile = file;
|
||||||
|
} else {
|
||||||
|
selectedFile = null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
selectedFile = null;
|
selectedFile = null;
|
||||||
@ -130,6 +133,9 @@
|
|||||||
// Get directory handle through picker
|
// Get directory handle through picker
|
||||||
const dirHandle = await window.showDirectoryPicker();
|
const dirHandle = await window.showDirectoryPicker();
|
||||||
|
|
||||||
|
console.log(typeof dirHandle);
|
||||||
|
console.log(dirHandle);
|
||||||
|
|
||||||
let totalFiles = 0;
|
let totalFiles = 0;
|
||||||
let uploadedFiles = 0;
|
let uploadedFiles = 0;
|
||||||
|
|
||||||
@ -196,8 +202,18 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Helper function to maintain file paths within zip
|
// Helper function to maintain file paths within zip
|
||||||
const getRelativePath = (fullPath, basePath) => {
|
const syncDirectoryHandler = async () => {
|
||||||
return fullPath.substring(basePath.length + 1);
|
const res = await resetKnowledgeById(localStorage.token, id).catch((e) => {
|
||||||
|
toast.error(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
knowledge = res;
|
||||||
|
toast.success($i18n.t('Knowledge reset successfully.'));
|
||||||
|
|
||||||
|
// Upload directory
|
||||||
|
uploadDirectoryHandler();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const addFileHandler = async (fileId) => {
|
const addFileHandler = async (fileId) => {
|
||||||
@ -501,6 +517,9 @@
|
|||||||
document.getElementById('files-input').click();
|
document.getElementById('files-input').click();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
on:sync={(e) => {
|
||||||
|
syncDirectoryHandler();
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,18 +5,11 @@
|
|||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
import Dropdown from '$lib/components/common/Dropdown.svelte';
|
import Dropdown from '$lib/components/common/Dropdown.svelte';
|
||||||
import GarbageBin from '$lib/components/icons/GarbageBin.svelte';
|
|
||||||
import Pencil from '$lib/components/icons/Pencil.svelte';
|
|
||||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||||
import Tags from '$lib/components/chat/Tags.svelte';
|
|
||||||
import Share from '$lib/components/icons/Share.svelte';
|
|
||||||
import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte';
|
|
||||||
import DocumentDuplicate from '$lib/components/icons/DocumentDuplicate.svelte';
|
|
||||||
import ArrowDownTray from '$lib/components/icons/ArrowDownTray.svelte';
|
|
||||||
import ArrowUpCircle from '$lib/components/icons/ArrowUpCircle.svelte';
|
import ArrowUpCircle from '$lib/components/icons/ArrowUpCircle.svelte';
|
||||||
import EllipsisHorizontal from '$lib/components/icons/EllipsisHorizontal.svelte';
|
|
||||||
import BarsArrowUp from '$lib/components/icons/BarsArrowUp.svelte';
|
import BarsArrowUp from '$lib/components/icons/BarsArrowUp.svelte';
|
||||||
import FolderOpen from '$lib/components/icons/FolderOpen.svelte';
|
import FolderOpen from '$lib/components/icons/FolderOpen.svelte';
|
||||||
|
import ArrowPath from '$lib/components/icons/ArrowPath.svelte';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
@ -83,6 +76,23 @@
|
|||||||
<div class="flex items-center">{$i18n.t('Upload directory')}</div>
|
<div class="flex items-center">{$i18n.t('Upload directory')}</div>
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
|
|
||||||
|
<Tooltip
|
||||||
|
content={$i18n.t(
|
||||||
|
'This option will delete all existing files in the collection and replace them with newly uploaded files.'
|
||||||
|
)}
|
||||||
|
className="w-full"
|
||||||
|
>
|
||||||
|
<DropdownMenu.Item
|
||||||
|
class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
|
||||||
|
on:click={() => {
|
||||||
|
dispatch('sync', { type: 'directory' });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ArrowPath strokeWidth="2" />
|
||||||
|
<div class="flex items-center">{$i18n.t('Sync directory')}</div>
|
||||||
|
</DropdownMenu.Item>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
|
class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
|
Loading…
Reference in New Issue
Block a user