11"use client" ;
22
3- import { useState } from "react" ;
4- import { Play , Loader2 , Workflow , ChevronDown , ChevronRight , Info , AlertCircle } from "lucide-react" ;
3+ import { Play , Loader2 , Workflow , AlertCircle } from "lucide-react" ;
54import { AccordionItem , AccordionTrigger , AccordionContent } from "@/components/ui/accordion" ;
65import { Badge } from "@/components/ui/badge" ;
76import { Button } from "@/components/ui/button" ;
87import { Select , SelectContent , SelectItem , SelectSeparator , SelectTrigger , SelectValue } from "@/components/ui/select" ;
98import { Alert , AlertDescription , AlertTitle } from "@/components/ui/alert" ;
10- import { Popover , PopoverContent , PopoverTrigger } from "@/components/ui/popover" ;
119import type { WorkflowConfig } from "../../lib/types" ;
1210
13- type WorkflowMetadata = {
14- commands : Array < { id : string ; name : string ; slashCommand : string ; description ?: string } > ;
15- agents : Array < { id : string ; name : string ; description ?: string } > ;
16- } ;
17-
1811type WorkflowsAccordionProps = {
1912 sessionPhase ?: string ;
2013 activeWorkflow : string | null ;
2114 selectedWorkflow : string ;
2215 pendingWorkflow : WorkflowConfig | null ;
2316 workflowActivating : boolean ;
24- workflowMetadata ?: WorkflowMetadata ;
2517 ootbWorkflows : WorkflowConfig [ ] ;
2618 isExpanded : boolean ;
2719 onWorkflowChange : ( value : string ) => void ;
2820 onActivateWorkflow : ( ) => void ;
29- onCommandClick : ( slashCommand : string ) => void ;
3021 onResume ?: ( ) => void ;
3122} ;
3223
@@ -36,21 +27,12 @@ export function WorkflowsAccordion({
3627 selectedWorkflow,
3728 pendingWorkflow,
3829 workflowActivating,
39- workflowMetadata,
4030 ootbWorkflows,
4131 isExpanded,
4232 onWorkflowChange,
4333 onActivateWorkflow,
44- onCommandClick,
4534 onResume,
4635} : WorkflowsAccordionProps ) {
47- const [ showCommandsList , setShowCommandsList ] = useState ( false ) ;
48- const [ showAgentsList , setShowAgentsList ] = useState ( false ) ;
49- const [ commandsScrollTop , setCommandsScrollTop ] = useState ( false ) ;
50- const [ commandsScrollBottom , setCommandsScrollBottom ] = useState ( true ) ;
51- const [ agentsScrollTop , setAgentsScrollTop ] = useState ( false ) ;
52- const [ agentsScrollBottom , setAgentsScrollBottom ] = useState ( true ) ;
53-
5436 const isSessionStopped = sessionPhase === 'Stopped' || sessionPhase === 'Error' || sessionPhase === 'Completed' ;
5537
5638 return (
@@ -167,171 +149,7 @@ export function WorkflowsAccordion({
167149
168150 { /* Show active workflow info */ }
169151 { activeWorkflow && ! workflowActivating && (
170- < >
171- { /* Commands Section */ }
172- { workflowMetadata ?. commands && workflowMetadata . commands . length > 0 && (
173- < div className = "space-y-2" >
174- < div >
175- < Button
176- variant = "ghost"
177- size = "sm"
178- className = "w-full justify-between h-8 px-2"
179- onClick = { ( ) => setShowCommandsList ( ! showCommandsList ) }
180- >
181- < span className = "text-xs font-medium" >
182- { showCommandsList ? 'Hide' : 'Show' } { workflowMetadata . commands . length } available command{ workflowMetadata . commands . length !== 1 ? 's' : '' }
183- </ span >
184- { showCommandsList ? (
185- < ChevronDown className = "h-3 w-3" />
186- ) : (
187- < ChevronRight className = "h-3 w-3" />
188- ) }
189- </ Button >
190-
191- { showCommandsList && (
192- < div className = "relative mt-2" >
193- { commandsScrollTop && (
194- < div className = "absolute top-0 left-0 right-0 h-8 bg-gradient-to-b from-card to-transparent pointer-events-none z-10" />
195- ) }
196- < div
197- className = "max-h-[400px] overflow-y-auto space-y-2 pr-1"
198- onScroll = { ( e ) => {
199- const target = e . currentTarget ;
200- const isScrolledFromTop = target . scrollTop > 10 ;
201- const isScrolledToBottom = target . scrollHeight - target . scrollTop <= target . clientHeight + 10 ;
202- setCommandsScrollTop ( isScrolledFromTop ) ;
203- setCommandsScrollBottom ( ! isScrolledToBottom ) ;
204- } }
205- >
206- { workflowMetadata . commands . map ( ( cmd ) => {
207- const commandTitle = cmd . name . includes ( '.' )
208- ? cmd . name . split ( '.' ) . pop ( )
209- : cmd . name ;
210-
211- return (
212- < div
213- key = { cmd . id }
214- className = "p-3 rounded-md border bg-muted/30"
215- >
216- < div className = "flex items-center justify-between mb-1" >
217- < h3 className = "text-sm font-bold capitalize" >
218- { commandTitle }
219- </ h3 >
220- < Button
221- variant = "outline"
222- size = "sm"
223- className = "flex-shrink-0 h-7 text-xs"
224- onClick = { ( ) => onCommandClick ( cmd . slashCommand ) }
225- >
226- Run { cmd . slashCommand . replace ( / ^ \/ s p e c k i t \. / , '/' ) }
227- </ Button >
228- </ div >
229- { cmd . description && (
230- < p className = "text-xs text-muted-foreground" >
231- { cmd . description }
232- </ p >
233- ) }
234- </ div >
235- ) ;
236- } ) }
237- </ div >
238- { commandsScrollBottom && (
239- < div className = "absolute bottom-0 left-0 right-0 h-8 bg-gradient-to-t from-card to-transparent pointer-events-none z-10" />
240- ) }
241- </ div >
242- ) }
243- </ div >
244- </ div >
245- ) }
246-
247- { workflowMetadata ?. commands ?. length === 0 && (
248- < p className = "text-xs text-muted-foreground text-left py-2" >
249- No commands found in this workflow
250- </ p >
251- ) }
252-
253- { /* Agents Section */ }
254- { workflowMetadata ?. agents && workflowMetadata . agents . length > 0 && (
255- < div className = "space-y-2" >
256- < div >
257- < Button
258- variant = "ghost"
259- size = "sm"
260- className = "w-full justify-between h-8 px-2"
261- onClick = { ( ) => setShowAgentsList ( ! showAgentsList ) }
262- >
263- < span className = "text-xs font-medium" >
264- { showAgentsList ? 'Hide' : 'Show' } { workflowMetadata . agents . length } available agent{ workflowMetadata . agents . length !== 1 ? 's' : '' }
265- </ span >
266- { showAgentsList ? (
267- < ChevronDown className = "h-3 w-3" />
268- ) : (
269- < ChevronRight className = "h-3 w-3" />
270- ) }
271- </ Button >
272-
273- { showAgentsList && (
274- < div className = "mt-2 pt-2 mx-3 space-y-2" >
275- { /* Scrollable agents list */ }
276- < div className = "relative" >
277- { agentsScrollTop && (
278- < div className = "absolute top-0 left-0 right-0 h-8 bg-gradient-to-b from-card to-transparent pointer-events-none z-10" />
279- ) }
280- < div
281- className = "max-h-48 overflow-y-auto space-y-1 pr-1"
282- onScroll = { ( e ) => {
283- const target = e . currentTarget ;
284- const isScrolledFromTop = target . scrollTop > 10 ;
285- const isScrolledToBottom = target . scrollHeight - target . scrollTop <= target . clientHeight + 10 ;
286- setAgentsScrollTop ( isScrolledFromTop ) ;
287- setAgentsScrollBottom ( ! isScrolledToBottom ) ;
288- } }
289- >
290- < div className = "space-y-1 space-x-6" >
291- { workflowMetadata . agents . map ( ( agent ) => (
292- < div key = { agent . id } className = "flex items-center gap-2 group" >
293- < span className = "text-sm font-normal" >
294- { agent . name }
295- </ span >
296- < Popover >
297- < PopoverTrigger asChild >
298- < button
299- className = "p-0.5 hover:bg-muted rounded flex-shrink-0"
300- onClick = { ( e ) => {
301- e . preventDefault ( ) ;
302- e . stopPropagation ( ) ;
303- } }
304- >
305- < Info className = "h-3.5 w-3.5 text-muted-foreground" />
306- </ button >
307- </ PopoverTrigger >
308- < PopoverContent className = "max-w-xs" align = "start" >
309- < div className = "space-y-2" >
310- < p className = "font-semibold text-sm" > { agent . name } </ p >
311- < p className = "text-xs text-muted-foreground" > { agent . description } </ p >
312- </ div >
313- </ PopoverContent >
314- </ Popover >
315- </ div >
316- ) ) }
317- </ div >
318- </ div >
319- { agentsScrollBottom && (
320- < div className = "absolute bottom-0 left-0 right-0 h-8 bg-gradient-to-t from-card to-transparent pointer-events-none z-10" />
321- ) }
322- </ div >
323- </ div >
324- ) }
325- </ div >
326- </ div >
327- ) }
328-
329- { workflowMetadata ?. agents ?. length === 0 && (
330- < p className = "text-xs text-muted-foreground text-left py-2" >
331- No agents found in this workflow
332- </ p >
333- ) }
334- </ >
152+ < > </ >
335153 ) }
336154
337155 { /* Show activating/switching state */ }
0 commit comments