@@ -57,6 +57,11 @@ import Link from "next/link";
5757import { FlowTypeService } from "@edition/flowtype/services/FlowType.service" ;
5858import { icon } from "@core/util/icons" ;
5959import { formatDistanceToNow } from "date-fns" ;
60+ import { useFlowExecutionStore } from "@edition/flow/hooks/Flow.execution.hook" ;
61+ import { IconLoader2 } from "@tabler/icons-react" ;
62+ import { motion } from "framer-motion" ;
63+ import { LineWobble } from 'ldrs/react'
64+ import 'ldrs/react/LineWobble.css'
6065
6166export interface NodeGanttItem extends GanttItem {
6267 data ?: {
@@ -155,6 +160,33 @@ export const FlowExecutionResultView: React.FC = () => {
155160 [ flow ?. executionResults ?. nodes ]
156161 )
157162
163+ const executions = useFlowExecutionStore ( s => s . executions )
164+ const pendingExecutions = React . useMemo (
165+ ( ) => executions . filter ( execution => execution . flowId === flowId ) ,
166+ [ executions , flowId ]
167+ )
168+
169+ // When a manual execution is triggered elsewhere (the definition panel) its pending
170+ // entry appears here; focus its loading tab so the user sees the spinner immediately.
171+ const previousPendingRef = React . useRef < string [ ] > ( [ ] )
172+ React . useEffect ( ( ) => {
173+ const currentIds = pendingExecutions . map ( execution => execution . executionIdentifier )
174+ const newlyAdded = currentIds . find ( id => ! previousPendingRef . current . includes ( id ) )
175+ if ( newlyAdded ) setActiveTab ( newlyAdded )
176+ previousPendingRef . current = currentIds
177+ } , [ pendingExecutions ] )
178+
179+ // Once the pending execution resolves its loading tab disappears; fall back to the
180+ // newest result so the freshly arrived execution result becomes visible.
181+ React . useEffect ( ( ) => {
182+ if ( ! activeTab ) return
183+ const stillPending = pendingExecutions . some ( execution => execution . executionIdentifier === activeTab )
184+ const isResult = flowExecutionResults . some ( result => result ?. id === activeTab )
185+ if ( ! stillPending && ! isResult ) {
186+ setActiveTab ( flowExecutionResults [ 0 ] ?. id ?? undefined )
187+ }
188+ } , [ pendingExecutions , flowExecutionResults , activeTab ] )
189+
158190 const ganttItems = React . useMemo < Map < ExecutionResult [ 'id' ] , NodeGanttItem [ ] > > (
159191 ( ) => {
160192 return new Map < ExecutionResult [ "id" ] , NodeGanttItem [ ] > ( flowExecutionResults . map ( result => [ result ?. id , [
@@ -256,6 +288,21 @@ export const FlowExecutionResultView: React.FC = () => {
256288 ) : null
257289 }
258290 >
291+ { pendingExecutions . map ( execution => (
292+ < FileTabsTrigger value = { execution . executionIdentifier }
293+ key = { execution . executionIdentifier } >
294+ < Flex align = { "center" } style = { { gap : "0.35rem" } } >
295+ < motion . div style = { { display : "flex" } }
296+ animate = { { rotate : 360 } }
297+ transition = { { duration : 1 , ease : "linear" , repeat : Infinity } } >
298+ < IconLoader2 size = { 13 } />
299+ </ motion . div >
300+ < Text size = { "sm" } >
301+ Executing...
302+ </ Text >
303+ </ Flex >
304+ </ FileTabsTrigger >
305+ ) ) }
259306 { Array . from ( ganttItems ) ?. map ( ( [ id , items ] ) => {
260307
261308 const execution = flowExecutionResults . find ( execution => execution ?. id === id )
@@ -275,6 +322,34 @@ export const FlowExecutionResultView: React.FC = () => {
275322 } ) }
276323 </ FileTabsList > } >
277324 < >
325+ { pendingExecutions . map ( execution => (
326+ < FileTabsContent h = { "100%" }
327+ p = { "0" }
328+ value = { execution . executionIdentifier }
329+ key = { execution . executionIdentifier } >
330+ < Flex align = { "center" } justify = { "center" } h = { "100%" }
331+ style = { { textAlign : "center" , flexDirection : "column" } } >
332+ < LineWobble
333+ size = "200"
334+ stroke = "5"
335+ bgOpacity = "0.5"
336+ speed = "2"
337+ color = "rgba(255, 255, 255, 0.15)"
338+ />
339+ < Spacing spacing = { "xl" } />
340+ < Text size = { "md" } >
341+ Executing flow
342+ </ Text >
343+ < Spacing spacing = { "xs" } />
344+ < Text hierarchy = { "tertiary" } style = { {
345+ margin : "0 35%" ,
346+ textAlign : "center"
347+ } } >
348+ We are running your flow. This may take a few moments to load every data object.
349+ </ Text >
350+ </ Flex >
351+ </ FileTabsContent >
352+ ) ) }
278353 {
279354 ganttItems . size > 0 ? Array . from ( ganttItems ) ?. map ( ( [ id , items ] ) => {
280355 return < FileTabsContent h = { "100%" }
@@ -428,7 +503,7 @@ export const FlowExecutionResultView: React.FC = () => {
428503 } }
429504 </ Gantt >
430505 </ FileTabsContent >
431- } ) : (
506+ } ) : pendingExecutions . length > 0 ? null : (
432507 < Flex align = { "center" } justify = { "center" } h = { "100%" }
433508 style = { { textAlign : "center" , flexDirection : "column" } } >
434509 < Flex align = { "center" } justify = { "center" }
0 commit comments