feat: display browser step data

This commit is contained in:
RohitR311
2025-05-07 09:22:50 +05:30
parent ec36df79fd
commit 0a1704e2a8

View File

@@ -1,7 +1,7 @@
import * as React from 'react'; import * as React from 'react';
import SwipeableDrawer from '@mui/material/SwipeableDrawer'; import SwipeableDrawer from '@mui/material/SwipeableDrawer';
import Typography from '@mui/material/Typography'; import Typography from '@mui/material/Typography';
import { Button, Grid, Tabs, Tab, Box } from '@mui/material'; import { Button, Grid, Box } from '@mui/material';
import { useCallback, useEffect, useRef, useState } from "react"; import { useCallback, useEffect, useRef, useState } from "react";
import { useSocketStore } from "../../context/socket"; import { useSocketStore } from "../../context/socket";
import { Buffer } from 'buffer'; import { Buffer } from 'buffer';
@@ -19,6 +19,7 @@ import { SidePanelHeader } from '../recorder/SidePanelHeader';
import { useGlobalInfoStore } from '../../context/globalInfo'; import { useGlobalInfoStore } from '../../context/globalInfo';
import { useThemeMode } from '../../context/theme-provider'; import { useThemeMode } from '../../context/theme-provider';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useBrowserSteps } from '../../context/browserSteps';
interface InterpretationLogProps { interface InterpretationLogProps {
isOpen: boolean; isOpen: boolean;
@@ -41,6 +42,10 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
const logEndRef = useRef<HTMLDivElement | null>(null); const logEndRef = useRef<HTMLDivElement | null>(null);
const { browserSteps } = useBrowserSteps();
const [activeActionId, setActiveActionId] = useState<number | null>(null);
const { browserWidth, outputPreviewHeight, outputPreviewWidth } = useBrowserDimensionsStore(); const { browserWidth, outputPreviewHeight, outputPreviewWidth } = useBrowserDimensionsStore();
const { socket } = useSocketStore(); const { socket } = useSocketStore();
const { currentWorkflowActionsState, shouldResetInterpretationLog, notify } = useGlobalInfoStore(); const { currentWorkflowActionsState, shouldResetInterpretationLog, notify } = useGlobalInfoStore();
@@ -71,33 +76,39 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
scrollLogToBottom(); scrollLogToBottom();
}, []); }, []);
const handleSerializableCallback = useCallback(({ type, data }: { type: string, data: any }) => { useEffect(() => {
setLog((prevState) => if (activeActionId !== null) {
prevState + '\n' + t('interpretation_log.data_sections.serializable_received') + '\n' const textSteps = browserSteps.filter(step => step.type === 'text');
+ JSON.stringify(data, null, 2) + '\n' + t('interpretation_log.data_sections.separator')); if (textSteps.length > 0) {
const textDataRow: Record<string, string> = {};
if (type === 'captureList') {
setCaptureListData(prev => [...prev, data]); textSteps.forEach(step => {
if (captureListData.length === 0) { textDataRow[step.label] = step.data;
const availableTabs = getAvailableTabs(); });
const tabIndex = availableTabs.findIndex(tab => tab.id === 'captureList');
if (tabIndex !== -1) setActiveTab(tabIndex); setCaptureTextData([textDataRow]);
} }
} else if (type === 'captureText') {
if (Array.isArray(data)) { const listSteps = browserSteps.filter(step => step.type === 'list');
setCaptureTextData(data); if (listSteps.length > 0) {
} else { setCaptureListData(listSteps);
setCaptureTextData([data]);
}
if (captureTextData.length === 0) {
const availableTabs = getAvailableTabs();
const tabIndex = availableTabs.findIndex(tab => tab.id === 'captureText');
if (tabIndex !== -1) setActiveTab(tabIndex);
} }
updateActiveTab();
} }
}, [activeActionId, browserSteps, t]);
scrollLogToBottom();
}, [captureListData.length, captureTextData.length, t]); const updateActiveTab = useCallback(() => {
const availableTabs = getAvailableTabs();
if (captureListData.length > 0 && availableTabs.findIndex(tab => tab.id === 'captureList') !== -1) {
setActiveTab(availableTabs.findIndex(tab => tab.id === 'captureList'));
} else if (captureTextData.length > 0 && availableTabs.findIndex(tab => tab.id === 'captureText') !== -1) {
setActiveTab(availableTabs.findIndex(tab => tab.id === 'captureText'));
} else if (screenshotData.length > 0 && availableTabs.findIndex(tab => tab.id === 'captureScreenshot') !== -1) {
setActiveTab(availableTabs.findIndex(tab => tab.id === 'captureScreenshot'));
}
}, [captureListData.length, captureTextData.length, screenshotData.length]);
const handleBinaryCallback = useCallback(({ data, mimetype, type }: { data: any, mimetype: string, type: string }) => { const handleBinaryCallback = useCallback(({ data, mimetype, type }: { data: any, mimetype: string, type: string }) => {
const base64String = Buffer.from(data).toString('base64'); const base64String = Buffer.from(data).toString('base64');
@@ -121,6 +132,10 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
scrollLogToBottom(); scrollLogToBottom();
}, [screenshotData.length, t]); }, [screenshotData.length, t]);
const handleActivePairId = useCallback((id: number) => {
setActiveActionId(id);
}, []);
const handleCustomValueChange = (event: React.ChangeEvent<HTMLInputElement>) => { const handleCustomValueChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setCustomValue(event.target.value); setCustomValue(event.target.value);
}; };
@@ -134,19 +149,21 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
setActiveTab(0); setActiveTab(0);
setCaptureListPage(0); setCaptureListPage(0);
setScreenshotPage(0); setScreenshotPage(0);
setActiveActionId(null);
} }
}, [shouldResetInterpretationLog]); }, [shouldResetInterpretationLog]);
useEffect(() => { useEffect(() => {
socket?.on('log', handleLog); socket?.on('log', handleLog);
socket?.on('serializableCallback', handleSerializableCallback);
socket?.on('binaryCallback', handleBinaryCallback); socket?.on('binaryCallback', handleBinaryCallback);
socket?.on('activePairId', handleActivePairId);
return () => { return () => {
socket?.off('log', handleLog); socket?.off('log', handleLog);
socket?.off('serializableCallback', handleSerializableCallback);
socket?.off('binaryCallback', handleBinaryCallback); socket?.off('binaryCallback', handleBinaryCallback);
socket?.off('activePairId', handleActivePairId);
}; };
}, [socket, handleLog, handleSerializableCallback, handleBinaryCallback]); }, [socket, handleLog, handleBinaryCallback, handleActivePairId]);
const getAvailableTabs = useCallback(() => { const getAvailableTabs = useCallback(() => {
const tabs = []; const tabs = [];
@@ -321,45 +338,48 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
<Table> <Table>
<TableHead> <TableHead>
<TableRow> <TableRow>
{captureListData[captureListPage] && captureListData[captureListPage].length > 0 && {Object.values(captureListData[captureListPage]?.fields || {}).map((field: any, index) => (
Object.keys(captureListData[captureListPage][0]).map((column) => ( <TableCell
<TableCell key={index}
key={column} sx={{
sx={{ borderBottom: '1px solid',
borderBottom: '1px solid', borderColor: darkMode ? '#3a4453' : '#dee2e6',
borderColor: darkMode ? '#3a4453' : '#dee2e6', backgroundColor: darkMode ? '#2a3441' : '#f8f9fa'
backgroundColor: darkMode ? '#2a3441' : '#f8f9fa' }}
}} >
> {field.label}
{column} </TableCell>
</TableCell> ))}
))
}
</TableRow> </TableRow>
</TableHead> </TableHead>
<TableBody> <TableBody>
{captureListData[captureListPage] && {(captureListData[captureListPage]?.data || [])
captureListData[captureListPage].map((row: any, idx: any) => ( .slice(0, Math.min(captureListData[captureListPage]?.limit || 10, 5))
<TableRow .map((row: any, rowIndex: any) => (
key={idx} <TableRow
sx={{ key={rowIndex}
borderBottom: '1px solid', sx={{
borderColor: darkMode ? '#3a4453' : '#dee2e6' borderBottom: rowIndex < Math.min(
}} (captureListData[captureListPage]?.data?.length || 0),
> Math.min(captureListData[captureListPage]?.limit || 10, 5)
{Object.keys(row).map((column) => ( ) - 1 ? '1px solid' : 'none',
<TableCell borderColor: darkMode ? '#3a4453' : '#dee2e6'
key={column} }}
sx={{ >
borderBottom: 'none', {Object.values(captureListData[captureListPage]?.fields || {}).map((field: any, colIndex) => (
py: 2 <TableCell
}} key={colIndex}
> sx={{
{row[column]} borderBottom: 'none',
</TableCell> py: 2
))} }}
</TableRow> >
))} {row[field.label]}
</TableCell>
))}
</TableRow>
))
}
</TableBody> </TableBody>
</Table> </Table>
</TableContainer> </TableContainer>