Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added frontend/src/assets/emptystateIcons/agent.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/src/assets/emptystateIcons/kb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
152 changes: 93 additions & 59 deletions frontend/src/routes/_authenticated/agent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ import { textToCitationIndex } from "@/utils/chatUtils.tsx"
import { GoogleDriveNavigation } from "@/components/GoogleDriveNavigation"
import { CollectionNavigation } from "@/components/CollectionNavigation"
import ViewAgent from "@/components/ViewAgent"
import agentEmptyStateIcon from "@/assets/emptystateIcons/agent.png"

type CurrentResp = {
resp: string
Expand Down Expand Up @@ -2751,22 +2752,36 @@ function AgentComponent() {
AGENTS
</h1>
<div className="flex items-center gap-4 ">
<div className="relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-5 w-5" />
<input
type="text"
placeholder="Search agents.."
value={listSearchQuery}
onChange={handleListSearchChange}
className="pl-10 pr-4 py-2 rounded-full border border-gray-200 dark:border-slate-600 w-[300px] focus:outline-none focus:ring-2 focus:ring-gray-300 dark:focus:ring-slate-500 bg-white dark:bg-slate-700 dark:text-gray-100"
/>
</div>
<Button
onClick={handleCreateNewAgent}
className="bg-slate-800 hover:bg-slate-700 text-white font-mono font-medium rounded-full px-6 py-2 flex items-center gap-2"
>
<Plus size={18} /> CREATE
</Button>
{(() => {
// Calculate whether current tab has agents
const agentLists: Record<string, SelectPublicAgent[]> = {
"all": allAgentsList,
"made-by-me": madeByMeAgentsList,
"shared-to-me": sharedToMeAgentsList,
}
const currentTabHasAgents = (agentLists[activeTab]?.length ?? 0) > 0

return currentTabHasAgents && (
<>
<div className="relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-5 w-5" />
<input
type="text"
placeholder="Search agents.."
value={listSearchQuery}
onChange={handleListSearchChange}
className="pl-10 pr-4 py-2 rounded-full border border-gray-200 dark:border-slate-600 w-[300px] focus:outline-none focus:ring-2 focus:ring-gray-300 dark:focus:ring-slate-500 bg-white dark:bg-slate-700 dark:text-gray-100"
/>
</div>
<Button
onClick={handleCreateNewAgent}
className="bg-slate-800 hover:bg-slate-700 text-white font-mono font-medium rounded-full px-6 py-2 flex items-center gap-2"
>
<Plus size={18} /> CREATE
</Button>
</>
)
})()}
</div>
</div>

Expand Down Expand Up @@ -2820,46 +2835,42 @@ function AgentComponent() {
)
})()}

{(allAgentsList.length > 0 ||
madeByMeAgentsList.length > 0 ||
sharedToMeAgentsList.length > 0) && ( // Only show tabs if there are agents in any list
<div className="flex items-center justify-between mb-2">
<div className="flex space-x-2">
<TabButton
active={activeTab === "all"}
onClick={() => handleTabChange("all")}
icon="asterisk"
label="ALL"
/>
<TabButton
active={activeTab === "shared-to-me"}
onClick={() => handleTabChange("shared-to-me")}
icon="users"
label="SHARED-WITH-ME"
/>
<TabButton
active={activeTab === "made-by-me"}
onClick={() => handleTabChange("made-by-me")}
icon="user"
label="MADE-BY-ME"
<div className="flex items-center justify-between mb-2">
<div className="flex space-x-2">
<TabButton
active={activeTab === "all"}
onClick={() => handleTabChange("all")}
icon="asterisk"
label="ALL"
/>
<TabButton
active={activeTab === "shared-to-me"}
onClick={() => handleTabChange("shared-to-me")}
icon="users"
label="SHARED-WITH-ME"
/>
<TabButton
active={activeTab === "made-by-me"}
onClick={() => handleTabChange("made-by-me")}
icon="user"
label="MADE-BY-ME"
/>
</div>
<div>
<Button
onClick={fetchAllAgentData}
variant="outline"
size="sm"
className="text-xs flex items-center gap-2 text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-slate-700"
disabled={isLoadingAgents}
>
<RefreshCw
size={14}
className={`${isLoadingAgents ? "animate-spin" : ""}`}
/>
</div>
<div>
<Button
onClick={fetchAllAgentData}
variant="outline"
size="sm"
className="text-xs flex items-center gap-2 text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-slate-700"
disabled={isLoadingAgents}
>
<RefreshCw
size={14}
className={`${isLoadingAgents ? "animate-spin" : ""}`}
/>
</Button>
</div>
</Button>
</div>
)}
</div>

