From 479759ffae17018f6563c8ab160a0354e30c7570 Mon Sep 17 00:00:00 2001 From: Wojciech Bandzerewicz <57405495+thewbuk@users.noreply.github.com> Date: Mon, 29 Jul 2024 14:44:47 +0100 Subject: [PATCH] api fixes --- .../knowledge/useListKnowledgeBaseFiles.ts | 16 ++-- .../src/lib/vdp-sdk/knowledge/types.ts | 2 +- .../knowledge/components/CatalogFilesTab.tsx | 11 ++- .../DuplicateFileNotification.tsx | 41 ++++++++ .../src/view/knowledge/components/Sidebar.tsx | 29 +++--- .../knowledge/components/UploadExploreTab.tsx | 96 +++++++++++-------- 6 files changed, 131 insertions(+), 64 deletions(-) create mode 100644 packages/toolkit/src/view/knowledge/components/Notifications/DuplicateFileNotification.tsx diff --git a/packages/toolkit/src/lib/react-query-service/knowledge/useListKnowledgeBaseFiles.ts b/packages/toolkit/src/lib/react-query-service/knowledge/useListKnowledgeBaseFiles.ts index bce46bf051..603df00ea9 100644 --- a/packages/toolkit/src/lib/react-query-service/knowledge/useListKnowledgeBaseFiles.ts +++ b/packages/toolkit/src/lib/react-query-service/knowledge/useListKnowledgeBaseFiles.ts @@ -1,39 +1,37 @@ import { useQuery } from "@tanstack/react-query"; - import { Nullable } from "@instill-ai/toolkit"; - import { createInstillAxiosClient } from "../../vdp-sdk/helper"; import { File } from "../../vdp-sdk/knowledge/types"; export function useListKnowledgeBaseFiles({ - ownerId, + namespaceId, knowledgeBaseId, accessToken, enabled, }: { - ownerId: Nullable; + namespaceId: Nullable | undefined; knowledgeBaseId: Nullable; accessToken: Nullable; enabled: boolean; }) { return useQuery({ - queryKey: ["knowledgeBaseFiles", ownerId, knowledgeBaseId], + queryKey: ["knowledgeBaseFiles", namespaceId, knowledgeBaseId], queryFn: async () => { if (!accessToken) { throw new Error("accessToken not provided"); } - if (!ownerId) { - throw new Error("ownerId not provided"); + if (!namespaceId) { + throw new Error("namespaceId not provided"); } if (!knowledgeBaseId) { throw new Error("knowledgeBaseId not provided"); } const client = createInstillAxiosClient(accessToken, true); const response = await client.get<{ files: File[] }>( - `/namespaces/${ownerId}/knowledge-bases/${knowledgeBaseId}/files`, + `/namespaces/${namespaceId}/knowledge-bases/${knowledgeBaseId}/files`, ); return response.data.files; }, enabled, }); -} +} \ No newline at end of file diff --git a/packages/toolkit/src/lib/vdp-sdk/knowledge/types.ts b/packages/toolkit/src/lib/vdp-sdk/knowledge/types.ts index 4fe2da6fb2..fb09619000 100644 --- a/packages/toolkit/src/lib/vdp-sdk/knowledge/types.ts +++ b/packages/toolkit/src/lib/vdp-sdk/knowledge/types.ts @@ -1,4 +1,4 @@ -export interface KnowledgeBase { +export type KnowledgeBase = { usage: number; kbId: string; name: string; diff --git a/packages/toolkit/src/view/knowledge/components/CatalogFilesTab.tsx b/packages/toolkit/src/view/knowledge/components/CatalogFilesTab.tsx index 10b123fd09..9873408015 100644 --- a/packages/toolkit/src/view/knowledge/components/CatalogFilesTab.tsx +++ b/packages/toolkit/src/view/knowledge/components/CatalogFilesTab.tsx @@ -8,7 +8,7 @@ import { Tag, } from "@instill-ai/design-system"; -import { InstillStore, useInstillStore, useShallow } from "../../../lib"; +import { InstillStore, useAuthenticatedUser, useInstillStore, useShallow } from "../../../lib"; import { useDeleteKnowledgeBaseFile, useListKnowledgeBaseFiles, @@ -83,15 +83,20 @@ export const CatalogFilesTab: React.FC = ({ })), ); + const me = useAuthenticatedUser({ + enabled: enabledQuery, + accessToken, + }); + const { data: files, isLoading, refetch, } = useListKnowledgeBaseFiles({ - ownerId: knowledgeBase.ownerName, + namespaceId: me.data?.id ?? null, knowledgeBaseId: knowledgeBase.kbId, accessToken, - enabled: enabledQuery, + enabled: enabledQuery && Boolean(me.data?.id), }); const deleteKnowledgeBaseFile = useDeleteKnowledgeBaseFile(); diff --git a/packages/toolkit/src/view/knowledge/components/Notifications/DuplicateFileNotification.tsx b/packages/toolkit/src/view/knowledge/components/Notifications/DuplicateFileNotification.tsx new file mode 100644 index 0000000000..b3fac888e4 --- /dev/null +++ b/packages/toolkit/src/view/knowledge/components/Notifications/DuplicateFileNotification.tsx @@ -0,0 +1,41 @@ +import * as React from "react"; + +import { Button, Icons } from "@instill-ai/design-system"; + +type DuplicateFileNotificationProps = { + deletedFileName: string; + undoDelete: () => void; + setShowDeleteMessage: React.Dispatch>; +}; + +const DuplicateFileNotification = ({ + deletedFileName, + setShowDeleteMessage, +}: DuplicateFileNotificationProps) => { + + return ( +
+ +
+
+
+ {deletedFileName} Already Uploaded or Exists in Knowledge Base +
+
+ Current knowledge base does not support uploading the same file twice. Please consider deleting the old file with the same name or renaming your new file before attempting to upload again. +
+
+
+ +
+ ); +}; + +export default DuplicateFileNotification; diff --git a/packages/toolkit/src/view/knowledge/components/Sidebar.tsx b/packages/toolkit/src/view/knowledge/components/Sidebar.tsx index 6343de2822..f95c578bbd 100644 --- a/packages/toolkit/src/view/knowledge/components/Sidebar.tsx +++ b/packages/toolkit/src/view/knowledge/components/Sidebar.tsx @@ -1,9 +1,7 @@ "use client"; import { useRouter } from "next/navigation"; - import { Icons } from "@instill-ai/design-system"; - import { KnowledgeBase } from "../../../lib/vdp-sdk/knowledge/types"; type SidebarProps = { @@ -29,12 +27,13 @@ export const Sidebar = ({ }; const getTabClassName = (tabName: string, isSubTab = false) => { - const baseClass = `flex h-8 items-center gap-x-2 rounded px-3 product-button-button-2 ${ - isSubTab ? "ml-4" : "" - }`; + const baseClass = `flex h-8 items-center gap-x-2 rounded px-3 product-button-button-2 ${isSubTab ? "ml-4" : "" + }`; + const isActive = + activeTab === tabName || (isSubTab && selectedTextOption === tabName); - if (activeTab === tabName || (isSubTab && selectedTextOption === tabName)) { - return `${baseClass} bg-semantic-accent-bg text-semantic-accent-hover`; + if (isActive) { + return `${baseClass} bg-semantic-accent-bg text-semantic-accent-hover font-bold`; } else if (!selectedKnowledgeBase && tabName !== "knowledge-base") { return `${baseClass} cursor-not-allowed text-semantic-fg-disabled`; } else { @@ -52,6 +51,8 @@ export const Sidebar = ({ return "stroke-semantic-fg-secondary"; }; + const isCatalogExpanded = activeTab === "catalog"; + return ( ); -}; +}; \ No newline at end of file diff --git a/packages/toolkit/src/view/knowledge/components/UploadExploreTab.tsx b/packages/toolkit/src/view/knowledge/components/UploadExploreTab.tsx index b7093c8c13..6134b53a3f 100644 --- a/packages/toolkit/src/view/knowledge/components/UploadExploreTab.tsx +++ b/packages/toolkit/src/view/knowledge/components/UploadExploreTab.tsx @@ -91,6 +91,7 @@ export const UploadExploreTab = ({ ); const uploadKnowledgeBaseFile = useUploadKnowledgeBaseFile(); const processKnowledgeBaseFiles = useProcessKnowledgeBaseFiles(); + const [isProcessing, setIsProcessing] = React.useState(false); const getFileType = (file: File) => { const extension = file.name.split(".").pop()?.toLowerCase(); @@ -137,44 +138,53 @@ export const UploadExploreTab = ({ }; const handleProcessFiles = async () => { + setIsProcessing(true); const files = form.getValues("files"); - if (files.length === 0) return; + if (files.length === 0) { + setIsProcessing(false); + return; + } - const uploadedFiles = await Promise.all( - files.map(async (file) => { - const reader = new FileReader(); - return new Promise<{ fileUid: string }>((resolve, reject) => { - reader.onload = async (event) => { - const content = btoa(event.target?.result as string); - try { - const uploadedFile = await uploadKnowledgeBaseFile.mutateAsync({ - ownerId: ownerID, - knowledgeBaseId: knowledgeBase.kbId, - payload: { - name: file.name, - type: getFileType(file), - content, - }, - accessToken, - }); - resolve(uploadedFile); - } catch (error) { - reject(error); - } - }; - reader.readAsBinaryString(file); - }); - }), - ); + try { + const uploadedFiles = await Promise.all( + files.map(async (file) => { + const reader = new FileReader(); + return new Promise<{ fileUid: string }>((resolve, reject) => { + reader.onload = async (event) => { + const content = btoa(event.target?.result as string); + try { + const uploadedFile = await uploadKnowledgeBaseFile.mutateAsync({ + ownerId: ownerID, + knowledgeBaseId: knowledgeBase.kbId, + payload: { + name: file.name, + type: getFileType(file), + content, + }, + accessToken, + }); + resolve(uploadedFile); + } catch (error) { + reject(error); + } + }; + reader.readAsBinaryString(file); + }); + }) + ); - const fileUids = uploadedFiles.map((file) => file.fileUid); + const fileUids = uploadedFiles.map((file) => file.fileUid); - await processKnowledgeBaseFiles.mutateAsync({ - fileUids, - accessToken, - }); + await processKnowledgeBaseFiles.mutateAsync({ + fileUids, + accessToken, + }); - onProcessFile(); + onProcessFile(); + } catch (error) { + console.error("Error processing files:", error); + setIsProcessing(false); + } }; const me = useAuthenticatedUser({ @@ -203,11 +213,10 @@ export const UploadExploreTab = ({
{ e.preventDefault(); setIsDragging(true); @@ -309,10 +318,17 @@ export const UploadExploreTab = ({