Skip to content

Commit

Permalink
api fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
thewbuk committed Jul 29, 2024
1 parent 84e7f38 commit 479759f
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 64 deletions.
Original file line number Diff line number Diff line change
@@ -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<string>;
namespaceId: Nullable<string> | undefined;
knowledgeBaseId: Nullable<string>;
accessToken: Nullable<string>;
enabled: boolean;
}) {
return useQuery<File[]>({
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,
});
}
}
2 changes: 1 addition & 1 deletion packages/toolkit/src/lib/vdp-sdk/knowledge/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export interface KnowledgeBase {
export type KnowledgeBase = {
usage: number;
kbId: string;
name: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -83,15 +83,20 @@ export const CatalogFilesTab: React.FC<CatalogFilesTabProps> = ({
})),
);

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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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<React.SetStateAction<boolean>>;
};

const DuplicateFileNotification = ({
deletedFileName,
setShowDeleteMessage,
}: DuplicateFileNotificationProps) => {

return (
<div className="fixed bottom-4 right-8 flex h-[136px] w-[400px] rounded-sm border border-semantic-bg-line bg-semantic-bg-primary p-4 shadow">
<Icons.AlertTriangle className="mr-4 h-6 w-6 stroke-semantic-warning-on-bg" />
<div className="mr-4 shrink grow basis-0 flex-col items-start justify-start space-y-4">
<div className="flex flex-col items-start justify-start gap-1 self-stretch">
<div className="self-stretch product-body-text-2-semibold truncate">
{deletedFileName} Already Uploaded or Exists in Knowledge Base
</div>
<div className="self-stretch text-semantic-fg-secondary product-body-text-3-regular">
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.
</div>
</div>
</div>
<Button
className="absolute right-2 top-2"
variant="tertiaryGrey"
size="sm"
onClick={() => setShowDeleteMessage(false)}
>
<Icons.X className="h-6 w-6 stroke-semantic-fg-secondary" />
</Button>
</div>
);
};

export default DuplicateFileNotification;
29 changes: 18 additions & 11 deletions packages/toolkit/src/view/knowledge/components/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -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 = {
Expand All @@ -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 {
Expand All @@ -52,6 +51,8 @@ export const Sidebar = ({
return "stroke-semantic-fg-secondary";
};

const isCatalogExpanded = activeTab === "catalog";

return (
<aside className="flex w-[160px] flex-col gap-y-4">
<div
Expand All @@ -75,10 +76,14 @@ export const Sidebar = ({
}
}}
>
<Icons.ChevronRight className={`w-4 h-4 ${getCatalogIconColor()}`} />
{isCatalogExpanded ? (
<Icons.ChevronDown className={`w-4 h-4 ${getCatalogIconColor()}`} />
) : (
<Icons.ChevronRight className={`w-4 h-4 ${getCatalogIconColor()}`} />
)}
Catalog
</div>
{activeTab === "catalog" && (
{isCatalogExpanded && (
<>
<div
className={getTabClassName("Files", true)}
Expand All @@ -93,7 +98,9 @@ export const Sidebar = ({
</div>
<div
className={getTabClassName("Chunk", true)}
onClick={() => selectedKnowledgeBase && onTextOptionChange("Chunk")}
onClick={() =>
selectedKnowledgeBase && onTextOptionChange("Chunk")
}
>
Chunk
</div>
Expand All @@ -116,4 +123,4 @@ export const Sidebar = ({
</div>
</aside>
);
};
};
96 changes: 56 additions & 40 deletions packages/toolkit/src/view/knowledge/components/UploadExploreTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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({
Expand Down Expand Up @@ -203,11 +213,10 @@ export const UploadExploreTab = ({
<Form.Item className="w-full">
<Form.Control>
<div
className={`flex w-full cursor-pointer flex-col items-center justify-center rounded bg-semantic-bg-base-bg text-semantic-fg-secondary product-body-text-4-regular ${
isDragging
? "border-semantic-accent-default"
: "border-semantic-bg-line"
} [border-dash-gap:6px] [border-dash:6px] [border-style:dashed] [border-width:2px]`}
className={`flex w-full cursor-pointer flex-col items-center justify-center rounded bg-semantic-bg-base-bg text-semantic-fg-secondary product-body-text-4-regular ${isDragging
? "border-semantic-accent-default"
: "border-semantic-bg-line"
} [border-dash-gap:6px] [border-dash:6px] [border-style:dashed] [border-width:2px]`}
onDragEnter={(e) => {
e.preventDefault();
setIsDragging(true);
Expand Down Expand Up @@ -309,10 +318,17 @@ export const UploadExploreTab = ({
<Button
variant="primary"
size="lg"
disabled={form.watch("files").length === 0}
disabled={form.watch("files").length === 0 || isProcessing}
onClick={handleProcessFiles}
>
Process Files
{isProcessing ? (
<>
<Icons.LayersTwo01 className="mr-2 h-4 w-4 animate-spin" />
Processing...
</>
) : (
"Process Files"
)}
</Button>
</div>
</div>
Expand Down

0 comments on commit 479759f

Please sign in to comment.