{(() => {
let currentListToDisplay: SelectPublicAgent[] = []
Expand Down Expand Up @@ -2910,13 +2921,36 @@ function AgentComponent() {
}

if (currentListToDisplay.length === 0 && !listSearchQuery) {
const isSharedTab = activeTab === "shared-to-me"
const title = isSharedTab
? "No agents shared with you yet"
: "No agents created yet"
const description = isSharedTab
? null
: "Click 'Create Agent' to add your first agent"

return (
<div className="text-center py-10 text-gray-500 dark:text-gray-400">
<p className="text-lg mb-2">
No agents in this category yet.
<div className="flex flex-col items-center justify-center min-h-[60vh]">
<img
src={agentEmptyStateIcon}
alt="No agents"
className="w-32 h-32 mb-6 opacity-60"
/>
<p className="text-xl font-medium text-gray-700 dark:text-gray-300 mb-2">
{title}
</p>
{activeTab === "all" && (
<p>Click "CREATE" to get started.</p>
{description && (
<p className="text-sm text-gray-500 dark:text-gray-400 mb-6">
{description}
</p>
)}
{!isSharedTab && (
<Button
onClick={handleCreateNewAgent}
className="bg-slate-800 hover:bg-slate-700 text-white font-mono font-medium rounded-full px-6 py-2 flex items-center gap-2"
>
<Plus size={18} /> CREATE AGENT
</Button>
)}
</div>
)
Expand Down
45 changes: 38 additions & 7 deletions frontend/src/routes/_authenticated/knowledgeManagement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import CsvViewer from "@/components/CsvViewer"
import TxtViewer from "@/components/TxtViewer"
import { useUploadProgress } from "@/store/useUploadProgressStore"
import { DebugDocModal } from "@/components/DebugDocModal"
import kbEmptyStateIcon from "@/assets/emptystateIcons/kb.png"

// Persistent storage for documentId -> tempChatId mapping using sessionStorage
const DOCUMENT_CHAT_MAP_KEY = "documentToTempChatMap"
Expand Down Expand Up @@ -1774,21 +1775,50 @@ function KnowledgeManagementContent() {
<h1 className="text-[32px] font-display text-gray-700 dark:text-gray-100 tracking-wider">
KNOWLEDGE MANAGEMENT
</h1>
<div className="flex items-center gap-4">
{/* <Search className="text-gray-400 dark:text-gray-500 h-6 w-6" /> */}
{(collections.length > 0 || isUploading) && (
<div className="flex items-center gap-4">
{/* <Search className="text-gray-400 dark:text-gray-500 h-6 w-6" /> */}
<Button
onClick={() => setShowNewCollection(true)}
disabled={isUploading}
className="bg-slate-800 hover:bg-slate-700 dark:bg-[#2d2d2d] dark:hover:bg-[#404040] text-white rounded-full px-4 py-2 flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed"
>
<Plus size={16} />
<span className="font-mono text-[12px] font-medium">
NEW COLLECTION
</span>
</Button>
</div>
)}
</div>

{collections.length === 0 && !isUploading ? (
// Empty state - centered layout
<div className="flex flex-col items-center justify-center min-h-[70vh]">
<img
src={kbEmptyStateIcon}
alt="No collections"
className="w-32 h-32 mb-6 opacity-60"
/>
<h2 className="text-xl font-semibold text-gray-700 dark:text-gray-300 mb-2">
No collections available yet
</h2>
<p className="text-gray-500 dark:text-gray-400 mb-8 text-center ">
Add your first collection to structure and manage information
</p>
<Button
onClick={() => setShowNewCollection(true)}
disabled={isUploading}
className="bg-slate-800 hover:bg-slate-700 dark:bg-[#2d2d2d] dark:hover:bg-[#404040] text-white rounded-full px-4 py-2 flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed"
className="bg-slate-800 hover:bg-slate-700 dark:bg-[#2d2d2d] dark:hover:bg-[#404040] text-white rounded-full px-6 py-3 flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed"
>
<Plus size={16} />
<span className="font-mono text-[12px] font-medium">
NEW COLLECTION
ADD COLLECTION
</span>
</Button>
</div>
</div>
<div className="mt-12">
) : (
<div className="mt-12">
{/* Show skeleton loader when uploading to NEW collection */}
{isUploading && batchProgress.total > 0 && isNewCollectionUpload && (
<div className="mb-8">
Expand Down Expand Up @@ -2070,7 +2100,8 @@ function KnowledgeManagementContent() {
)}
</div>
))}
</div>
</div>
)}
</div>
</div>
)}
Expand Down