import React, { useState, useEffect, useCallback } from 'react'; import { Button, MenuItem, Paper, Box, TextField } from "@mui/material"; import { Dropdown as MuiDropdown } from '../atoms/DropdownMui'; import styled from "styled-components"; import { ActionSettings } from "../molecules/ActionSettings"; import { SelectChangeEvent } from "@mui/material/Select/Select"; import { SimpleBox } from "../atoms/Box"; import Typography from "@mui/material/Typography"; import { useGlobalInfoStore } from "../../context/globalInfo"; import { PairForEdit } from "../../pages/RecordingPage"; import { useActionContext } from '../../context/browserActions'; import { useBrowserSteps } from '../../context/browserSteps'; import { useSocketStore } from '../../context/socket'; interface RightSidePanelProps { pairForEdit: PairForEdit; } export const RightSidePanel = ({ pairForEdit }: RightSidePanelProps) => { const [content, setContent] = useState('action'); const [action, setAction] = useState(''); const [isSettingsDisplayed, setIsSettingsDisplayed] = useState(false); const [labels, setLabels] = useState<{ [id: number]: string }>({}); const [errors, setErrors] = useState<{ [id: number]: string }>({}); const [confirmedSteps, setConfirmedSteps] = useState<{ [id: number]: boolean }>({}); const { lastAction } = useGlobalInfoStore(); const { getText, getScreenshot, startGetText, stopGetText, startGetScreenshot, stopGetScreenshot } = useActionContext(); const { browserSteps, updateBrowserStepLabel, deleteBrowserStep } = useBrowserSteps(); const { socket } = useSocketStore(); const handleChange = (event: React.SyntheticEvent, newValue: string) => { setContent(newValue); }; const handleActionSelect = (event: SelectChangeEvent) => { const { value } = event.target; setAction(value); setIsSettingsDisplayed(true); }; const handleLabelChange = (id: number, label: string) => { setLabels(prevLabels => ({ ...prevLabels, [id]: label })); if (!label.trim()) { setErrors(prevErrors => ({ ...prevErrors, [id]: 'Label cannot be empty' })); } else { setErrors(prevErrors => ({ ...prevErrors, [id]: '' })); } }; const handleConfirm = (id: number) => { const label = labels[id]?.trim(); if (label) { updateBrowserStepLabel(id, label); setConfirmedSteps(prev => ({ ...prev, [id]: true })); } else { setErrors(prevErrors => ({ ...prevErrors, [id]: 'Label cannot be empty' })); } }; const handleDiscard = (id: number) => { deleteBrowserStep(id); setLabels(prevLabels => { const { [id]: _, ...rest } = prevLabels; return rest; }); setErrors(prevErrors => { const { [id]: _, ...rest } = prevErrors; return rest; }); }; // Create settings object when stopping text capture const createSettingsObject = useCallback(() => { const settings: Record = {}; browserSteps.forEach(step => { if (step.label && step.value) { settings[step.label] = step.value; } }); console.log(`settings from getText:`, settings); return settings; }, [browserSteps]); // Stop text capture and emit settings object const stopCaptureAndEmitSettings = useCallback(() => { stopGetText(); const settings = createSettingsObject(); socket?.emit('action', { action: 'settings', settings }); }, [stopGetText, createSettingsObject, socket]); return ( Last action: {` ${lastAction}`} {content === 'action' && ( <> Type of action: click on coordinates enqueueLinks scrape scrapeSchema screenshot script scroll {isSettingsDisplayed && } )} {!getText && !getScreenshot && } {getText && } {!getText && !getScreenshot && } {getScreenshot && } {browserSteps.map(step => ( handleLabelChange(step.id, e.target.value)} fullWidth margin="normal" error={!!errors[step.id]} helperText={errors[step.id]} InputProps={{ readOnly: confirmedSteps[step.id] }} /> {!confirmedSteps[step.id] && ( )} ))} ); }; const ActionTypeWrapper = styled.div` display: flex; flex-direction: column; align-items: center; justify-content: center; margin-top: 20px; `; export const ActionDescription = styled.p` margin-left: 15px; `;