import * as React from 'react'; import SwipeableDrawer from '@mui/material/SwipeableDrawer'; import Typography from '@mui/material/Typography'; import { Button, Grid, Tabs, Tab, Box } from '@mui/material'; import { useCallback, useEffect, useRef, useState } from "react"; import { useSocketStore } from "../../context/socket"; import { Buffer } from 'buffer'; import { useBrowserDimensionsStore } from "../../context/browserDimensions"; import Table from '@mui/material/Table'; import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; import TableContainer from '@mui/material/TableContainer'; import TableHead from '@mui/material/TableHead'; import TableRow from '@mui/material/TableRow'; import Paper from '@mui/material/Paper'; import StorageIcon from '@mui/icons-material/Storage'; import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward'; import { SidePanelHeader } from '../recorder/SidePanelHeader'; import { useGlobalInfoStore } from '../../context/globalInfo'; import { useThemeMode } from '../../context/theme-provider'; import { useTranslation } from 'react-i18next'; interface InterpretationLogProps { isOpen: boolean; setIsOpen: (isOpen: boolean) => void; } export const InterpretationLog: React.FC = ({ isOpen, setIsOpen }) => { const { t } = useTranslation(); const [log, setLog] = useState(''); const [customValue, setCustomValue] = useState(''); const [captureListData, setCaptureListData] = useState([]); const [captureTextData, setCaptureTextData] = useState([]); const [screenshotData, setScreenshotData] = useState([]); const [otherData, setOtherData] = useState([]); const [captureListPage, setCaptureListPage] = useState(0); const [screenshotPage, setScreenshotPage] = useState(0); const [otherPage, setOtherPage] = useState(0); const [activeTab, setActiveTab] = useState(0); const logEndRef = useRef(null); const { browserWidth, outputPreviewHeight, outputPreviewWidth } = useBrowserDimensionsStore(); const { socket } = useSocketStore(); const { currentWorkflowActionsState, shouldResetInterpretationLog, notify } = useGlobalInfoStore(); const toggleDrawer = (newOpen: boolean) => (event: React.KeyboardEvent | React.MouseEvent) => { if ( event.type === 'keydown' && ((event as React.KeyboardEvent).key === 'Tab' || (event as React.KeyboardEvent).key === 'Shift') ) { return; } setIsOpen(newOpen); }; const scrollLogToBottom = () => { if (logEndRef.current) { logEndRef.current.scrollIntoView({ behavior: "smooth" }); } }; const handleLog = useCallback((msg: string, date: boolean = true) => { if (!date) { setLog((prevState) => prevState + '\n' + msg); } else { setLog((prevState) => prevState + '\n' + `[${new Date().toLocaleString()}] ` + msg); } scrollLogToBottom(); }, []); const handleSerializableCallback = useCallback(({ type, data }: { type: string, data: any }) => { setLog((prevState) => prevState + '\n' + t('interpretation_log.data_sections.serializable_received') + '\n' + JSON.stringify(data, null, 2) + '\n' + t('interpretation_log.data_sections.separator')); if (type === 'captureList' && Array.isArray(data)) { setCaptureListData(prev => [...prev, data]); if (captureListData.length === 0) { const availableTabs = getAvailableTabs(); const tabIndex = availableTabs.findIndex(tab => tab.id === 'captureList'); if (tabIndex !== -1) setActiveTab(tabIndex); } } else if (type === 'captureText') { if (Array.isArray(data)) { setCaptureTextData(data); } else { setCaptureTextData([data]); } if (captureTextData.length === 0) { const availableTabs = getAvailableTabs(); const tabIndex = availableTabs.findIndex(tab => tab.id === 'captureText'); if (tabIndex !== -1) setActiveTab(tabIndex); } } scrollLogToBottom(); }, [captureListData.length, captureTextData.length, otherData.length, t]); const handleBinaryCallback = useCallback(({ data, mimetype, type }: { data: any, mimetype: string, type: string }) => { const base64String = Buffer.from(data).toString('base64'); const imageSrc = `data:${mimetype};base64,${base64String}`; setLog((prevState) => prevState + '\n' + t('interpretation_log.data_sections.binary_received') + '\n' + t('interpretation_log.data_sections.mimetype') + mimetype + '\n' + t('interpretation_log.data_sections.image_below') + '\n' + t('interpretation_log.data_sections.separator')); if (type === 'captureScreenshot') { setScreenshotData(prev => [...prev, imageSrc]); if (screenshotData.length === 0) { const availableTabs = getAvailableTabs(); const tabIndex = availableTabs.findIndex(tab => tab.id === 'captureScreenshot'); if (tabIndex !== -1) setActiveTab(tabIndex); } } scrollLogToBottom(); }, [screenshotData.length, t]); const handleCustomValueChange = (event: React.ChangeEvent) => { setCustomValue(event.target.value); }; useEffect(() => { if (shouldResetInterpretationLog) { setLog(''); setCaptureListData([]); setCaptureTextData([]); setScreenshotData([]); setOtherData([]); setActiveTab(0); setCaptureListPage(0); setScreenshotPage(0); setOtherPage(0); } }, [shouldResetInterpretationLog]); useEffect(() => { socket?.on('log', handleLog); socket?.on('serializableCallback', handleSerializableCallback); socket?.on('binaryCallback', handleBinaryCallback); return () => { socket?.off('log', handleLog); socket?.off('serializableCallback', handleSerializableCallback); socket?.off('binaryCallback', handleBinaryCallback); }; }, [socket, handleLog, handleSerializableCallback, handleBinaryCallback]); const getAvailableTabs = useCallback(() => { const tabs = []; if (captureListData.length > 0) { tabs.push({ id: 'captureList', label: 'Lists' }); } if (captureTextData.length > 0) { tabs.push({ id: 'captureText', label: 'Texts' }); } if (screenshotData.length > 0) { tabs.push({ id: 'captureScreenshot', label: 'Screenshots' }); } return tabs; }, [captureListData.length, captureTextData.length, screenshotData.length, otherData.length]); const availableTabs = getAvailableTabs(); useEffect(() => { if (activeTab >= availableTabs.length && availableTabs.length > 0) { setActiveTab(0); } }, [activeTab, availableTabs.length]); const { hasScrapeListAction, hasScreenshotAction, hasScrapeSchemaAction } = currentWorkflowActionsState; useEffect(() => { if (hasScrapeListAction || hasScrapeSchemaAction || hasScreenshotAction) { setIsOpen(true); } }, [hasScrapeListAction, hasScrapeSchemaAction, hasScreenshotAction, setIsOpen]); const { darkMode } = useThemeMode(); const getCaptureTextColumns = captureTextData.length > 0 ? Object.keys(captureTextData[0]) : []; return (
{t('interpretation_log.titles.output_preview')} {availableTabs.length > 0 ? ( <> {availableTabs.map((tab, index) => ( setActiveTab(index)} sx={{ px: 4, py: 2, cursor: 'pointer', borderBottom: activeTab === index ? '2px solid' : 'none', borderColor: activeTab === index ? (darkMode ? '#ff00c3' : '#ff00c3') : 'transparent', backgroundColor: activeTab === index ? (darkMode ? '#34404d' : '#e9ecef') : 'transparent', color: darkMode ? 'white' : 'black', fontWeight: activeTab === index ? 500 : 400, textAlign: 'center', position: 'relative', '&:hover': { backgroundColor: activeTab !== index ? (darkMode ? '#303b49' : '#e2e6ea') : undefined } }} > {tab.label} ))} {activeTab === availableTabs.findIndex(tab => tab.id === 'captureList') && captureListData.length > 0 && ( {`Table ${captureListPage + 1} of ${captureListData.length}`} {captureListData[captureListPage] && captureListData[captureListPage].length > 0 && Object.keys(captureListData[captureListPage][0]).map((column) => ( {column} )) } {captureListData[captureListPage] && captureListData[captureListPage].map((row: any, idx: any) => ( {Object.keys(row).map((column) => ( {row[column]} ))} ))}
)} {activeTab === availableTabs.findIndex(tab => tab.id === 'captureScreenshot') && ( {screenshotData.length > 1 && ( {`Screenshot ${screenshotPage + 1} of ${screenshotData.length}`} )} {screenshotData.length > 0 && ( {t('interpretation_log.titles.screenshot')} {screenshotPage + 1} {`${t('interpretation_log.titles.screenshot')} )} )} {activeTab === availableTabs.findIndex(tab => tab.id === 'captureText') && ( {getCaptureTextColumns.map((column) => ( {column} ))} {captureTextData.map((row, idx) => ( {getCaptureTextColumns.map((column) => ( {row[column]} ))} ))}
)}
) : ( {hasScrapeListAction || hasScrapeSchemaAction || hasScreenshotAction ? ( <> {t('interpretation_log.messages.successful_training')} ) : ( {t('interpretation_log.messages.no_selection')} )} )}
); };