- {group.label}
+ {groupedTools
+ .filter((g) => !g.connectorIcon)
+ .map((group) => (
+
- {group.tools.map((tool) => {
- const isDisabled = disabledTools.includes(tool.name);
- const ToolIcon = getToolIcon(tool.name);
- const row = (
-
- );
- })}
+ ))}
+ {groupedTools.some((g) => g.connectorIcon) && (
+
Loading tools...
@@ -931,7 +1070,14 @@ function formatToolName(name: string): string {
.join(" ");
}
-const TOOL_GROUPS: { label: string; tools: string[] }[] = [
+interface ToolGroup {
+ label: string;
+ tools: string[];
+ connectorIcon?: string;
+ tooltip?: string;
+}
+
+const TOOL_GROUPS: ToolGroup[] = [
{
label: "Research",
tools: ["search_knowledge_base", "search_surfsense_docs", "scrape_webpage", "link_preview"],
@@ -950,6 +1096,48 @@ const TOOL_GROUPS: { label: string; tools: string[] }[] = [
label: "Memory",
tools: ["save_memory", "recall_memory"],
},
+ {
+ label: "Gmail",
+ tools: ["create_gmail_draft", "update_gmail_draft", "send_gmail_email", "trash_gmail_email"],
+ connectorIcon: "gmail",
+ tooltip: "Create drafts, update drafts, send emails, and trash emails in Gmail.",
+ },
+ {
+ label: "Google Calendar",
+ tools: ["create_calendar_event", "update_calendar_event", "delete_calendar_event"],
+ connectorIcon: "google_calendar",
+ tooltip: "Create, update, and delete events in Google Calendar.",
+ },
+ {
+ label: "Google Drive",
+ tools: ["create_google_drive_file", "delete_google_drive_file"],
+ connectorIcon: "google_drive",
+ tooltip: "Create and delete files in Google Drive.",
+ },
+ {
+ label: "Notion",
+ tools: ["create_notion_page", "update_notion_page", "delete_notion_page"],
+ connectorIcon: "notion",
+ tooltip: "Create, update, and delete pages in Notion.",
+ },
+ {
+ label: "Linear",
+ tools: ["create_linear_issue", "update_linear_issue", "delete_linear_issue"],
+ connectorIcon: "linear",
+ tooltip: "Create, update, and delete issues in Linear.",
+ },
+ {
+ label: "Jira",
+ tools: ["create_jira_issue", "update_jira_issue", "delete_jira_issue"],
+ connectorIcon: "jira",
+ tooltip: "Create, update, and delete issues in Jira.",
+ },
+ {
+ label: "Confluence",
+ tools: ["create_confluence_page", "update_confluence_page", "delete_confluence_page"],
+ connectorIcon: "confluence",
+ tooltip: "Create, update, and delete pages in Confluence.",
+ },
];
const MessageError: FC = () => {
diff --git a/surfsense_web/components/connectors/composio-drive-folder-tree.tsx b/surfsense_web/components/connectors/composio-drive-folder-tree.tsx
index 2af53acac..05fbf801b 100644
--- a/surfsense_web/components/connectors/composio-drive-folder-tree.tsx
+++ b/surfsense_web/components/connectors/composio-drive-folder-tree.tsx
@@ -12,7 +12,7 @@ import {
Image,
Presentation,
} from "lucide-react";
-import { useState } from "react";
+import { useEffect, useState } from "react";
import { Checkbox } from "@/components/ui/checkbox";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Spinner } from "@/components/ui/spinner";
@@ -48,23 +48,24 @@ interface ComposioDriveFolderTreeProps {
onSelectFolders: (folders: SelectedFolder[]) => void;
selectedFiles?: SelectedFolder[];
onSelectFiles?: (files: SelectedFolder[]) => void;
+ onAuthError?: (message: string) => void;
}
// Helper to get appropriate icon for file type
function getFileIcon(mimeType: string, className: string = "h-4 w-4") {
if (mimeType.includes("spreadsheet") || mimeType.includes("excel")) {
- return
;
+ return
;
}
if (mimeType.includes("presentation") || mimeType.includes("powerpoint")) {
- return
;
+ return
;
}
if (mimeType.includes("document") || mimeType.includes("word") || mimeType.includes("text")) {
- return
;
+ return
;
}
if (mimeType.includes("image")) {
- return
;
+ return
;
}
- return
;
+ return
;
}
export function ComposioDriveFolderTree({
@@ -73,13 +74,30 @@ export function ComposioDriveFolderTree({
onSelectFolders,
selectedFiles = [],
onSelectFiles = () => {},
+ onAuthError,
}: ComposioDriveFolderTreeProps) {
const [itemStates, setItemStates] = useState
);
diff --git a/surfsense_web/components/layout/ui/shell/LayoutShell.tsx b/surfsense_web/components/layout/ui/shell/LayoutShell.tsx
index e99bae22d..babd287e4 100644
--- a/surfsense_web/components/layout/ui/shell/LayoutShell.tsx
+++ b/surfsense_web/components/layout/ui/shell/LayoutShell.tsx
@@ -1,6 +1,7 @@
"use client";
-import { useMemo, useState } from "react";
+import { AnimatePresence, motion } from "motion/react";
+import { useCallback, useMemo, useState } from "react";
import { TooltipProvider } from "@/components/ui/tooltip";
import type { InboxItem } from "@/hooks/use-inbox";
import { useIsMobile } from "@/hooks/use-mobile";
@@ -12,15 +13,16 @@ import { Header } from "../header";
import { IconRail } from "../icon-rail";
import { RightPanel } from "../right-panel/RightPanel";
import {
- AllPrivateChatsSidebar,
- AllSharedChatsSidebar,
- AnnouncementsSidebar,
+ AllPrivateChatsSidebarContent,
+ AllSharedChatsSidebarContent,
+ AnnouncementsSidebarContent,
DocumentsSidebar,
- InboxSidebar,
+ InboxSidebarContent,
MobileSidebar,
MobileSidebarTrigger,
Sidebar,
} from "../sidebar";
+import { SidebarSlideOutPanel } from "../sidebar/SidebarSlideOutPanel";
// Per-tab data source
interface TabDataSource {
@@ -34,10 +36,11 @@ interface TabDataSource {
markAllAsRead: () => Promise