diff --git a/server/src/routes/storage.ts b/server/src/routes/storage.ts index 01f1ca6b..e159d8cb 100644 --- a/server/src/routes/storage.ts +++ b/server/src/routes/storage.ts @@ -501,6 +501,7 @@ router.put('/runs/:id', requireSignIn, async (req: AuthenticatedRequest, res) => return res.send({ browserId: id, runId: plainRun.runId, + robotMetaId: recording.recording_meta.id, }); } catch (e) { const { message } = e as Error; diff --git a/src/api/storage.ts b/src/api/storage.ts index 290f6e7f..0bfcaf15 100644 --- a/src/api/storage.ts +++ b/src/api/storage.ts @@ -161,7 +161,7 @@ export const createRunForStoredRecording = async (id: string, settings: RunSetti } } catch (error: any) { console.log(error); - return { browserId: '', runId: '' }; + return { browserId: '', runId: '', robotMetaId: '' }; } } diff --git a/src/components/run/ColapsibleRow.tsx b/src/components/run/ColapsibleRow.tsx index 8cf27d6d..87e38684 100644 --- a/src/components/run/ColapsibleRow.tsx +++ b/src/components/run/ColapsibleRow.tsx @@ -35,8 +35,9 @@ interface CollapsibleRowProps { currentLog: string; abortRunHandler: () => void; runningRecordingName: string; + urlRunId: string | null; } -export const CollapsibleRow = ({ row, handleDelete, isOpen, currentLog, abortRunHandler, runningRecordingName }: CollapsibleRowProps) => { +export const CollapsibleRow = ({ row, handleDelete, isOpen, currentLog, abortRunHandler, runningRecordingName, urlRunId }: CollapsibleRowProps) => { const { t } = useTranslation(); const navigate = useNavigate(); const [open, setOpen] = useState(isOpen); @@ -62,14 +63,18 @@ export const CollapsibleRow = ({ row, handleDelete, isOpen, currentLog, abortRun abortRunHandler(); } + useEffect(() => { + setOpen(urlRunId === row.runId || isOpen); + }, [urlRunId, row.runId, isOpen]); + const handleRowExpand = () => { const newOpen = !open; setOpen(newOpen); - if (newOpen) { - navigate(`/runs/${row.robotMetaId}/run/${row.runId}`); - } else { - navigate(`/runs/${row.robotMetaId}`); - } + navigate( + newOpen + ? `/runs/${row.robotMetaId}/run/${row.runId}` + : `/runs/${row.robotMetaId}` + ); //scrollToLogBottom(); }; diff --git a/src/components/run/RunsTable.tsx b/src/components/run/RunsTable.tsx index 8fd52a99..a3b8dfd4 100644 --- a/src/components/run/RunsTable.tsx +++ b/src/components/run/RunsTable.tsx @@ -12,7 +12,7 @@ import TableRow from '@mui/material/TableRow'; import { Accordion, AccordionSummary, AccordionDetails, Typography, Box, TextField, CircularProgress, Tooltip } from '@mui/material'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import SearchIcon from '@mui/icons-material/Search'; -import { useNavigate } from 'react-router-dom'; +import { useLocation, useNavigate } from 'react-router-dom'; import { useGlobalInfoStore } from "../../context/globalInfo"; import { getStoredRuns } from "../../api/storage"; import { RunSettings } from "./RunSettings"; @@ -85,6 +85,21 @@ export const RunsTable: React.FC = ({ }) => { const { t } = useTranslation(); const navigate = useNavigate(); + const location = useLocation(); + + const getUrlParams = () => { + const match = location.pathname.match(/\/runs\/([^\/]+)(?:\/run\/([^\/]+))?/); + return { + robotMetaId: match?.[1] || null, + urlRunId: match?.[2] || null + }; + }; + + const { robotMetaId: urlRobotMetaId, urlRunId } = getUrlParams(); + + const isAccordionExpanded = useCallback((currentRobotMetaId: string) => { + return currentRobotMetaId === urlRobotMetaId; + }, [urlRobotMetaId]); const [accordionPage, setAccordionPage] = useState(0); const [accordionsPerPage, setAccordionsPerPage] = useState(10); @@ -314,10 +329,11 @@ export const RunsTable: React.FC = ({ key={`row-${row.id}`} row={row} handleDelete={handleDelete} - isOpen={runId === row.runId && runningRecordingName === row.name} + isOpen={urlRunId === row.runId || (runId === row.runId && runningRecordingName === row.name)} currentLog={currentInterpretationLog} abortRunHandler={abortRunHandler} runningRecordingName={runningRecordingName} + urlRunId={urlRunId} /> )); }, [paginationStates, runId, runningRecordingName, currentInterpretationLog, abortRunHandler, handleDelete, accordionSortConfigs]); diff --git a/src/pages/MainPage.tsx b/src/pages/MainPage.tsx index b9a4f24f..0801a933 100644 --- a/src/pages/MainPage.tsx +++ b/src/pages/MainPage.tsx @@ -15,6 +15,7 @@ import { ScheduleSettings } from "../components/robot/ScheduleSettings"; import { IntegrationSettings } from "../components/integration/IntegrationSettings"; import { RobotSettings } from "../components/robot/RobotSettings"; import { apiUrl } from "../apiConfig"; +import { useNavigate } from 'react-router-dom'; interface MainPageProps { handleEditRecording: (id: string, fileName: string) => void; @@ -24,6 +25,7 @@ interface MainPageProps { export interface CreateRunResponse { browserId: string; runId: string; + robotMetaId: string; } export interface ScheduleRunResponse { @@ -40,12 +42,14 @@ export const MainPage = ({ handleEditRecording, initialContent }: MainPageProps) const [currentInterpretationLog, setCurrentInterpretationLog] = React.useState(''); const [ids, setIds] = React.useState({ browserId: '', - runId: '' + runId: '', + robotMetaId: '' }); let aborted = false; const { notify, setRerenderRuns, setRecordingId } = useGlobalInfoStore(); + const navigate = useNavigate(); const abortRunHandler = (runId: string) => { aborted = true; @@ -88,8 +92,9 @@ export const MainPage = ({ handleEditRecording, initialContent }: MainPageProps) }, [currentInterpretationLog]) const handleRunRecording = useCallback((settings: RunSettings) => { - createRunForStoredRecording(runningRecordingId, settings).then(({ browserId, runId }: CreateRunResponse) => { - setIds({ browserId, runId }); + createRunForStoredRecording(runningRecordingId, settings).then(({ browserId, runId, robotMetaId }: CreateRunResponse) => { + setIds({ browserId, runId, robotMetaId }); + navigate(`/runs/${robotMetaId}/run/${runId}`); const socket = io(`${apiUrl}/${browserId}`, { transports: ["websocket"],