diff --git a/src/components/robot/RecordingsTable.tsx b/src/components/robot/RecordingsTable.tsx index 42c5971b..188b3165 100644 --- a/src/components/robot/RecordingsTable.tsx +++ b/src/components/robot/RecordingsTable.tsx @@ -36,8 +36,8 @@ import { MoreHoriz, Refresh } from "@mui/icons-material"; -import { useGlobalInfoStore } from "../../context/globalInfo"; -import { checkRunsForRecording, deleteRecordingFromStorage, getStoredRecordings } from "../../api/storage"; +import { useGlobalInfoStore, useCachedRecordings } from "../../context/globalInfo"; +import { checkRunsForRecording, deleteRecordingFromStorage } from "../../api/storage"; import { Add } from "@mui/icons-material"; import { useNavigate } from 'react-router-dom'; import { canCreateBrowserInState, getActiveBrowserId, stopRecording } from "../../api/recording"; @@ -150,12 +150,11 @@ export const RecordingsTable = ({ const { t } = useTranslation(); const [page, setPage] = React.useState(0); const [rowsPerPage, setRowsPerPage] = React.useState(10); - const [rows, setRows] = React.useState([]); + const { data: recordingsData = [], isLoading: isFetching, error, refetch } = useCachedRecordings(); const [isModalOpen, setModalOpen] = React.useState(false); const [searchTerm, setSearchTerm] = React.useState(''); const [isWarningModalOpen, setWarningModalOpen] = React.useState(false); const [activeBrowserId, setActiveBrowserId] = React.useState(''); - const [isFetching, setIsFetching] = React.useState(true); const columns = useMemo(() => [ { id: 'interpret', label: t('recordingtable.run'), minWidth: 80 }, @@ -238,44 +237,42 @@ export const RecordingsTable = ({ if (dateStr.includes('PM') || dateStr.includes('AM')) { return new Date(dateStr); } - + return new Date(dateStr.replace(/(\d+)\/(\d+)\//, '$2/$1/')) } catch { return new Date(0); } }; - const fetchRecordings = useCallback(async () => { - try { - const recordings = await getStoredRecordings(); - if (recordings) { - const parsedRows = recordings - .map((recording: any, index: number) => { - if (recording?.recording_meta) { - const parsedDate = parseDateString(recording.recording_meta.updatedAt); - - return { - id: index, - ...recording.recording_meta, - content: recording.recording, - parsedDate - }; - } - return null; - }) - .filter(Boolean) - .sort((a, b) => b.parsedDate.getTime() - a.parsedDate.getTime()); - - setRecordings(parsedRows.map((recording) => recording.name)); - setRows(parsedRows); - } - } catch (error) { - console.error('Error fetching recordings:', error); - notify('error', t('recordingtable.notifications.fetch_error')); - } finally { - setIsFetching(false); + const rows = useMemo(() => { + if (!recordingsData) return []; + + const parsedRows = recordingsData + .map((recording: any, index: number) => { + if (recording?.recording_meta) { + const parsedDate = parseDateString(recording.recording_meta.updatedAt); + + return { + id: index, + ...recording.recording_meta, + content: recording.recording, + parsedDate + }; + } + return null; + }) + .filter(Boolean) + .sort((a, b) => b.parsedDate.getTime() - a.parsedDate.getTime()); + + return parsedRows; + }, [recordingsData]); + + useEffect(() => { + if (rows.length > 0) { + setRecordings(rows.map((recording) => recording.name)); } - }, [setRecordings, notify, t]); + }, [rows, setRecordings]); + const handleNewRecording = useCallback(async () => { const canCreateRecording = await canCreateBrowserInState("recording"); @@ -331,7 +328,7 @@ export const RecordingsTable = ({ if (lastPair?.what) { if (Array.isArray(lastPair.what)) { - const gotoAction = lastPair.what.find(action => + const gotoAction = lastPair.what.find((action: any) => action && typeof action === 'object' && 'action' in action && action.action === "goto" ) as any; @@ -408,17 +405,12 @@ export const RecordingsTable = ({ window.sessionStorage.setItem('initialUrl', event.target.value); } - useEffect(() => { - fetchRecordings(); - }, [fetchRecordings]); - useEffect(() => { if (rerenderRobots) { - fetchRecordings().then(() => { - setRerenderRobots(false); - }); + refetch(); + setRerenderRobots(false); } - }, [rerenderRobots, fetchRecordings, setRerenderRobots]); + }, [rerenderRobots, setRerenderRobots, refetch]); function useDebounce(value: T, delay: number): T { const [debouncedValue, setDebouncedValue] = React.useState(value); @@ -468,12 +460,11 @@ export const RecordingsTable = ({ const success = await deleteRecordingFromStorage(id); if (success) { - setRows([]); notify('success', t('recordingtable.notifications.delete_success')); - fetchRecordings(); + refetch(); } } - }), [handleRunRecording, handleScheduleRecording, handleIntegrateRecording, handleSettingsRecording, handleEditRobot, handleDuplicateRobot, handleRetrainRobot, notify, t]); + }), [handleRunRecording, handleScheduleRecording, handleIntegrateRecording, handleSettingsRecording, handleEditRobot, handleDuplicateRobot, handleRetrainRobot, notify, t, refetch]); return ( diff --git a/src/components/run/RunsTable.tsx b/src/components/run/RunsTable.tsx index cfcb05d4..4bd3a40c 100644 --- a/src/components/run/RunsTable.tsx +++ b/src/components/run/RunsTable.tsx @@ -13,8 +13,7 @@ import { Accordion, AccordionSummary, AccordionDetails, Typography, Box, TextFie import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import SearchIcon from '@mui/icons-material/Search'; import { useLocation, useNavigate } from 'react-router-dom'; -import { useGlobalInfoStore } from "../../context/globalInfo"; -import { getStoredRuns } from "../../api/storage"; +import { useGlobalInfoStore, useCachedRuns } from "../../context/globalInfo"; import { RunSettings } from "./RunSettings"; import { CollapsibleRow } from "./ColapsibleRow"; import { ArrowDownward, ArrowUpward, UnfoldMore } from '@mui/icons-material'; @@ -132,16 +131,14 @@ export const RunsTable: React.FC = ({ [t] ); - const [rows, setRows] = useState([]); - const [searchTerm, setSearchTerm] = useState(''); - const [isFetching, setIsFetching] = useState(true); + const { notify, rerenderRuns, setRerenderRuns } = useGlobalInfoStore(); + const { data: rows = [], isLoading: isFetching, error, refetch } = useCachedRuns(); + const [searchTerm, setSearchTerm] = useState(''); const [paginationStates, setPaginationStates] = useState({}); const [expandedRows, setExpandedRows] = useState>(new Set()); const [expandedAccordions, setExpandedAccordions] = useState>(new Set()); - const { notify, rerenderRuns, setRerenderRuns } = useGlobalInfoStore(); - const handleAccordionChange = useCallback((robotMetaId: string, isExpanded: boolean) => { setExpandedAccordions(prev => { const newSet = new Set(prev); @@ -278,47 +275,18 @@ export const RunsTable: React.FC = ({ debouncedSetSearch(event.target.value); }, [debouncedSearch]); - const fetchRuns = useCallback(async () => { - try { - const runs = await getStoredRuns(); - if (runs) { - const parsedRows: Data[] = runs.map((run: any, index: number) => ({ - id: index, - ...run, - })); - setRows(parsedRows); - } else { - notify('error', t('runstable.notifications.no_runs')); - } - } catch (error) { - notify('error', t('runstable.notifications.fetch_error')); - } finally { - setIsFetching(false); - } - }, [notify, t]); useEffect(() => { - let mounted = true; - - if (rows.length === 0 || rerenderRuns) { - setIsFetching(true); - fetchRuns().then(() => { - if (mounted) { - setRerenderRuns(false); - } - }); + if (rerenderRuns) { + refetch(); + setRerenderRuns(false); } - - return () => { - mounted = false; - }; - }, [rerenderRuns, rows.length, setRerenderRuns, fetchRuns]); + }, [rerenderRuns, setRerenderRuns, refetch]); const handleDelete = useCallback(() => { - setRows([]); notify('success', t('runstable.notifications.delete_success')); - fetchRuns(); - }, [notify, t, fetchRuns]); + refetch(); + }, [notify, t, refetch]); // Filter rows based on search term const filteredRows = useMemo(() => { @@ -350,15 +318,15 @@ export const RunsTable: React.FC = ({ }, {} as Record); Object.keys(groupedData).forEach(robotId => { - groupedData[robotId].sort((a, b) => + groupedData[robotId].sort((a: any, b: any) => parseDateString(b.startedAt).getTime() - parseDateString(a.startedAt).getTime() ); }); const robotEntries = Object.entries(groupedData).map(([robotId, runs]) => ({ robotId, - runs, - latestRunDate: parseDateString(runs[0].startedAt).getTime() + runs: runs as Data[], + latestRunDate: parseDateString((runs as Data[])[0].startedAt).getTime() })); robotEntries.sort((a, b) => b.latestRunDate - a.latestRunDate);