From 9bee47ea4d7009b5614b81b1ef534271f87a9705 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Fri, 10 Nov 2023 10:01:22 -0300 Subject: [PATCH 1/5] fix: dont map node_modules on docker compose --- docker-compose-dev.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index 0f53d297..677fe4ae 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -367,6 +367,7 @@ services: - 3000:3000 volumes: - ./frontend:/usr/src/app # Enable hot reload for frontend + - /usr/src/app/node_modules depends_on: domino_rest: condition: service_started From 37c8f72539887427cb2e25c2cf6c674ceaa884d3 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Mon, 13 Nov 2023 11:36:53 -0300 Subject: [PATCH 2/5] feat: improve change selected run --- .../WorkflowDetail/WorkflowRunDetail.tsx | 209 ++++++----- .../WorkflowDetail/WorkflowRunsTable.tsx | 326 +++++++++--------- .../components/WorkflowDetail/index.tsx | 54 ++- 3 files changed, 319 insertions(+), 270 deletions(-) diff --git a/frontend/src/features/myWorkflows/components/WorkflowDetail/WorkflowRunDetail.tsx b/frontend/src/features/myWorkflows/components/WorkflowDetail/WorkflowRunDetail.tsx index ec5e5413..83980eb0 100644 --- a/frontend/src/features/myWorkflows/components/WorkflowDetail/WorkflowRunDetail.tsx +++ b/frontend/src/features/myWorkflows/components/WorkflowDetail/WorkflowRunDetail.tsx @@ -4,8 +4,14 @@ import { useAuthenticatedGetWorkflowRunTaskLogs, useAuthenticatedGetWorkflowRunTaskResult, } from "features/myWorkflows/api"; -import React, { useCallback, useMemo, useState } from "react"; -import { useInterval } from "utils"; +import React, { + forwardRef, + useCallback, + useImperativeHandle, + useMemo, + useState, +} from "react"; +import { type KeyedMutator } from "swr"; import { CustomTabMenu, CustomTabPanel } from "./CustomTabMenu"; import { TaskDetails } from "./CustomTabMenu/TaskDetail"; @@ -19,104 +25,121 @@ interface Props { nodeId: string | null; tasks: IWorkflowRunTaskExtended[] | null; workflowId: string; - autoUpdate: boolean; } -export const WorkflowRunDetail: React.FC = ({ - runId, - nodeId, - tasks, - workflowId, - autoUpdate, -}) => { - const [value, setValue] = useState(0); +export interface WorkflowRunDetailRef { + refreshTaskResults: KeyedMutator< + | { + base64_content: string; + file_type: string; + } + | undefined + >; + refreshTaskLogs: KeyedMutator< + | { + data: string[]; + } + | undefined + >; +} - const taskData = useMemo(() => { - if (nodeId) { - const task = tasks?.find((task) => { - return task.task_id === nodeId; - }); +export const WorkflowRunDetail = forwardRef( + ({ runId, nodeId, tasks, workflowId }, ref) => { + const [value, setValue] = useState(0); - return task; - } - }, [nodeId, tasks]); + const taskData = useMemo(() => { + if (nodeId) { + const task = tasks?.find((task) => { + return task.task_id === nodeId; + }); - const { data: taskLogs } = useAuthenticatedGetWorkflowRunTaskLogs({ - runId: runId ?? "", - taskId: taskData?.task_id ?? "", - taskTryNumber: String(taskData?.try_number) ?? "", - workflowId, - }); + return task; + } + }, [nodeId, tasks]); - const { - data: taskResult, - isLoading, - mutate, - } = useAuthenticatedGetWorkflowRunTaskResult({ - runId: runId ?? "", - taskId: taskData?.task_id ?? "", - taskTryNumber: String(taskData?.try_number) ?? "", - workflowId, - }); + const { data: taskLogs, mutate: refreshTaskLogs } = + useAuthenticatedGetWorkflowRunTaskLogs({ + runId: runId ?? "", + taskId: taskData?.task_id ?? "", + taskTryNumber: String(taskData?.try_number) ?? "", + workflowId, + }); - const handleChange = useCallback( - (_event: React.SyntheticEvent, newValue: number) => { - setValue(newValue); - }, - [], - ); + const { + data: taskResult, + isLoading, + mutate: refreshTaskResults, + } = useAuthenticatedGetWorkflowRunTaskResult({ + runId: runId ?? "", + taskId: taskData?.task_id ?? "", + taskTryNumber: String(taskData?.try_number) ?? "", + workflowId, + }); - useInterval(mutate, 1000, autoUpdate); + const handleChange = useCallback( + (_event: React.SyntheticEvent, newValue: number) => { + setValue(newValue); + }, + [], + ); - return ( - - {runId ? ( - nodeId ? ( - - {taskData && ( - <> - - - - - - - - - - - )} - - ) : ( - - ({ + refreshTaskResults, + refreshTaskLogs, + })); + + return ( + + {runId ? ( + nodeId ? ( + + {taskData && ( + <> + + + + + + + + + + + )} + + ) : ( + - Select a domino piece - - - ) - ) : ( - - )} - - ); -}; + + Select a domino piece + + + ) + ) : ( + + )} + + ); + }, +); + +WorkflowRunDetail.displayName = "WorkflowRunDetail"; diff --git a/frontend/src/features/myWorkflows/components/WorkflowDetail/WorkflowRunsTable.tsx b/frontend/src/features/myWorkflows/components/WorkflowDetail/WorkflowRunsTable.tsx index d41021e2..ccb4b181 100644 --- a/frontend/src/features/myWorkflows/components/WorkflowDetail/WorkflowRunsTable.tsx +++ b/frontend/src/features/myWorkflows/components/WorkflowDetail/WorkflowRunsTable.tsx @@ -3,8 +3,13 @@ import { DataGrid, type GridColDef } from "@mui/x-data-grid"; import { NoDataOverlay } from "components/NoDataOverlay"; import { useAuthenticatedGetWorkflowRuns } from "features/myWorkflows/api"; import { type IWorkflowRuns } from "features/myWorkflows/types"; -import React, { useCallback, useEffect, useMemo, useState } from "react"; -import { useInterval } from "utils"; +import React, { + forwardRef, + useEffect, + useImperativeHandle, + useMemo, + useState, +} from "react"; import { States } from "./States"; import { WorkflowRunTableFooter } from "./WorkflowRunTableFooter"; @@ -12,179 +17,170 @@ import { WorkflowRunTableFooter } from "./WorkflowRunTableFooter"; interface Props { workflowId: string; selectedRun: IWorkflowRuns | null; - autoUpdate: boolean; - setAutoUpdate: React.Dispatch>; onSelectedRunChange: (run: IWorkflowRuns | null) => void; triggerRun: () => void; } -export const WorkflowRunsTable: React.FC = ({ - workflowId, - selectedRun, - onSelectedRunChange: setSelectedRun, - triggerRun, - autoUpdate, - setAutoUpdate, -}) => { - const [paginationModel, setPaginationModel] = useState({ - pageSize: 10, - page: 0, - }); +export interface WorkflowRunsTableRef { + refetchWorkflowsRun: () => void; +} - const { - data: workflowRuns, - isLoading, - mutate: refetchWorkflowsRun, - } = useAuthenticatedGetWorkflowRuns({ - page: paginationModel.page, - pageSize: paginationModel.pageSize, - workflowId, - }); +export const WorkflowRunsTable = forwardRef( + ( + { + workflowId, + selectedRun, + onSelectedRunChange: setSelectedRun, + triggerRun, + }, + ref, + ) => { + const [paginationModel, setPaginationModel] = useState({ + pageSize: 10, + page: 0, + }); - const handleRefreshWorkflowsRuns = useCallback(async () => { - if ( - workflowRuns && - workflowRuns.data?.some( - (wr) => wr.state !== "success" && wr.state !== "failed", - ) - ) { - setAutoUpdate(true); - } else if (workflowRuns) { - setAutoUpdate(false); - } - void refetchWorkflowsRun(); - }, [workflowRuns, setAutoUpdate]); + const { + data: workflowRuns, + isLoading, + mutate: refetchWorkflowsRun, + } = useAuthenticatedGetWorkflowRuns({ + page: paginationModel.page, + pageSize: paginationModel.pageSize, + workflowId, + }); - const columns = useMemo>>( - () => [ - { - field: "start_date", - headerName: "Start Date", - headerAlign: "center", - align: "center", - type: "string", - flex: 1, - minWidth: 150, - valueFormatter: ({ value }) => new Date(value).toLocaleString(), - }, - { - field: "end_date", - headerName: "End Date", - headerAlign: "center", - align: "center", - type: "string", - flex: 1, - minWidth: 150, - valueFormatter: ({ value }) => new Date(value).toLocaleString(), - }, - { - field: "execution_date", - headerName: "Execution Date", - headerAlign: "center", - align: "center", - minWidth: 150, - flex: 1, - valueFormatter: ({ value }) => new Date(value).toLocaleString(), - }, - { - field: "state", - headerName: "State", - headerAlign: "center", - align: "center", - type: "string", - minWidth: 150, - // flex: 1, - renderCell: (params) => { - return ; + const columns = useMemo>>( + () => [ + { + field: "start_date", + headerName: "Start Date", + headerAlign: "center", + align: "center", + type: "string", + flex: 1, + minWidth: 150, + valueFormatter: ({ value }) => new Date(value).toLocaleString(), }, - }, - ], - [], - ); - - const { rows, totalRows } = useMemo( - () => ({ - // every column need a id prop in DataGrid component - rows: - workflowRuns?.data?.map((wr) => ({ - ...wr, - id: wr.workflow_run_id, - })) ?? [], - totalRows: workflowRuns?.metadata?.total ?? 0, - }), - [workflowRuns], - ); + { + field: "end_date", + headerName: "End Date", + headerAlign: "center", + align: "center", + type: "string", + flex: 1, + minWidth: 150, + valueFormatter: ({ value }) => new Date(value).toLocaleString(), + }, + { + field: "execution_date", + headerName: "Execution Date", + headerAlign: "center", + align: "center", + minWidth: 150, + flex: 1, + valueFormatter: ({ value }) => new Date(value).toLocaleString(), + }, + { + field: "state", + headerName: "State", + headerAlign: "center", + align: "center", + type: "string", + minWidth: 150, + // flex: 1, + renderCell: (params) => { + return ; + }, + }, + ], + [], + ); - useEffect(() => { - if (!isLoading && workflowRuns?.data && workflowRuns?.data?.length > 0) { - setSelectedRun(workflowRuns.data[0]); - } - }, [isLoading, workflowRuns]); + const { rows, totalRows } = useMemo( + () => ({ + // every column need a id prop in DataGrid component + rows: + workflowRuns?.data?.map((wr) => ({ + ...wr, + id: wr.workflow_run_id, + })) ?? [], + totalRows: workflowRuns?.metadata?.total ?? 0, + }), + [workflowRuns], + ); - useInterval(handleRefreshWorkflowsRuns, 3000, autoUpdate); + useImperativeHandle(ref, () => ({ + refetchWorkflowsRun, + })); - const newRun = useCallback(() => { - triggerRun(); - setAutoUpdate(true); - }, [triggerRun, setAutoUpdate]); + useEffect(() => { + if (!isLoading && workflowRuns?.data && workflowRuns?.data?.length > 0) { + setSelectedRun(workflowRuns.data[0]); + } + }, [isLoading, workflowRuns]); - return ( - - - - {isLoading ? ( - - ) : ( - { - setSelectedRun( - workflowRuns?.data?.find((wr) => wr.workflow_run_id === id) ?? - null, - ); - }} - rowSelectionModel={ - selectedRun ? [selectedRun.workflow_run_id] : [] - } - columns={columns} - rows={rows} - pagination - paginationMode="server" - pageSizeOptions={[5, 10, 25]} - initialState={{ - pagination: { - paginationModel, - }, - }} - rowCount={totalRows} - onPaginationModelChange={setPaginationModel} - disableDensitySelector - hideFooterSelectedRowCount - disableColumnMenu - disableColumnSelector - slots={{ - noRowsOverlay: NoDataOverlay, - footer: WorkflowRunTableFooter, - }} - slotProps={{ - footer: { triggerRun: newRun }, - }} - sx={{ - "&.MuiDataGrid-root .MuiDataGrid-cell:focus": { - outline: "none", - }, - "& .MuiDataGrid-row:hover": { - cursor: "pointer", - }, - }} - /> - )} - + return ( + + + + {isLoading ? ( + + ) : ( + { + setSelectedRun( + workflowRuns?.data?.find( + (wr) => wr.workflow_run_id === id, + ) ?? null, + ); + }} + rowSelectionModel={ + selectedRun ? [selectedRun.workflow_run_id] : [] + } + columns={columns} + rows={rows} + pagination + paginationMode="server" + pageSizeOptions={[5, 10, 25]} + initialState={{ + pagination: { + paginationModel, + }, + }} + rowCount={totalRows} + onPaginationModelChange={setPaginationModel} + disableDensitySelector + hideFooterSelectedRowCount + disableColumnMenu + disableColumnSelector + slots={{ + noRowsOverlay: NoDataOverlay, + footer: WorkflowRunTableFooter, + }} + slotProps={{ + footer: { triggerRun }, + }} + sx={{ + "&.MuiDataGrid-root .MuiDataGrid-cell:focus": { + outline: "none", + }, + "& .MuiDataGrid-row:hover": { + cursor: "pointer", + }, + }} + /> + )} + + - - ); -}; + ); + }, +); + +WorkflowRunsTable.displayName = "WorkflowRunsTable"; diff --git a/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx b/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx index 6e90691e..90eea3ca 100644 --- a/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx +++ b/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx @@ -16,13 +16,19 @@ import { type IWorkflowRuns, type IWorkflowRunTasks, } from "features/myWorkflows/types"; -import React, { useCallback, useRef, useState } from "react"; +import React, { useCallback, useEffect, useRef, useState } from "react"; import { useParams } from "react-router-dom"; import { type NodeMouseHandler } from "reactflow"; import { useInterval } from "utils"; -import { WorkflowRunDetail } from "./WorkflowRunDetail"; -import { WorkflowRunsTable } from "./WorkflowRunsTable"; +import { + WorkflowRunDetail, + type WorkflowRunDetailRef, +} from "./WorkflowRunDetail"; +import { + WorkflowRunsTable, + type WorkflowRunsTableRef, +} from "./WorkflowRunsTable"; /** * @todo Cancel run. [] @@ -38,12 +44,15 @@ export interface IWorkflowRunTaskExtended extends IWorkflowRunTasks { export const WorkflowDetail: React.FC = () => { const { id } = useParams<{ id: string }>(); - const workflowPanelRef = useRef(null); const [autoUpdate, setAutoUpdate] = useState(true); const [selectedNodeId, setSelectedNodeId] = useState(null); const [selectedRun, setSelectedRun] = useState(null); const [tasks, setTasks] = useState([]); + const workflowPanelRef = useRef(null); + const workflowRunsTableRef = useRef(null); + const workflowRunDetailRef = useRef(null); + const { data: workflow } = useAuthenticatedGetWorkflowId({ id: id as string, }); @@ -51,7 +60,16 @@ export const WorkflowDetail: React.FC = () => { const fetchWorkflowTasks = useAuthenticatedGetWorkflowRunTasks(); const handleRunWorkflow = useAuthenticatedPostWorkflowRunId(); - const handleFetchWorkflowRunTasks = useCallback(async () => { + const refreshDetails = useCallback(() => { + void workflowRunDetailRef.current?.refreshTaskLogs(); + void workflowRunDetailRef.current?.refreshTaskResults(); + }, [workflowRunDetailRef]); + + const refreshTable = useCallback(() => { + void workflowRunsTableRef.current?.refetchWorkflowsRun(); + }, [workflowRunsTableRef]); + + const refreshTasks = useCallback(async () => { if (selectedRun && workflow) { try { const pageSize = 100; @@ -143,10 +161,17 @@ export const WorkflowDetail: React.FC = () => { console.log(e); } } - }, [workflow, fetchWorkflowTasks, autoUpdate, selectedRun]); + }, [workflow, fetchWorkflowTasks, selectedRun]); + + const refresh = useCallback(() => { + console.log("refresh"); + refreshDetails(); + refreshTable(); + void refreshTasks(); + }, [refreshDetails, refreshTable, refreshTasks]); const handleSelectRun = useCallback( - async (run: IWorkflowRuns | null) => { + (run: IWorkflowRuns | null) => { // if (!(run?.state === "success") && !(run?.state === "failed")) { // setAutoUpdate(true); // } @@ -154,7 +179,7 @@ export const WorkflowDetail: React.FC = () => { setSelectedRun(run); setAutoUpdate(true); }, - [handleFetchWorkflowRunTasks], + [refreshDetails, refreshTable, refreshTasks], ); const onNodeDoubleClick = useCallback( @@ -164,7 +189,13 @@ export const WorkflowDetail: React.FC = () => { [], ); - useInterval(handleFetchWorkflowRunTasks, 1000, autoUpdate); + useEffect(() => { + if (selectedRun) { + refresh(); + } + }, [selectedRun, refresh]); + + useInterval(refreshTasks, 1000, autoUpdate); return ( @@ -183,10 +214,9 @@ export const WorkflowDetail: React.FC = () => { } }} selectedRun={selectedRun} + ref={workflowRunsTableRef} onSelectedRunChange={handleSelectRun} workflowId={id as string} - autoUpdate={autoUpdate} - setAutoUpdate={setAutoUpdate} /> {/* WorkflowPanel */} @@ -204,11 +234,11 @@ export const WorkflowDetail: React.FC = () => { {/* Right Column */} From 14751642bc96404e1afa9e411aae14b9b7147c22 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Mon, 13 Nov 2023 13:49:01 -0300 Subject: [PATCH 3/5] fix: refresh update all details --- .../myWorkflows/components/WorkflowDetail/index.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx b/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx index 90eea3ca..da928aba 100644 --- a/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx +++ b/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx @@ -172,10 +172,6 @@ export const WorkflowDetail: React.FC = () => { const handleSelectRun = useCallback( (run: IWorkflowRuns | null) => { - // if (!(run?.state === "success") && !(run?.state === "failed")) { - // setAutoUpdate(true); - // } - // TODO force run without first delay setSelectedRun(run); setAutoUpdate(true); }, @@ -195,7 +191,7 @@ export const WorkflowDetail: React.FC = () => { } }, [selectedRun, refresh]); - useInterval(refreshTasks, 1000, autoUpdate); + useInterval(refresh, 1000, autoUpdate); return ( @@ -211,6 +207,7 @@ export const WorkflowDetail: React.FC = () => { triggerRun={() => { if (workflow?.id) { void handleRunWorkflow({ id: String(workflow.id) }); + setAutoUpdate(true); } }} selectedRun={selectedRun} From a3e3bc43171acbf0c2a18a627b574253d75b8aba Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Mon, 13 Nov 2023 14:17:22 -0300 Subject: [PATCH 4/5] fix: refresh when is same status --- .../components/WorkflowDetail/index.tsx | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx b/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx index da928aba..b0778bdf 100644 --- a/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx +++ b/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx @@ -1,5 +1,4 @@ import { Grid, Paper } from "@mui/material"; -import { AxiosError } from "axios"; import { Breadcrumbs } from "components/Breadcrumbs"; import { WorkflowPanel, @@ -145,30 +144,27 @@ export const WorkflowDetail: React.FC = () => { workflowPanelRef.current?.setNodes(JSON.parse(newNodes)); workflowPanelRef.current?.setEdges(workflow.ui_schema.edges); setTasks(tasks); - if ( - selectedRun && - (selectedRun.state === "success" || selectedRun.state === "failed") - ) { - setAutoUpdate(false); - } else { - setAutoUpdate(true); - } } } catch (e) { - if (e instanceof AxiosError) { - console.log(e); - } console.log(e); } } }, [workflow, fetchWorkflowTasks, selectedRun]); - const refresh = useCallback(() => { - console.log("refresh"); + const refresh = useCallback(async () => { refreshDetails(); refreshTable(); - void refreshTasks(); - }, [refreshDetails, refreshTable, refreshTasks]); + await refreshTasks(); + + if ( + selectedRun && + (selectedRun.state === "success" || selectedRun.state === "failed") + ) { + setAutoUpdate(false); + } else { + setAutoUpdate(true); + } + }, [refreshDetails, refreshTable, refreshTasks, selectedRun, setAutoUpdate]); const handleSelectRun = useCallback( (run: IWorkflowRuns | null) => { @@ -187,7 +183,9 @@ export const WorkflowDetail: React.FC = () => { useEffect(() => { if (selectedRun) { - refresh(); + refresh().catch((e) => { + console.log(e); + }); } }, [selectedRun, refresh]); From 4339cb0031ac5a9e4be63f624e8d6b91b7434a86 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Mon, 13 Nov 2023 16:50:28 -0300 Subject: [PATCH 5/5] fix: tasks details view --- .../api/runs/getWorkflowRunTaskResult.ts | 65 +++++++++---------- .../WorkflowDetail/WorkflowRunDetail.tsx | 18 ++--- .../components/WorkflowDetail/index.tsx | 16 +++-- 3 files changed, 52 insertions(+), 47 deletions(-) diff --git a/frontend/src/features/myWorkflows/api/runs/getWorkflowRunTaskResult.ts b/frontend/src/features/myWorkflows/api/runs/getWorkflowRunTaskResult.ts index c6e83b8f..21c71550 100644 --- a/frontend/src/features/myWorkflows/api/runs/getWorkflowRunTaskResult.ts +++ b/frontend/src/features/myWorkflows/api/runs/getWorkflowRunTaskResult.ts @@ -10,38 +10,41 @@ export interface IGetWorkflowRunTaskResultParams { taskTryNumber: string; } -const getWorkflowRunTaskResultUrl = ( - workspace: string, - workflowId: string, - runId: string, - taskId: string, - taskTryNumber: string, -) => { - if (workspace && workflowId && runId && taskId && Number(taskTryNumber)) +const getWorkflowRunTaskResultUrl = ({ + workspace, + workflowId, + runId, + taskId, + taskTryNumber, +}: Partial) => { + if (workspace && workflowId && runId && taskId && taskTryNumber) { return `/workspaces/${workspace}/workflows/${workflowId}/runs/${runId}/tasks/${taskId}/${taskTryNumber}/result`; + } else { + return null; + } }; /** * Get workflows using GET /workflows * @returns workflow */ -const getWorkflowRunTaskResult: ( - workspace: string, - workflowId: string, - runId: string, - taskId: string, - taskTryNumber: string, -) => Promise< +const getWorkflowRunTaskResult: ({ + workspace, + workflowId, + runId, + taskId, + taskTryNumber, +}: Partial) => Promise< AxiosResponse<{ base64_content: string; file_type: string }> | undefined -> = async (workspace, workflowId, runId, taskId, taskTryNumber) => { +> = async ({ workspace, workflowId, runId, taskId, taskTryNumber }) => { if (workspace && workflowId && runId && taskId && taskTryNumber) { - const url = getWorkflowRunTaskResultUrl( + const url = getWorkflowRunTaskResultUrl({ workspace, workflowId, runId, taskId, taskTryNumber, - ); + }); if (url) return await dominoApiClient.get(url); } }; @@ -51,7 +54,7 @@ const getWorkflowRunTaskResult: ( * @returns runs as swr response */ export const useAuthenticatedGetWorkflowRunTaskResult = ( - params: IGetWorkflowRunTaskResultParams, + params: Partial, ) => { const { workspace } = useWorkspaces(); if (!workspace) @@ -59,21 +62,17 @@ export const useAuthenticatedGetWorkflowRunTaskResult = ( "Impossible to fetch workflows without specifying a workspace", ); + const url = getWorkflowRunTaskResultUrl({ + workspace: workspace.id, + ...params, + }); + return useSWR( - getWorkflowRunTaskResultUrl( - workspace.id, - params.workflowId, - params.runId, - params.taskId, - params.taskTryNumber, - ) ?? null, + url, async () => - await getWorkflowRunTaskResult( - workspace.id, - params.workflowId, - params.runId, - params.taskId, - params.taskTryNumber, - ).then((data) => data?.data), + await getWorkflowRunTaskResult({ + workspace: workspace.id, + ...params, + }).then((data) => data?.data), ); }; diff --git a/frontend/src/features/myWorkflows/components/WorkflowDetail/WorkflowRunDetail.tsx b/frontend/src/features/myWorkflows/components/WorkflowDetail/WorkflowRunDetail.tsx index 83980eb0..15c5cc96 100644 --- a/frontend/src/features/myWorkflows/components/WorkflowDetail/WorkflowRunDetail.tsx +++ b/frontend/src/features/myWorkflows/components/WorkflowDetail/WorkflowRunDetail.tsx @@ -21,10 +21,10 @@ import { TaskResult } from "./CustomTabMenu/TaskResult"; import { type IWorkflowRunTaskExtended } from "."; interface Props { - runId: string | null; - nodeId: string | null; - tasks: IWorkflowRunTaskExtended[] | null; - workflowId: string; + runId?: string; + nodeId?: string; + tasks?: IWorkflowRunTaskExtended[]; + workflowId?: string; } export interface WorkflowRunDetailRef { @@ -55,14 +55,14 @@ export const WorkflowRunDetail = forwardRef( return task; } - }, [nodeId, tasks]); + }, [runId, nodeId, tasks]); const { data: taskLogs, mutate: refreshTaskLogs } = useAuthenticatedGetWorkflowRunTaskLogs({ runId: runId ?? "", taskId: taskData?.task_id ?? "", taskTryNumber: String(taskData?.try_number) ?? "", - workflowId, + workflowId: workflowId ?? "", }); const { @@ -70,9 +70,9 @@ export const WorkflowRunDetail = forwardRef( isLoading, mutate: refreshTaskResults, } = useAuthenticatedGetWorkflowRunTaskResult({ - runId: runId ?? "", - taskId: taskData?.task_id ?? "", - taskTryNumber: String(taskData?.try_number) ?? "", + runId, + taskId: taskData?.state === "success" ? taskData?.task_id : undefined, + taskTryNumber: String(taskData?.try_number), workflowId, }); diff --git a/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx b/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx index b0778bdf..6afd1431 100644 --- a/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx +++ b/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx @@ -44,9 +44,9 @@ export interface IWorkflowRunTaskExtended extends IWorkflowRunTasks { export const WorkflowDetail: React.FC = () => { const { id } = useParams<{ id: string }>(); const [autoUpdate, setAutoUpdate] = useState(true); - const [selectedNodeId, setSelectedNodeId] = useState(null); + const [selectedNodeId, setSelectedNodeId] = useState(); const [selectedRun, setSelectedRun] = useState(null); - const [tasks, setTasks] = useState([]); + const [statusTasks, setTasks] = useState([]); const workflowPanelRef = useRef(null); const workflowRunsTableRef = useRef(null); @@ -135,6 +135,13 @@ export const WorkflowDetail: React.FC = () => { nodes.push(...nodesData); } } + const currentTaks = JSON.stringify(statusTasks); + const newTasks = JSON.stringify(tasks); + + if (currentTaks !== newTasks) { + setTasks(tasks); + } + const currentNodes = JSON.stringify( workflowPanelRef.current?.nodes ?? {}, ); @@ -143,7 +150,6 @@ export const WorkflowDetail: React.FC = () => { // need to create a different object to perform a re-render workflowPanelRef.current?.setNodes(JSON.parse(newNodes)); workflowPanelRef.current?.setEdges(workflow.ui_schema.edges); - setTasks(tasks); } } catch (e) { console.log(e); @@ -230,8 +236,8 @@ export const WorkflowDetail: React.FC = () => {