mirror of https://github.com/kortix-ai/suna.git
Merge pull request #1510 from kubet/fix/task-triggers
fix: task responsive panel
This commit is contained in:
commit
b3987b06e6
|
@ -440,7 +440,7 @@ export const EventBasedTriggerDialog: React.FC<EventBasedTriggerDialogProps> = (
|
|||
console.error('Details keys:', Object.keys(e.details));
|
||||
console.error('Details content:', JSON.stringify(e.details, null, 2));
|
||||
}
|
||||
|
||||
|
||||
// Check for details property from api-client.ts error structure
|
||||
if (e?.details?.detail?.error?.message) {
|
||||
errorMessage = e.details.detail.error.message;
|
||||
|
|
|
@ -59,27 +59,27 @@ const SCHEDULE_PRESETS = [
|
|||
|
||||
const getScheduleDisplay = (cron?: string) => {
|
||||
if (!cron) return { name: 'Not configured', icon: <Clock className="h-4 w-4" /> };
|
||||
|
||||
|
||||
const preset = SCHEDULE_PRESETS.find(p => p.cron === cron);
|
||||
if (preset) return preset;
|
||||
|
||||
|
||||
return { name: cron, icon: <Clock className="h-4 w-4" /> };
|
||||
};
|
||||
|
||||
export function SimplifiedTriggerDetailPanel({ trigger, onClose }: SimplifiedTriggerDetailPanelProps) {
|
||||
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
|
||||
const [showEditDialog, setShowEditDialog] = useState(false);
|
||||
|
||||
|
||||
const deleteMutation = useDeleteTrigger();
|
||||
const toggleMutation = useToggleTrigger();
|
||||
const updateMutation = useUpdateTrigger();
|
||||
|
||||
|
||||
const { data: workflows = [] } = useAgentWorkflows(trigger.agent_id);
|
||||
const workflowName = workflows.find(w => w.id === trigger.config?.workflow_id)?.name;
|
||||
|
||||
|
||||
const isScheduled = trigger.trigger_type.toLowerCase() === 'schedule' || trigger.trigger_type.toLowerCase() === 'scheduled';
|
||||
const scheduleDisplay = getScheduleDisplay(trigger.config?.cron_expression);
|
||||
|
||||
|
||||
const handleToggle = async () => {
|
||||
try {
|
||||
await toggleMutation.mutateAsync({
|
||||
|
@ -92,7 +92,7 @@ export function SimplifiedTriggerDetailPanel({ trigger, onClose }: SimplifiedTri
|
|||
console.error('Error toggling task:', error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const handleDelete = async () => {
|
||||
try {
|
||||
await deleteMutation.mutateAsync({
|
||||
|
@ -106,7 +106,7 @@ export function SimplifiedTriggerDetailPanel({ trigger, onClose }: SimplifiedTri
|
|||
console.error('Error deleting task:', error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const handleEditSave = async (config: any) => {
|
||||
try {
|
||||
await updateMutation.mutateAsync({
|
||||
|
@ -123,9 +123,9 @@ export function SimplifiedTriggerDetailPanel({ trigger, onClose }: SimplifiedTri
|
|||
console.error('Error updating task:', error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const isLoading = deleteMutation.isPending || toggleMutation.isPending || updateMutation.isPending;
|
||||
|
||||
|
||||
const provider = {
|
||||
provider_id: isScheduled ? 'schedule' : trigger.provider_id,
|
||||
name: trigger.name,
|
||||
|
@ -134,7 +134,7 @@ export function SimplifiedTriggerDetailPanel({ trigger, onClose }: SimplifiedTri
|
|||
webhook_enabled: !!trigger.webhook_url,
|
||||
config_schema: {}
|
||||
};
|
||||
|
||||
|
||||
const triggerConfig = {
|
||||
trigger_id: trigger.trigger_id,
|
||||
agent_id: trigger.agent_id,
|
||||
|
@ -150,15 +150,15 @@ export function SimplifiedTriggerDetailPanel({ trigger, onClose }: SimplifiedTri
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="h-full bg-white flex flex-col">
|
||||
<div className={"h-full bg-white flex flex-col w-full sm:w-[440px] xl:w-2xl"}>
|
||||
{/* Header */}
|
||||
<div className="px-8 py-6 border-b border-gray-200">
|
||||
<div className="flex items-start justify-between mb-6">
|
||||
<div className="flex-1">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<h1 className="text-2xl font-medium text-black">{trigger.name}</h1>
|
||||
<Badge
|
||||
variant={trigger.is_active ? "highlight" : "secondary"}
|
||||
<Badge
|
||||
variant={trigger.is_active ? "highlight" : "secondary"}
|
||||
className="text-xs"
|
||||
>
|
||||
{trigger.is_active ? "Active" : "Inactive"}
|
||||
|
@ -207,8 +207,8 @@ export function SimplifiedTriggerDetailPanel({ trigger, onClose }: SimplifiedTri
|
|||
disabled={isLoading}
|
||||
className={cn(
|
||||
"flex-1 border-gray-200",
|
||||
trigger.is_active
|
||||
? "hover:bg-gray-50"
|
||||
trigger.is_active
|
||||
? "hover:bg-gray-50"
|
||||
: "bg-black hover:bg-gray-900 text-white"
|
||||
)}
|
||||
>
|
||||
|
@ -259,7 +259,7 @@ export function SimplifiedTriggerDetailPanel({ trigger, onClose }: SimplifiedTri
|
|||
{trigger.config?.execution_type === 'agent' ? 'Agent Instructions' : 'Workflow Execution'}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-600">
|
||||
{trigger.config?.execution_type === 'agent'
|
||||
{trigger.config?.execution_type === 'agent'
|
||||
? 'Custom prompt for the agent'
|
||||
: `Runs workflow: ${workflowName || 'Unknown'}`
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ export function SimplifiedTriggerDetailPanel({ trigger, onClose }: SimplifiedTri
|
|||
<p className="text-sm text-gray-600">Assigned Agent</p>
|
||||
</div>
|
||||
</div>
|
||||
<Link
|
||||
<Link
|
||||
href={`/agents/config/${trigger.agent_id}`}
|
||||
className="p-2 rounded-lg hover:bg-gray-100 transition-colors"
|
||||
>
|
||||
|
|
|
@ -12,8 +12,8 @@ import {
|
|||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import {
|
||||
MessageSquare,
|
||||
import {
|
||||
MessageSquare,
|
||||
Github,
|
||||
Slack,
|
||||
Clock,
|
||||
|
@ -61,12 +61,12 @@ const getTriggerCategory = (triggerType: string): 'scheduled' | 'app' => {
|
|||
|
||||
const formatCronExpression = (cron?: string) => {
|
||||
if (!cron) return 'Not configured';
|
||||
|
||||
|
||||
const parts = cron.split(' ');
|
||||
if (parts.length !== 5) return cron;
|
||||
|
||||
|
||||
const [minute, hour, dayOfMonth, month, dayOfWeek] = parts;
|
||||
|
||||
|
||||
if (minute === '0' && hour === '0' && dayOfMonth === '*' && month === '*' && dayOfWeek === '*') {
|
||||
return 'Daily at midnight';
|
||||
}
|
||||
|
@ -85,24 +85,24 @@ const formatCronExpression = (cron?: string) => {
|
|||
if (minute === '0' && hour === String(hour) && dayOfMonth === '*' && month === '*' && dayOfWeek === '*') {
|
||||
return `Daily at ${hour}:${minute.padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
|
||||
return cron;
|
||||
};
|
||||
|
||||
const TriggerListItem = ({
|
||||
trigger,
|
||||
const TriggerListItem = ({
|
||||
trigger,
|
||||
onClick,
|
||||
isSelected
|
||||
}: {
|
||||
}: {
|
||||
trigger: TriggerWithAgent;
|
||||
onClick: () => void;
|
||||
isSelected: boolean;
|
||||
}) => {
|
||||
const Icon = getTriggerIcon(trigger.trigger_type);
|
||||
const isScheduled = getTriggerCategory(trigger.trigger_type) === 'scheduled';
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
<div
|
||||
onClick={onClick}
|
||||
className={cn(
|
||||
"rounded-xl border group flex items-center justify-between px-4 py-3 cursor-pointer transition-all",
|
||||
|
@ -114,8 +114,8 @@ const TriggerListItem = ({
|
|||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-medium text-sm truncate">{trigger.name}</span>
|
||||
<Badge
|
||||
variant={trigger.is_active ? "highlight" : "secondary"}
|
||||
<Badge
|
||||
variant={trigger.is_active ? "highlight" : "secondary"}
|
||||
className="text-xs"
|
||||
>
|
||||
{trigger.is_active ? "Active" : "Inactive"}
|
||||
|
@ -172,7 +172,7 @@ export function TasksPage() {
|
|||
const [selectedTrigger, setSelectedTrigger] = useState<TriggerWithAgent | null>(null);
|
||||
const [triggerDialogType, setTriggerDialogType] = useState<'schedule' | 'event' | null>(null);
|
||||
const [pendingTriggerId, setPendingTriggerId] = useState<string | null>(null);
|
||||
|
||||
|
||||
const sortedTriggers = useMemo(() => {
|
||||
return [...triggers].sort((a, b) => {
|
||||
if (a.is_active !== b.is_active) {
|
||||
|
@ -181,7 +181,7 @@ export function TasksPage() {
|
|||
return new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime();
|
||||
});
|
||||
}, [triggers]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (pendingTriggerId) {
|
||||
const newTrigger = triggers.find(t => t.trigger_id === pendingTriggerId);
|
||||
|
@ -191,7 +191,7 @@ export function TasksPage() {
|
|||
}
|
||||
}
|
||||
}, [triggers, pendingTriggerId]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedTrigger) {
|
||||
const updatedTrigger = triggers.find(t => t.trigger_id === selectedTrigger.trigger_id);
|
||||
|
@ -202,16 +202,16 @@ export function TasksPage() {
|
|||
}
|
||||
}
|
||||
}, [triggers, selectedTrigger?.trigger_id]);
|
||||
|
||||
|
||||
const handleClosePanel = () => {
|
||||
setSelectedTrigger(null);
|
||||
};
|
||||
|
||||
|
||||
const handleTriggerCreated = (triggerId: string) => {
|
||||
setTriggerDialogType(null);
|
||||
setPendingTriggerId(triggerId);
|
||||
};
|
||||
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div className="h-screen flex flex-col">
|
||||
|
@ -226,7 +226,7 @@ export function TasksPage() {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className="h-screen flex overflow-hidden">
|
||||
<div className="flex-1 flex flex-col overflow-hidden">
|
||||
|
@ -302,7 +302,9 @@ export function TasksPage() {
|
|||
</div>
|
||||
<div className={cn(
|
||||
"h-screen transition-all duration-300 ease-in-out overflow-hidden border-l",
|
||||
selectedTrigger ? "w-2xl" : "w-0"
|
||||
selectedTrigger
|
||||
? "w-full sm:w-[440px] xl:w-2xl"
|
||||
: "w-0"
|
||||
)}>
|
||||
{selectedTrigger && (
|
||||
<SimplifiedTriggerDetailPanel
|
||||
|
|
|
@ -34,9 +34,9 @@ export function TriggerCreationDialog({
|
|||
const [step, setStep] = useState<'agent' | 'config'>('agent');
|
||||
const [name, setName] = useState<string>('');
|
||||
const [description, setDescription] = useState<string>('');
|
||||
const [config, setConfig] = useState<ScheduleTriggerConfig>({
|
||||
cron_expression: '',
|
||||
execution_type: 'agent'
|
||||
const [config, setConfig] = useState<ScheduleTriggerConfig>({
|
||||
cron_expression: '',
|
||||
execution_type: 'agent'
|
||||
});
|
||||
const createTriggerMutation = useCreateTrigger();
|
||||
|
||||
|
|
Loading…
Reference in New Issue