diff --git a/apps/rowboat/app/projects/[projectId]/job-rules/components/job-rules-tabs.tsx b/apps/rowboat/app/projects/[projectId]/job-rules/components/job-rules-tabs.tsx index c5a7cf17..32d01d2d 100644 --- a/apps/rowboat/app/projects/[projectId]/job-rules/components/job-rules-tabs.tsx +++ b/apps/rowboat/app/projects/[projectId]/job-rules/components/job-rules-tabs.tsx @@ -4,9 +4,10 @@ import { useState } from "react"; import { Tabs, Tab } from "@/components/ui/tabs"; import { ScheduledJobRulesList } from "../scheduled/components/scheduled-job-rules-list"; import { RecurringJobRulesList } from "./recurring-job-rules-list"; +import { TriggersTab } from "./triggers-tab"; export function JobRulesTabs({ projectId }: { projectId: string }) { - const [activeTab, setActiveTab] = useState("scheduled"); + const [activeTab, setActiveTab] = useState("triggers"); const handleTabChange = (key: React.Key) => { setActiveTab(key.toString()); @@ -20,10 +21,13 @@ export function JobRulesTabs({ projectId }: { projectId: string }) { aria-label="Job Rules" fullWidth > - + + + + - + diff --git a/apps/rowboat/app/projects/[projectId]/workflow/components/TriggersModal.tsx b/apps/rowboat/app/projects/[projectId]/job-rules/components/triggers-tab.tsx similarity index 88% rename from apps/rowboat/app/projects/[projectId]/workflow/components/TriggersModal.tsx rename to apps/rowboat/app/projects/[projectId]/job-rules/components/triggers-tab.tsx index 3ec1a906..9d7d9afe 100644 --- a/apps/rowboat/app/projects/[projectId]/workflow/components/TriggersModal.tsx +++ b/apps/rowboat/app/projects/[projectId]/job-rules/components/triggers-tab.tsx @@ -1,36 +1,23 @@ 'use client'; import React, { useState, useEffect, useCallback } from 'react'; -import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, Button, Spinner, Card, CardBody, CardHeader } from '@heroui/react'; +import { Button, Spinner, Card, CardBody, CardHeader } from '@heroui/react'; import { Plus, Trash2, ZapIcon } from 'lucide-react'; import { z } from 'zod'; import { ComposioTriggerDeployment } from '@/src/entities/models/composio-trigger-deployment'; import { ComposioTriggerType } from '@/src/entities/models/composio-trigger-type'; import { listComposioTriggerDeployments, deleteComposioTriggerDeployment, createComposioTriggerDeployment } from '@/app/actions/composio.actions'; import { SelectComposioToolkit } from '../../tools/components/SelectComposioToolkit'; -import { ComposioTriggerTypesPanel } from './ComposioTriggerTypesPanel'; -import { TriggerConfigForm } from './TriggerConfigForm'; +import { ComposioTriggerTypesPanel } from '../../workflow/components/ComposioTriggerTypesPanel'; +import { TriggerConfigForm } from '../../workflow/components/TriggerConfigForm'; import { ToolkitAuthModal } from '../../tools/components/ToolkitAuthModal'; import { ZToolkit } from "@/src/application/lib/composio/types"; import { Project } from "@/src/entities/models/project"; - -interface TriggersModalProps { - isOpen: boolean; - onClose: () => void; - projectId: string; - projectConfig: z.infer; - onProjectConfigUpdated?: () => void; -} +import { fetchProject } from '@/app/actions/project.actions'; type TriggerDeployment = z.infer; -export function TriggersModal({ - isOpen, - onClose, - projectId, - projectConfig, - onProjectConfigUpdated, -}: TriggersModalProps) { +export function TriggersTab({ projectId }: { projectId: string }) { const [triggers, setTriggers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); @@ -40,6 +27,16 @@ export function TriggersModal({ const [showAuthModal, setShowAuthModal] = useState(false); const [isSubmittingTrigger, setIsSubmittingTrigger] = useState(false); const [deletingTrigger, setDeletingTrigger] = useState(null); + const [projectConfig, setProjectConfig] = useState | null>(null); + + const loadProjectConfig = useCallback(async () => { + try { + const config = await fetchProject(projectId); + setProjectConfig(config); + } catch (err: any) { + console.error('Error fetching project config:', err); + } + }, [projectId]); const loadTriggers = useCallback(async () => { try { @@ -115,7 +112,7 @@ export function TriggersModal({ const handleAuthComplete = async () => { setShowAuthModal(false); - onProjectConfigUpdated?.(); + await loadProjectConfig(); // Refresh project config }; const handleTriggerSubmit = async (triggerConfig: Record) => { @@ -151,10 +148,14 @@ export function TriggersModal({ }; useEffect(() => { - if (isOpen && !showCreateFlow) { + loadProjectConfig(); + }, [loadProjectConfig]); + + useEffect(() => { + if (!showCreateFlow) { loadTriggers(); } - }, [isOpen, showCreateFlow, loadTriggers]); + }, [showCreateFlow, loadTriggers]); const renderTriggerList = () => { if (loading) { @@ -319,31 +320,11 @@ export function TriggersModal({ return ( <> - - - -
- - Manage Triggers -
-
- - {showCreateFlow ? renderCreateFlow() : renderTriggerList()} - - {!showCreateFlow && ( - - - - )} -
-
+
+
+ {showCreateFlow ? renderCreateFlow() : renderTriggerList()} +
+
{/* Auth Modal */} {selectedToolkit && ( @@ -357,4 +338,4 @@ export function TriggersModal({ )} ); -} \ No newline at end of file +} diff --git a/apps/rowboat/app/projects/[projectId]/job-rules/page.tsx b/apps/rowboat/app/projects/[projectId]/job-rules/page.tsx index a6149b91..b7ce6e4c 100644 --- a/apps/rowboat/app/projects/[projectId]/job-rules/page.tsx +++ b/apps/rowboat/app/projects/[projectId]/job-rules/page.tsx @@ -3,7 +3,7 @@ import { requireActiveBillingSubscription } from '@/app/lib/billing'; import { JobRulesTabs } from "./components/job-rules-tabs"; export const metadata: Metadata = { - title: "Job Rules", + title: "Triggers", }; export default async function Page( diff --git a/apps/rowboat/app/projects/[projectId]/workflow/components/TopBar.tsx b/apps/rowboat/app/projects/[projectId]/workflow/components/TopBar.tsx index 1fcb772f..4a948f50 100644 --- a/apps/rowboat/app/projects/[projectId]/workflow/components/TopBar.tsx +++ b/apps/rowboat/app/projects/[projectId]/workflow/components/TopBar.tsx @@ -8,7 +8,7 @@ interface TopBarProps { localProjectName: string; projectNameError: string | null; onProjectNameChange: (value: string) => void; - onProjectNameCommit: (value: string) => void; + onProjectNameCommit: (value: string) => Promise; publishing: boolean; isLive: boolean; showCopySuccess: boolean; @@ -23,7 +23,6 @@ interface TopBarProps { onRevertToLive: () => void; onToggleCopilot: () => void; onSettingsModalOpen: () => void; - onTriggersModalOpen: () => void; } export function TopBar({ @@ -45,7 +44,6 @@ export function TopBar({ onRevertToLive, onToggleCopilot, onSettingsModalOpen, - onTriggersModalOpen, }: TopBarProps) { const router = useRouter(); const params = useParams(); @@ -168,16 +166,9 @@ export function TopBar({ } - onPress={onTriggersModalOpen} - > - Manage triggers - - } onPress={() => { if (projectId) { router.push(`/projects/${projectId}/job-rules`); } }} > - Go to schedule runs + Manage triggers {!isLive ? ( <> diff --git a/apps/rowboat/app/projects/[projectId]/workflow/workflow_editor.tsx b/apps/rowboat/app/projects/[projectId]/workflow/workflow_editor.tsx index 1ca97033..f677f96d 100644 --- a/apps/rowboat/app/projects/[projectId]/workflow/workflow_editor.tsx +++ b/apps/rowboat/app/projects/[projectId]/workflow/workflow_editor.tsx @@ -37,7 +37,6 @@ import { Button as CustomButton } from "@/components/ui/button"; import { ConfigApp } from "../config/app"; import { InputField } from "@/app/lib/components/input-field"; import { VoiceSection } from "../config/components/voice"; -import { TriggersModal } from "./components/TriggersModal"; import { TopBar } from "./components/TopBar"; enablePatches(); @@ -882,9 +881,6 @@ export function WorkflowEditor({ // Modal state for chat widget configuration const { isOpen: isChatWidgetModalOpen, onOpen: onChatWidgetModalOpen, onClose: onChatWidgetModalClose } = useDisclosure(); - // Modal state for triggers management - const { isOpen: isTriggersModalOpen, onOpen: onTriggersModalOpen, onClose: onTriggersModalClose } = useDisclosure(); - // Project name state const [localProjectName, setLocalProjectName] = useState(projectConfig.name || ''); const [projectNameError, setProjectNameError] = useState(null); @@ -1285,7 +1281,6 @@ export function WorkflowEditor({ onRevertToLive={handleRevertToLive} onToggleCopilot={() => setShowCopilot(!showCopilot)} onSettingsModalOpen={onSettingsModalOpen} - onTriggersModalOpen={onTriggersModalOpen} /> {/* Content Area */} @@ -1565,14 +1560,6 @@ export function WorkflowEditor({ */} - {/* Triggers Management Modal */} - ); diff --git a/apps/rowboat/app/projects/layout/components/sidebar.tsx b/apps/rowboat/app/projects/layout/components/sidebar.tsx index 25085c69..53b6192e 100644 --- a/apps/rowboat/app/projects/layout/components/sidebar.tsx +++ b/apps/rowboat/app/projects/layout/components/sidebar.tsx @@ -17,7 +17,8 @@ import { HelpCircle, MessageSquareIcon, LogsIcon, - Clock + Clock, + ZapIcon } from "lucide-react"; import { fetchProject } from "@/app/actions/project.actions"; import { createProjectWithOptions } from "../../lib/project-creation-utils"; @@ -102,6 +103,12 @@ export default function Sidebar({ projectId, useAuth, collapsed = false, onToggl icon: WorkflowIcon, requiresProject: true }, + { + href: 'job-rules', + label: 'Triggers', + icon: ZapIcon, + requiresProject: true + }, { href: 'conversations', label: 'Conversations', @@ -114,12 +121,6 @@ export default function Sidebar({ projectId, useAuth, collapsed = false, onToggl icon: LogsIcon, requiresProject: true }, - { - href: 'job-rules', - label: 'Job Rules', - icon: Clock, - requiresProject: true - }, { href: 'config', label: 'Settings',