Refactor knowledge menu icons and use shadcn dropdown
This commit is contained in:
parent
2f3b7b69bd
commit
1fef4ee1df
2 changed files with 93 additions and 96 deletions
|
|
@ -4,10 +4,11 @@ import { useQueryClient } from "@tanstack/react-query";
|
|||
import {
|
||||
ChevronDown,
|
||||
Cloud,
|
||||
File,
|
||||
Folder,
|
||||
FolderOpen,
|
||||
Loader2,
|
||||
PlugZap,
|
||||
Upload,
|
||||
} from "lucide-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
|
@ -22,18 +23,26 @@ import {
|
|||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { useTask } from "@/contexts/task-context";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { File as SearchFile } from "@/src/app/api/queries/useGetSearchQuery";
|
||||
import GoogleDriveIcon from "@/app/settings/icons/google-drive-icon";
|
||||
import OneDriveIcon from "@/app/settings/icons/one-drive-icon";
|
||||
import SharePointIcon from "@/app/settings/icons/share-point-icon";
|
||||
import AwsIcon from "@/app/settings/icons/aws-icon";
|
||||
|
||||
export function KnowledgeDropdown() {
|
||||
const { addTask } = useTask();
|
||||
const { refetch: refetchTasks } = useGetTasksQuery();
|
||||
const queryClient = useQueryClient();
|
||||
const router = useRouter();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [showFolderDialog, setShowFolderDialog] = useState(false);
|
||||
const [showS3Dialog, setShowS3Dialog] = useState(false);
|
||||
const [showDuplicateDialog, setShowDuplicateDialog] = useState(false);
|
||||
|
|
@ -55,7 +64,6 @@ export function KnowledgeDropdown() {
|
|||
};
|
||||
}>({});
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const dropdownRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// Check AWS availability and cloud connectors on mount
|
||||
useEffect(() => {
|
||||
|
|
@ -141,24 +149,6 @@ export function KnowledgeDropdown() {
|
|||
checkAvailability();
|
||||
}, []);
|
||||
|
||||
// Handle click outside to close dropdown
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
if (
|
||||
dropdownRef.current &&
|
||||
!dropdownRef.current.contains(event.target as Node)
|
||||
) {
|
||||
setIsOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
if (isOpen) {
|
||||
document.addEventListener("mousedown", handleClickOutside);
|
||||
return () =>
|
||||
document.removeEventListener("mousedown", handleClickOutside);
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
const handleFileUpload = () => {
|
||||
fileInputRef.current?.click();
|
||||
};
|
||||
|
|
@ -168,8 +158,7 @@ export function KnowledgeDropdown() {
|
|||
if (files && files.length > 0) {
|
||||
const file = files[0];
|
||||
|
||||
// Close dropdown immediately after file selection
|
||||
setIsOpen(false);
|
||||
// File selection will close dropdown automatically
|
||||
|
||||
try {
|
||||
// Check if filename already exists (using ORIGINAL filename)
|
||||
|
|
@ -427,13 +416,19 @@ export function KnowledgeDropdown() {
|
|||
}
|
||||
};
|
||||
|
||||
// Icon mapping for cloud connectors
|
||||
const connectorIconMap = {
|
||||
google_drive: GoogleDriveIcon,
|
||||
onedrive: OneDriveIcon,
|
||||
sharepoint: SharePointIcon,
|
||||
};
|
||||
|
||||
const cloudConnectorItems = Object.entries(cloudConnectors)
|
||||
.filter(([, info]) => info.available)
|
||||
.map(([type, info]) => ({
|
||||
label: info.name,
|
||||
icon: PlugZap,
|
||||
icon: connectorIconMap[type as keyof typeof connectorIconMap] || PlugZap,
|
||||
onClick: async () => {
|
||||
setIsOpen(false);
|
||||
if (info.connected && info.hasToken) {
|
||||
setIsNavigatingToCloud(true);
|
||||
try {
|
||||
|
|
@ -448,36 +443,30 @@ export function KnowledgeDropdown() {
|
|||
}
|
||||
},
|
||||
disabled: !info.connected || !info.hasToken,
|
||||
tooltip: !info.connected
|
||||
? `Connect ${info.name} in Settings first`
|
||||
: !info.hasToken
|
||||
? `Reconnect ${info.name} - access token required`
|
||||
: undefined,
|
||||
}));
|
||||
|
||||
const menuItems = [
|
||||
{
|
||||
label: "Add File",
|
||||
icon: Upload,
|
||||
label: "File",
|
||||
icon: File,
|
||||
onClick: handleFileUpload,
|
||||
},
|
||||
{
|
||||
label: "Process Folder",
|
||||
icon: FolderOpen,
|
||||
onClick: () => {
|
||||
setIsOpen(false);
|
||||
setShowFolderDialog(true);
|
||||
},
|
||||
label: "Folder",
|
||||
icon: Folder,
|
||||
onClick: () => setShowFolderDialog(true),
|
||||
},
|
||||
{
|
||||
label: "Amazon S3",
|
||||
icon: AwsIcon,
|
||||
onClick: () => setShowS3Dialog(true),
|
||||
},
|
||||
...(awsEnabled
|
||||
? [
|
||||
{
|
||||
label: "Process S3 Bucket",
|
||||
icon: Cloud,
|
||||
onClick: () => {
|
||||
setIsOpen(false);
|
||||
setShowS3Dialog(true);
|
||||
},
|
||||
label: "Amazon S3",
|
||||
icon: AwsIcon,
|
||||
onClick: () => setShowS3Dialog(true),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
|
|
@ -490,13 +479,9 @@ export function KnowledgeDropdown() {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div ref={dropdownRef} className="relative">
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => !isLoading && setIsOpen(!isOpen)}
|
||||
disabled={isLoading}
|
||||
>
|
||||
<>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button disabled={isLoading}>
|
||||
{isLoading && <Loader2 className="h-4 w-4 animate-spin" />}
|
||||
<span>
|
||||
{isLoading
|
||||
|
|
@ -511,49 +496,30 @@ export function KnowledgeDropdown() {
|
|||
: "Processing..."
|
||||
: "Add Knowledge"}
|
||||
</span>
|
||||
{!isLoading && (
|
||||
<ChevronDown
|
||||
className={cn(
|
||||
"h-4 w-4 transition-transform",
|
||||
isOpen && "rotate-180"
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
</Button>
|
||||
{!isLoading && <ChevronDown className="h-4 w-4" />}
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="w-56">
|
||||
{menuItems.map((item, index) => (
|
||||
<DropdownMenuItem
|
||||
key={`${item.label}-${index}`}
|
||||
onClick={item.onClick}
|
||||
disabled={"disabled" in item ? item.disabled : false}
|
||||
>
|
||||
<item.icon className="mr-2 h-4 w-4 text-muted-foreground" />
|
||||
{item.label}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
{isOpen && !isLoading && (
|
||||
<div className="absolute top-full left-0 right-0 mt-1 bg-popover border border-border rounded-md shadow-md z-50">
|
||||
<div className="py-1">
|
||||
{menuItems.map((item, index) => (
|
||||
<button
|
||||
key={`${item.label}-${index}`}
|
||||
type="button"
|
||||
onClick={item.onClick}
|
||||
disabled={"disabled" in item ? item.disabled : false}
|
||||
title={"tooltip" in item ? item.tooltip : undefined}
|
||||
className={cn(
|
||||
"w-full px-3 py-2 text-left text-sm hover:bg-accent hover:text-accent-foreground",
|
||||
"disabled" in item &&
|
||||
item.disabled &&
|
||||
"opacity-50 cursor-not-allowed hover:bg-transparent hover:text-current"
|
||||
)}
|
||||
>
|
||||
{item.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<input
|
||||
ref={fileInputRef}
|
||||
type="file"
|
||||
onChange={handleFileChange}
|
||||
className="hidden"
|
||||
accept=".pdf,.doc,.docx,.txt,.md,.rtf,.odt"
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
ref={fileInputRef}
|
||||
type="file"
|
||||
onChange={handleFileChange}
|
||||
className="hidden"
|
||||
accept=".pdf,.doc,.docx,.txt,.md,.rtf,.odt"
|
||||
/>
|
||||
|
||||
{/* Process Folder Dialog */}
|
||||
<Dialog open={showFolderDialog} onOpenChange={setShowFolderDialog}>
|
||||
|
|
@ -575,7 +541,7 @@ export function KnowledgeDropdown() {
|
|||
type="text"
|
||||
placeholder="/path/to/documents"
|
||||
value={folderPath}
|
||||
onChange={e => setFolderPath(e.target.value)}
|
||||
onChange={(e) => setFolderPath(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex justify-end gap-2">
|
||||
|
|
@ -617,7 +583,7 @@ export function KnowledgeDropdown() {
|
|||
type="text"
|
||||
placeholder="s3://bucket/path"
|
||||
value={bucketUrl}
|
||||
onChange={e => setBucketUrl(e.target.value)}
|
||||
onChange={(e) => setBucketUrl(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex justify-end gap-2">
|
||||
|
|
|
|||
31
frontend/src/app/settings/icons/aws-icon.tsx
Normal file
31
frontend/src/app/settings/icons/aws-icon.tsx
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
const AwsIcon = ({ className }: { className?: string }) => {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={className}
|
||||
>
|
||||
<path
|
||||
d="M4.50896 6.82059C4.50896 7.01818 4.53024 7.1784 4.56749 7.29588C4.61006 7.41337 4.66328 7.54154 4.73778 7.68039C4.76438 7.72311 4.77503 7.76584 4.77503 7.80322C4.77503 7.85662 4.7431 7.91003 4.67392 7.96343L4.33867 8.18772C4.29078 8.21977 4.24288 8.23579 4.20031 8.23579C4.1471 8.23579 4.09388 8.20909 4.04067 8.16102C3.96617 8.08092 3.90231 7.99547 3.8491 7.91003C3.79588 7.81924 3.74267 7.71777 3.68413 7.59494C3.26906 8.08626 2.74756 8.33191 2.11963 8.33191C1.67263 8.33191 1.3161 8.20375 1.05535 7.94741C0.794596 7.69107 0.66156 7.34929 0.66156 6.92206C0.66156 6.46813 0.821203 6.09964 1.14581 5.82194C1.47042 5.54424 1.90145 5.40539 2.44956 5.40539C2.63049 5.40539 2.81674 5.42141 3.01363 5.44811C3.21053 5.47482 3.41274 5.51754 3.6256 5.5656V5.17576C3.6256 4.76989 3.54045 4.48685 3.37549 4.3213C3.2052 4.15575 2.91785 4.07564 2.5081 4.07564C2.32185 4.07564 2.13028 4.097 1.93338 4.14506C1.73649 4.19313 1.54492 4.25187 1.35867 4.32664C1.27352 4.36402 1.20967 4.38538 1.17242 4.39606C1.13517 4.40674 1.10856 4.41208 1.08727 4.41208C1.01277 4.41208 0.975524 4.35868 0.975524 4.24653V3.98485C0.975524 3.89941 0.986167 3.83532 1.01277 3.79794C1.03938 3.76056 1.08727 3.72318 1.16177 3.68579C1.34802 3.58967 1.57152 3.50956 1.83227 3.44548C2.09302 3.37605 2.36974 3.34401 2.66242 3.34401C3.29567 3.34401 3.75863 3.4882 4.05663 3.77658C4.34931 4.06496 4.49831 4.50287 4.49831 5.09031V6.82059H4.50896ZM2.34845 7.63233C2.52406 7.63233 2.70499 7.60028 2.89656 7.5362C3.08813 7.47212 3.25842 7.35463 3.4021 7.19442C3.48724 7.09295 3.5511 6.9808 3.58303 6.85263C3.61495 6.72446 3.63624 6.56959 3.63624 6.38802V6.16372C3.48192 6.12634 3.31695 6.0943 3.14667 6.07294C2.97638 6.05158 2.81142 6.0409 2.64645 6.0409C2.28992 6.0409 2.02917 6.11032 1.85356 6.25451C1.67795 6.3987 1.59281 6.60163 1.59281 6.86865C1.59281 7.11965 1.65667 7.30656 1.7897 7.43473C1.91742 7.56824 2.10367 7.63233 2.34845 7.63233ZM6.62156 8.20909C6.52578 8.20909 6.46192 8.19307 6.41935 8.15568C6.37678 8.12364 6.33953 8.04888 6.3076 7.94741L5.05706 3.8193C5.02513 3.71249 5.00917 3.64307 5.00917 3.60569C5.00917 3.52024 5.05174 3.47218 5.13688 3.47218H5.65838C5.75949 3.47218 5.82867 3.4882 5.86592 3.52558C5.90849 3.55762 5.94042 3.63239 5.97235 3.73386L6.86635 7.26918L7.69649 3.73386C7.7231 3.62705 7.75503 3.55762 7.7976 3.52558C7.84017 3.49354 7.91467 3.47218 8.01046 3.47218H8.43617C8.53728 3.47218 8.60646 3.4882 8.64903 3.52558C8.6916 3.55762 8.72885 3.63239 8.75014 3.73386L9.59092 7.3119L10.5115 3.73386C10.5435 3.62705 10.5807 3.55762 10.618 3.52558C10.6605 3.49354 10.7297 3.47218 10.8255 3.47218H11.3204C11.4055 3.47218 11.4534 3.5149 11.4534 3.60569C11.4534 3.63239 11.4481 3.65909 11.4428 3.69113C11.4375 3.72318 11.4268 3.7659 11.4055 3.82464L10.1231 7.95275C10.0911 8.05956 10.0539 8.12898 10.0113 8.16102C9.96874 8.19307 9.89956 8.21443 9.8091 8.21443H9.35146C9.25035 8.21443 9.18117 8.19841 9.1386 8.16102C9.09603 8.12364 9.05878 8.05422 9.03749 7.94741L8.21267 4.50287L7.39317 7.94207C7.36656 8.04888 7.33463 8.1183 7.29206 8.15568C7.24949 8.19307 7.17499 8.20909 7.07921 8.20909H6.62156ZM13.4596 8.35328C13.1829 8.35328 12.9062 8.32123 12.6401 8.25715C12.374 8.19307 12.1665 8.12364 12.0281 8.04353C11.943 7.99547 11.8845 7.94207 11.8632 7.894C11.8419 7.84594 11.8312 7.79254 11.8312 7.74447V7.47212C11.8312 7.35997 11.8738 7.30656 11.9536 7.30656C11.9856 7.30656 12.0175 7.3119 12.0494 7.32259C12.0814 7.33327 12.1292 7.35463 12.1825 7.37599C12.3634 7.45609 12.5603 7.52018 12.7678 7.5629C12.9807 7.60562 13.1882 7.62699 13.4011 7.62699C13.7363 7.62699 13.9971 7.56824 14.178 7.45075C14.3589 7.33327 14.4547 7.16237 14.4547 6.94342C14.4547 6.79389 14.4068 6.67106 14.311 6.56959C14.2152 6.46813 14.0343 6.37734 13.7736 6.29189L13.002 6.05158C12.6135 5.92875 12.3261 5.74718 12.1505 5.50686C11.9749 5.27188 11.8845 5.0102 11.8845 4.73251C11.8845 4.50821 11.9324 4.31062 12.0281 4.13972C12.1239 3.96883 12.2516 3.8193 12.4113 3.70181C12.5709 3.57899 12.7519 3.4882 12.9647 3.42411C13.1776 3.36003 13.4011 3.33333 13.6352 3.33333C13.7523 3.33333 13.8747 3.33867 13.9917 3.35469C14.1141 3.37071 14.2259 3.39207 14.3376 3.41343C14.4441 3.44014 14.5452 3.46684 14.641 3.49888C14.7367 3.53092 14.8112 3.56296 14.8645 3.59501C14.939 3.63773 14.9922 3.68045 15.0241 3.72852C15.056 3.77124 15.072 3.82998 15.072 3.90475V4.15575C15.072 4.26789 15.0294 4.32664 14.9496 4.32664C14.907 4.32664 14.8379 4.30528 14.7474 4.26255C14.4441 4.1237 14.1035 4.05428 13.7257 4.05428C13.4224 4.05428 13.1829 4.10234 13.0179 4.20381C12.853 4.30528 12.7678 4.46015 12.7678 4.6791C12.7678 4.82863 12.821 4.9568 12.9275 5.05827C13.0339 5.15973 13.2308 5.2612 13.5128 5.35199L14.2685 5.5923C14.6516 5.71513 14.9283 5.88603 15.0933 6.10498C15.2582 6.32394 15.3381 6.57493 15.3381 6.85263C15.3381 7.08227 15.2902 7.29054 15.1997 7.47212C15.1039 7.65369 14.9762 7.8139 14.8112 7.94207C14.6463 8.07558 14.4494 8.1717 14.2206 8.24113C13.9811 8.31589 13.731 8.35328 13.4596 8.35328Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M14.4654 10.9487C12.7146 12.2464 10.171 12.9353 7.98385 12.9353C4.91871 12.9353 2.15688 11.7978 0.0708824 9.90731C-0.094082 9.75778 0.0549181 9.55484 0.251811 9.67233C2.5081 10.9861 5.29121 11.7818 8.1701 11.7818C10.1124 11.7818 12.2463 11.3759 14.2099 10.5428C14.5026 10.4093 14.7527 10.7351 14.4654 10.9487Z"
|
||||
fill="#FF9900"
|
||||
/>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M15.1944 10.1156C14.9709 9.82721 13.715 9.97674 13.1457 10.0462C12.9754 10.0675 12.9488 9.91799 13.1031 9.80584C14.1035 9.10092 15.7478 9.30385 15.9394 9.53883C16.131 9.77914 15.8862 11.4293 14.9496 12.2197C14.8059 12.3425 14.6676 12.2784 14.7314 12.1182C14.9443 11.5895 15.4179 10.3986 15.1944 10.1156Z"
|
||||
fill="#FF9900"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default AwsIcon;
|
||||
Loading…
Add table
Reference in a new issue