Skip to content

Commit 2cac29a

Browse files
committed
feat: enhance FlowExecutionResultView with pending execution indicators and loading animations
1 parent 3b9c5e1 commit 2cac29a

1 file changed

Lines changed: 76 additions & 1 deletion

File tree

src/packages/ce/src/flow/views/FlowExecutionResultView.tsx

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ import Link from "next/link";
5757
import {FlowTypeService} from "@edition/flowtype/services/FlowType.service";
5858
import {icon} from "@core/util/icons";
5959
import {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

6166
export 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

Comments
 (0)