feat: cache robot and run fetch data

This commit is contained in:
Rohit Rajan
2025-09-19 11:24:23 +05:30
parent f885269688
commit 883922606c
2 changed files with 51 additions and 92 deletions

View File

@@ -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<Data[]>([]);
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<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = React.useState<T>(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 (
<React.Fragment>

View File

@@ -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<RunsTableProps> = ({
[t]
);
const [rows, setRows] = useState<Data[]>([]);
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<PaginationState>({});
const [expandedRows, setExpandedRows] = useState<Set<string>>(new Set());
const [expandedAccordions, setExpandedAccordions] = useState<Set<string>>(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<RunsTableProps> = ({
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<RunsTableProps> = ({
}, {} as Record<string, Data[]>);
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);