From 38a3a6b0ddf6a69cb7e5c23ce2a4abae0e5919f0 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Thu, 2 Apr 2026 21:42:20 +0530 Subject: [PATCH 01/16] feat: use Dialog instead of GenericModal --- src/components/robot/RecordingsTable.tsx | 76 ++++++++++++++++-------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/src/components/robot/RecordingsTable.tsx b/src/components/robot/RecordingsTable.tsx index f1e9bbe02..2e94ab89a 100644 --- a/src/components/robot/RecordingsTable.tsx +++ b/src/components/robot/RecordingsTable.tsx @@ -23,6 +23,11 @@ import { CircularProgress, FormControlLabel, Checkbox, + Dialog, + DialogTitle, + DialogContent, + DialogContentText, + DialogActions, } from "@mui/material"; import { Schedule, @@ -679,33 +684,52 @@ export const RecordingsTable = ({ - { setDeleteConfirmOpen(false); setPendingDeleteId(null); }} - modalStyle={{ ...modalStyle, padding: 0, backgroundColor: 'transparent', width: 'auto', maxWidth: '520px' }} - > + { + setDeleteConfirmOpen(false); + setPendingDeleteId(null); + }} + maxWidth="xs" + fullWidth +> + + {t('recordingtable.delete_confirm.title', { + name: pendingRow?.name, + defaultValue: 'Delete {{name}}?' + })} + + + + + {t('recordingtable.delete_confirm.message', { + name: pendingRow?.name, + defaultValue: 'Are you sure you want to delete the robot "{{name}}"?' + })} + + + + + - - - {t('recordingtable.delete_confirm.title', { name: pendingRow?.name, defaultValue: 'Delete {{name}}?' })} - - - {t('recordingtable.delete_confirm.message', { - name: pendingRow?.name, - defaultValue: 'Are you sure you want to delete the robot "{{name}}"?' - })} - - - - - - - - + + + ); } From 2d01f66595dfdda0832d5d03175be258cdb5b4f3 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Thu, 2 Apr 2026 21:42:41 +0530 Subject: [PATCH 02/16] chore: lint --- src/components/robot/RecordingsTable.tsx | 200 +++++++++++------------ 1 file changed, 100 insertions(+), 100 deletions(-) diff --git a/src/components/robot/RecordingsTable.tsx b/src/components/robot/RecordingsTable.tsx index 2e94ab89a..bfd8f9012 100644 --- a/src/components/robot/RecordingsTable.tsx +++ b/src/components/robot/RecordingsTable.tsx @@ -99,7 +99,7 @@ const LoadingRobotRow = memo(({ row, columns }: any) => { } else if (column.id === 'interpret') { return ( - - + - ); } else { @@ -186,7 +186,7 @@ export const RecordingsTable = ({ handleSettingsRecording, handleEditRobot, handleDuplicateRobot, - }: RecordingsTableProps) => { +}: RecordingsTableProps) => { const { t } = useTranslation(); const theme = useTheme(); const [page, setPage] = React.useState(0); @@ -232,11 +232,11 @@ export const RecordingsTable = ({ const notificationData = event.data.notification; if (notificationData) { notify(notificationData.type, notificationData.message); - - if ((notificationData.type === 'success' && - (notificationData.message.includes('saved') || notificationData.message.includes('retrained'))) || - (notificationData.type === 'warning' && - notificationData.message.includes('terminated'))) { + + if ((notificationData.type === 'success' && + (notificationData.message.includes('saved') || notificationData.message.includes('retrained'))) || + (notificationData.type === 'warning' && + notificationData.message.includes('terminated'))) { setRerenderRobots(true); } } @@ -253,9 +253,9 @@ export const RecordingsTable = ({ window.sessionStorage.removeItem('initialUrl'); } }; - + window.addEventListener('message', handleMessage); - + return () => { window.removeEventListener('message', handleMessage); }; @@ -330,7 +330,7 @@ export const RecordingsTable = ({ timestamp: Date.now() }; window.sessionStorage.setItem('recordingTabCloseMessage', JSON.stringify(closeMessage)); - + if (window.openedRecordingWindow && !window.openedRecordingWindow.closed) { try { window.openedRecordingWindow.close(); @@ -344,10 +344,10 @@ export const RecordingsTable = ({ if (activeBrowserId) { await stopRecording(activeBrowserId); notify('warning', t('browser_recording.notifications.terminated')); - + notifyRecordingTabsToClose(activeBrowserId); } - + setWarningModalOpen(false); setModalOpen(true); }; @@ -355,31 +355,31 @@ export const RecordingsTable = ({ const handleRetrainRobot = useCallback(async (id: string, name: string) => { const robot = rows.find(row => row.id === id); let targetUrl; - + if (robot?.content?.workflow && robot.content.workflow.length > 0) { const lastPair = robot.content.workflow[robot.content.workflow.length - 1]; - + if (lastPair?.what) { if (Array.isArray(lastPair.what)) { - const gotoAction = lastPair.what.find((action: any) => + const gotoAction = lastPair.what.find((action: any) => action && typeof action === 'object' && 'action' in action && action.action === "goto" ) as any; - + if (gotoAction?.args?.[0]) { targetUrl = gotoAction.args[0]; } } } } - + if (targetUrl) { setInitialUrl(targetUrl); setRecordingUrl(targetUrl); window.sessionStorage.setItem('initialUrl', targetUrl); } - + const canCreateRecording = await canCreateBrowserInState("recording"); - + if (!canCreateRecording) { const activeBrowserId = await getActiveBrowserId(); if (activeBrowserId) { @@ -389,45 +389,45 @@ export const RecordingsTable = ({ notify('warning', t('recordingtable.notifications.browser_limit_warning')); } } else { - startRetrainRecording(id, name, targetUrl); + startRetrainRecording(id, name, targetUrl); } }, [rows, setInitialUrl, setRecordingUrl]); const startRetrainRecording = (id: string, name: string, url?: string) => { setBrowserId('new-recording'); - setRecordingName(name); - setRecordingId(id); - + setRecordingName(name); + setRecordingId(id); + window.sessionStorage.setItem('browserId', 'new-recording'); window.sessionStorage.setItem('robotToRetrain', id); window.sessionStorage.setItem('robotName', name); - + window.sessionStorage.setItem('recordingUrl', url || recordingUrl); - + const sessionId = Date.now().toString(); window.sessionStorage.setItem('recordingSessionId', sessionId); - + window.openedRecordingWindow = window.open(`/recording-setup?session=${sessionId}`, '_blank'); - + window.sessionStorage.setItem('nextTabIsRecording', 'true'); }; const startRecording = () => { setModalOpen(false); - + // Set local state setBrowserId('new-recording'); setRecordingName(''); setRecordingId(''); - + window.sessionStorage.setItem('browserId', 'new-recording'); - + const sessionId = Date.now().toString(); window.sessionStorage.setItem('recordingSessionId', sessionId); window.sessionStorage.setItem('recordingUrl', recordingUrl); - + window.openedRecordingWindow = window.open(`/recording-setup?session=${sessionId}`, '_blank'); - + window.sessionStorage.setItem('nextTabIsRecording', 'true'); }; @@ -447,17 +447,17 @@ export const RecordingsTable = ({ function useDebounce(value: T, delay: number): T { const [debouncedValue, setDebouncedValue] = React.useState(value); - + useEffect(() => { const handler = setTimeout(() => { setDebouncedValue(value); }, delay); - + return () => { clearTimeout(handler); }; }, [value, delay]); - + return debouncedValue; } @@ -477,9 +477,9 @@ export const RecordingsTable = ({ }, [filteredRows, page, rowsPerPage]); const openDeleteConfirm = React.useCallback((id: string) => { - setPendingDeleteId(String(id)); - setDeleteConfirmOpen(true); - }, []); + setPendingDeleteId(String(id)); + setDeleteConfirmOpen(true); + }, []); const confirmDeleteRecording = React.useCallback(async () => { if (!pendingDeleteId) return; @@ -553,13 +553,13 @@ export const RecordingsTable = ({ - + {isFetching ? ( {debouncedSearchTerm ? t('recordingtable.placeholder.search') : t('recordingtable.placeholder.title')} - {debouncedSearchTerm + {debouncedSearchTerm ? t('recordingtable.search_criteria') : t('recordingtable.placeholder.body') } @@ -592,16 +592,16 @@ export const RecordingsTable = ({ <> - - {columns.map((column) => ( - - {column.label} - - ))} - + + {columns.map((column) => ( + + {column.label} + + ))} + {visibleRows.map((row) => ( {t('recordingtable.warning_modal.message')} - + + { + setDeleteConfirmOpen(false); + setPendingDeleteId(null); + }} + maxWidth="xs" + fullWidth + > + + {t('recordingtable.delete_confirm.title', { + name: pendingRow?.name, + defaultValue: 'Delete {{name}}?' + })} + + + + + {t('recordingtable.delete_confirm.message', { + name: pendingRow?.name, + defaultValue: 'Are you sure you want to delete the robot "{{name}}"?' + })} + + + + + - - - + + + ); } From f7a84bf4270724a019650ae45e30890d067bbc18 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Thu, 2 Apr 2026 21:43:20 +0530 Subject: [PATCH 03/16] chore: lint --- src/components/robot/RecordingsTable.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/robot/RecordingsTable.tsx b/src/components/robot/RecordingsTable.tsx index bfd8f9012..e49cc2115 100644 --- a/src/components/robot/RecordingsTable.tsx +++ b/src/components/robot/RecordingsTable.tsx @@ -862,7 +862,6 @@ const OptionsButton = ({ handleRetrain, handleEdit, handleDuplicate, handleDelet const MemoizedTableCell = memo(TableCell); -// Memoized action buttons const MemoizedInterpretButton = memo(InterpretButton); const MemoizedScheduleButton = memo(ScheduleButton); const MemoizedIntegrateButton = memo(IntegrateButton); From 110ef9c42a147e3edab78a8a8175c4b564e88420 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Thu, 2 Apr 2026 21:44:26 +0530 Subject: [PATCH 04/16] fix: color error --- src/components/robot/RecordingsTable.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/robot/RecordingsTable.tsx b/src/components/robot/RecordingsTable.tsx index e49cc2115..3afe6a92a 100644 --- a/src/components/robot/RecordingsTable.tsx +++ b/src/components/robot/RecordingsTable.tsx @@ -723,8 +723,7 @@ export const RecordingsTable = ({ From 3d394b1a8038bab20acaa3a116c00df682d9b57d Mon Sep 17 00:00:00 2001 From: amhsirak Date: Thu, 2 Apr 2026 21:45:11 +0530 Subject: [PATCH 05/16] fix: remove outlined --- src/components/robot/RecordingsTable.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/robot/RecordingsTable.tsx b/src/components/robot/RecordingsTable.tsx index 3afe6a92a..b9820b505 100644 --- a/src/components/robot/RecordingsTable.tsx +++ b/src/components/robot/RecordingsTable.tsx @@ -716,7 +716,6 @@ export const RecordingsTable = ({ setPendingDeleteId(null); }} color="inherit" - variant="outlined" > {t('common.cancel', { defaultValue: 'Cancel' })} From 1979fa92d7b3d62db89dbeb2eb372da476f227f3 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Thu, 2 Apr 2026 21:52:14 +0530 Subject: [PATCH 06/16] fix: remove custom fontweight --- src/components/robot/RecordingsTable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/robot/RecordingsTable.tsx b/src/components/robot/RecordingsTable.tsx index b9820b505..358edc10c 100644 --- a/src/components/robot/RecordingsTable.tsx +++ b/src/components/robot/RecordingsTable.tsx @@ -693,7 +693,7 @@ export const RecordingsTable = ({ maxWidth="xs" fullWidth > - + {t('recordingtable.delete_confirm.title', { name: pendingRow?.name, defaultValue: 'Delete {{name}}?' From 59ec403450213d36518859e7e29ffa5b418ef2b4 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Thu, 2 Apr 2026 22:07:26 +0530 Subject: [PATCH 07/16] feat: replace generic modal w dialog --- src/components/run/ColapsibleRow.tsx | 80 +++++++++++++++++++--------- 1 file changed, 54 insertions(+), 26 deletions(-) diff --git a/src/components/run/ColapsibleRow.tsx b/src/components/run/ColapsibleRow.tsx index 257476ec0..821798595 100644 --- a/src/components/run/ColapsibleRow.tsx +++ b/src/components/run/ColapsibleRow.tsx @@ -2,7 +2,10 @@ import { useEffect, useRef, useState } from "react"; import * as React from "react"; import TableRow from "@mui/material/TableRow"; import TableCell from "@mui/material/TableCell"; -import { Box, Collapse, IconButton, Typography, Chip, TextField } from "@mui/material"; +import { Box, Collapse, IconButton, Typography, Chip, TextField, Dialog, DialogTitle, + DialogContent, + DialogContentText, + DialogActions, } from "@mui/material"; import { Button } from "@mui/material"; import { DeleteForever, KeyboardArrowDown, KeyboardArrowUp, Settings } from "@mui/icons-material"; import { deleteRunFromStorage } from "../../api/storage"; @@ -282,31 +285,56 @@ export const CollapsibleRow = ({ row, handleDelete, isOpen, onToggleExpanded, cu - setDeleteOpen(false)} modalStyle={{ ...modalStyle, padding: 0, backgroundColor: 'transparent', width: 'auto', maxWidth: '520px' }}> - - - {t('runs_table.delete_confirm.title', { - name: row.name, - defaultValue: 'Delete run "{{name}}"?' - })} - - - {t('runs_table.delete_confirm.message', { - name: row.name, - defaultValue: 'Are you sure you want to delete the run "{{name}}"?' - })} - - - - - - - + setDeleteOpen(false)} + maxWidth="xs" + fullWidth + PaperProps={{ + sx: { + p: 0, + backgroundColor: theme.palette.mode === 'dark' + ? theme.palette.grey[900] + : theme.palette.background.paper, + borderRadius: 2, + width: { xs: '90vw', sm: '460px', md: '420px' }, + maxWidth: '90vw', + boxSizing: 'border-box' + } + }} +> + + {t('runs_table.delete_confirm.title', { + name: row.name, + defaultValue: 'Delete run "{{name}}"?' + })} + + + + + {t('runs_table.delete_confirm.message', { + name: row.name, + defaultValue: 'Are you sure you want to delete the run "{{name}}"?' + })} + + + + + + + + + ); } From c1e885ac4bb6977d234045e7c942f8bdaa97dc42 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Thu, 2 Apr 2026 22:07:42 +0530 Subject: [PATCH 08/16] chore: lint --- src/components/run/ColapsibleRow.tsx | 118 ++++++++++++++------------- 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/src/components/run/ColapsibleRow.tsx b/src/components/run/ColapsibleRow.tsx index 821798595..f44c50e57 100644 --- a/src/components/run/ColapsibleRow.tsx +++ b/src/components/run/ColapsibleRow.tsx @@ -2,10 +2,12 @@ import { useEffect, useRef, useState } from "react"; import * as React from "react"; import TableRow from "@mui/material/TableRow"; import TableCell from "@mui/material/TableCell"; -import { Box, Collapse, IconButton, Typography, Chip, TextField, Dialog, DialogTitle, +import { + Box, Collapse, IconButton, Typography, Chip, TextField, Dialog, DialogTitle, DialogContent, DialogContentText, - DialogActions, } from "@mui/material"; + DialogActions, +} from "@mui/material"; import { Button } from "@mui/material"; import { DeleteForever, KeyboardArrowDown, KeyboardArrowUp, Settings } from "@mui/icons-material"; import { deleteRunFromStorage } from "../../api/storage"; @@ -89,15 +91,15 @@ export const CollapsibleRow = ({ row, handleDelete, isOpen, onToggleExpanded, cu const [openSettingsModal, setOpenSettingsModal] = useState(false); const [userEmail, setUserEmail] = useState(null); const runByLabel = row.runByScheduleId - ? `${row.runByScheduleId}` - : row.runByUserId - ? `${userEmail}` - : row.runBySDK - ? 'SDK' - : row.runByAPI - ? 'API' - : 'Unknown'; - + ? `${row.runByScheduleId}` + : row.runByUserId + ? `${userEmail}` + : row.runBySDK + ? 'SDK' + : row.runByAPI + ? 'API' + : 'Unknown'; + const logEndRef = useRef(null); const [workflowProgress, setWorkflowProgress] = useState<{ @@ -245,7 +247,7 @@ export const CollapsibleRow = ({ row, handleDelete, isOpen, onToggleExpanded, cu setDeleteOpen(false)} - maxWidth="xs" - fullWidth - PaperProps={{ - sx: { - p: 0, - backgroundColor: theme.palette.mode === 'dark' - ? theme.palette.grey[900] - : theme.palette.background.paper, - borderRadius: 2, - width: { xs: '90vw', sm: '460px', md: '420px' }, - maxWidth: '90vw', - boxSizing: 'border-box' - } - }} -> - - {t('runs_table.delete_confirm.title', { - name: row.name, - defaultValue: 'Delete run "{{name}}"?' - })} - + open={isDeleteOpen} + onClose={() => setDeleteOpen(false)} + maxWidth="xs" + fullWidth + PaperProps={{ + sx: { + p: 0, + backgroundColor: theme.palette.mode === 'dark' + ? theme.palette.grey[900] + : theme.palette.background.paper, + borderRadius: 2, + width: { xs: '90vw', sm: '460px', md: '420px' }, + maxWidth: '90vw', + boxSizing: 'border-box' + } + }} + > + + {t('runs_table.delete_confirm.title', { + name: row.name, + defaultValue: 'Delete run "{{name}}"?' + })} + - - - {t('runs_table.delete_confirm.message', { - name: row.name, - defaultValue: 'Are you sure you want to delete the run "{{name}}"?' - })} - - + + + {t('runs_table.delete_confirm.message', { + name: row.name, + defaultValue: 'Are you sure you want to delete the run "{{name}}"?' + })} + + - - + + - - - + + + ); } From ba6ac594f6cbe74c60ff5797a4c0c1873ff96dc3 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Thu, 2 Apr 2026 22:20:58 +0530 Subject: [PATCH 09/16] feat: replace generic modal w dialog --- .../browser/BrowserRecordingSave.tsx | 48 +++++++++++++------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/src/components/browser/BrowserRecordingSave.tsx b/src/components/browser/BrowserRecordingSave.tsx index 5beed5d03..4213d0035 100644 --- a/src/components/browser/BrowserRecordingSave.tsx +++ b/src/components/browser/BrowserRecordingSave.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react' -import { Grid, Button, Box, Typography, IconButton, Menu, MenuItem, ListItemText } from '@mui/material'; +import { Grid, Button, Box, Typography, IconButton, Menu, MenuItem, ListItemText, Dialog, DialogTitle, DialogActions, } from '@mui/material'; import { SaveRecording } from "../recorder/SaveRecording"; import { useGlobalInfoStore } from '../../context/globalInfo'; import { useActionContext } from '../../context/browserActions'; @@ -183,19 +183,39 @@ const BrowserRecordingSave = () => { - setOpenDiscardModal(false)} modalStyle={modalStyle}> - - {t('browser_recording.modal.confirm_discard')} - - - - - - + setOpenDiscardModal(false)} + maxWidth="xs" + fullWidth + PaperProps={{ + sx: { + p: 0, + borderRadius: 2 + } + }} +> + + {t('browser_recording.modal.confirm_discard')} + + + + + + + + setOpenResetModal(false)} modalStyle={modalStyle}> From 255811b734d8f8f09aa49eb0925f79de09e5c3c8 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Thu, 2 Apr 2026 22:21:09 +0530 Subject: [PATCH 10/16] chore: lint --- .../browser/BrowserRecordingSave.tsx | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/src/components/browser/BrowserRecordingSave.tsx b/src/components/browser/BrowserRecordingSave.tsx index 4213d0035..a94977361 100644 --- a/src/components/browser/BrowserRecordingSave.tsx +++ b/src/components/browser/BrowserRecordingSave.tsx @@ -20,9 +20,9 @@ const BrowserRecordingSave = () => { const { socket } = useSocketStore(); - const { - stopGetText, - stopGetList, + const { + stopGetText, + stopGetList, stopGetScreenshot, stopPaginationMode, stopLimitMode, @@ -45,7 +45,7 @@ const BrowserRecordingSave = () => { timestamp: Date.now() }; window.sessionStorage.setItem('pendingNotification', JSON.stringify(notificationData)); - + if (window.opener) { window.opener.postMessage({ type: 'recording-notification', @@ -57,9 +57,9 @@ const BrowserRecordingSave = () => { timestamp: Date.now() }, '*'); } - + setBrowserId(null); - + window.close(); stopRecording(browserId).catch((error) => { @@ -74,7 +74,7 @@ const BrowserRecordingSave = () => { stopGetScreenshot(); stopPaginationMode(); stopLimitMode(); - + setShowLimitOptions(false); setShowPaginationOptions(false); setCaptureStage('initial'); @@ -97,7 +97,7 @@ const BrowserRecordingSave = () => { browserSteps.forEach(step => { deleteBrowserStep(step.id); }); - + if (socket) { socket?.emit('new-recording'); socket.emit('input:url', initialUrl); @@ -119,7 +119,7 @@ const BrowserRecordingSave = () => { }; const handleClick = (event: any) => { - setAnchorEl(event.currentTarget); + setAnchorEl(event.currentTarget); }; const handleClose = () => { @@ -184,38 +184,38 @@ const BrowserRecordingSave = () => { setOpenDiscardModal(false)} - maxWidth="xs" - fullWidth - PaperProps={{ - sx: { - p: 0, - borderRadius: 2 - } - }} -> - - {t('browser_recording.modal.confirm_discard')} - + open={openDiscardModal} + onClose={() => setOpenDiscardModal(false)} + maxWidth="xs" + fullWidth + PaperProps={{ + sx: { + p: 0, + borderRadius: 2 + } + }} + > + + {t('browser_recording.modal.confirm_discard')} + - - + + - - - + + + setOpenResetModal(false)} modalStyle={modalStyle}> @@ -224,9 +224,9 @@ const BrowserRecordingSave = () => { {t('browser_recording.modal.reset_warning')} - - - From 5e189204c5e60489e17622cfd2c48bd62b570528 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Thu, 2 Apr 2026 22:25:02 +0530 Subject: [PATCH 12/16] fix: border none --- src/components/browser/BrowserRecordingSave.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/browser/BrowserRecordingSave.tsx b/src/components/browser/BrowserRecordingSave.tsx index e1fb51879..7172dbf95 100644 --- a/src/components/browser/BrowserRecordingSave.tsx +++ b/src/components/browser/BrowserRecordingSave.tsx @@ -191,7 +191,8 @@ const BrowserRecordingSave = () => { PaperProps={{ sx: { p: 0, - borderRadius: 2 + borderRadius: 2, + border: "none" } }} > From 1411c3c1e60eb20afe80693aedd18a23961d900d Mon Sep 17 00:00:00 2001 From: amhsirak Date: Thu, 2 Apr 2026 22:36:29 +0530 Subject: [PATCH 13/16] feat: replace generic modal w dialog --- src/components/recorder/SaveRecording.tsx | 74 +++++++++++++++-------- 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/src/components/recorder/SaveRecording.tsx b/src/components/recorder/SaveRecording.tsx index cbfa7ae84..e3a0d4fce 100644 --- a/src/components/recorder/SaveRecording.tsx +++ b/src/components/recorder/SaveRecording.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useState, useContext } from 'react'; -import { Button, Box, LinearProgress, Tooltip } from "@mui/material"; +import { Button, Box, LinearProgress, Tooltip, Dialog, DialogTitle, DialogContent } from "@mui/material"; import { GenericModal } from "../ui/GenericModal"; import { stopRecording } from "../../api/recording"; import { useGlobalInfoStore } from "../../context/globalInfo"; @@ -160,30 +160,54 @@ export const SaveRecording = ({ fileName }: SaveRecordingProps) => { {t('right_panel.buttons.finish')} - setOpenModal(false)} modalStyle={modalStyle}> -
- {t('save_recording.title')} - - - {waitingForSave && - - - - - - } - -
+ setOpenModal(false)} + maxWidth="xs" + fullWidth + PaperProps={{ + sx: { + p: 0, + borderRadius: 2 + } + }} +> + + {t('save_recording.title')} + + + +
+ + + + + {waitingForSave && ( + + + + + + )} + +
+
); } From 119dcbf720dbb37d9bae5ab2e964ede3897eaa94 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Thu, 2 Apr 2026 22:43:25 +0530 Subject: [PATCH 14/16] chore: cleanup unused imports --- src/components/recorder/SaveRecording.tsx | 117 +++++++++++----------- 1 file changed, 58 insertions(+), 59 deletions(-) diff --git a/src/components/recorder/SaveRecording.tsx b/src/components/recorder/SaveRecording.tsx index e3a0d4fce..a6a43ffc6 100644 --- a/src/components/recorder/SaveRecording.tsx +++ b/src/components/recorder/SaveRecording.tsx @@ -1,11 +1,10 @@ import React, { useCallback, useEffect, useState, useContext } from 'react'; -import { Button, Box, LinearProgress, Tooltip, Dialog, DialogTitle, DialogContent } from "@mui/material"; -import { GenericModal } from "../ui/GenericModal"; +import { Button, Box, LinearProgress, Tooltip, Dialog, DialogTitle, DialogContent } from "@mui/material"; import { stopRecording } from "../../api/recording"; import { useGlobalInfoStore } from "../../context/globalInfo"; import { AuthContext } from '../../context/auth'; import { useSocketStore } from "../../context/socket"; -import { TextField, Typography } from "@mui/material"; +import { TextField } from "@mui/material"; import { useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; @@ -48,7 +47,7 @@ export const SaveRecording = ({ fileName }: SaveRecordingProps) => { const handleFinishClick = () => { const { hasScrapeListAction, hasScreenshotAction, hasScrapeSchemaAction } = currentWorkflowActionsState; const hasAnyAction = hasScrapeListAction || hasScreenshotAction || hasScrapeSchemaAction; - + if (!hasAnyAction) { notify('warning', t('save_recording.errors.no_actions_performed')); return; @@ -63,7 +62,7 @@ export const SaveRecording = ({ fileName }: SaveRecordingProps) => { const exitRecording = useCallback(async (data?: { actionType: string }) => { let successMessage = t('save_recording.notifications.save_success'); - + if (data && data.actionType) { if (data.actionType === 'retrained') { successMessage = t('save_recording.notifications.retrain_success'); @@ -73,31 +72,31 @@ export const SaveRecording = ({ fileName }: SaveRecordingProps) => { successMessage = t('save_recording.notifications.save_error'); } } - + const notificationData = { type: data?.actionType === 'error' ? 'error' : 'success', message: successMessage, timestamp: Date.now() }; window.sessionStorage.setItem('pendingNotification', JSON.stringify(notificationData)); - + if (window.opener) { window.opener.postMessage({ type: 'recording-notification', notification: notificationData }, '*'); - + window.opener.postMessage({ type: 'session-data-clear', timestamp: Date.now() }, '*'); } - + if (browserId) { await stopRecording(browserId); } setBrowserId(null); - + window.close(); }, [setBrowserId, browserId, t]); @@ -107,7 +106,7 @@ export const SaveRecording = ({ fileName }: SaveRecordingProps) => { if (user) { const { hasScrapeListAction, hasScreenshotAction, hasScrapeSchemaAction } = currentWorkflowActionsState; const hasAnyAction = hasScrapeListAction || hasScreenshotAction || hasScrapeSchemaAction; - + if (!hasAnyAction) { notify('warning', t('save_recording.errors.no_actions_performed')); return; @@ -160,54 +159,54 @@ export const SaveRecording = ({ fileName }: SaveRecordingProps) => { {t('right_panel.buttons.finish')} - setOpenModal(false)} - maxWidth="xs" - fullWidth - PaperProps={{ - sx: { - p: 0, - borderRadius: 2 - } - }} -> - - {t('save_recording.title')} - - - -
- - - - - {waitingForSave && ( - - - - - - )} - -
-
+ setOpenModal(false)} + maxWidth="xs" + fullWidth + PaperProps={{ + sx: { + p: 0, + borderRadius: 2 + } + }} + > + + {t('save_recording.title')} + + + +
+ + + + + {waitingForSave && ( + + + + + + )} + +
+
); } From f07687ee2a65f4da982260ff6ba4882b76386035 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Thu, 2 Apr 2026 23:14:44 +0530 Subject: [PATCH 15/16] feat: replace generic modal w dialog --- src/components/robot/pages/RobotCreate.tsx | 582 +++++++++++---------- 1 file changed, 299 insertions(+), 283 deletions(-) diff --git a/src/components/robot/pages/RobotCreate.tsx b/src/components/robot/pages/RobotCreate.tsx index 78a80b5fa..ef49a1932 100644 --- a/src/components/robot/pages/RobotCreate.tsx +++ b/src/components/robot/pages/RobotCreate.tsx @@ -18,6 +18,10 @@ import { Select, MenuItem, InputLabel, + Dialog, + DialogTitle, + DialogContent, + DialogActions, Collapse, FormControlLabel } from '@mui/material'; @@ -244,7 +248,7 @@ const RobotCreate: React.FC = () => { setIsLoading(true); try { const formatsForRequest = searchMode === 'discover' ? [] : searchOutputFormats; - + const result = await createSearchRobot( searchRobotName, { @@ -368,7 +372,7 @@ const RobotCreate: React.FC = () => { } }} > - + Recorder Mode @@ -409,7 +413,7 @@ const RobotCreate: React.FC = () => { Beta
- + AI Mode @@ -421,247 +425,247 @@ const RobotCreate: React.FC = () => {
- {generationMode === 'agent' && ( - - - setExtractRobotName(e.target.value)} - label="Name" - /> - + {generationMode === 'agent' && ( + + + setExtractRobotName(e.target.value)} + label="Name" + /> + + + + setAiPrompt(e.target.value)} + label="Extraction Prompt" + /> + + + setUrl(e.target.value)} + label="Website URL (Optional)" + /> + + + + + LLM Provider + + + + + Model + + + + + {/* API Key for non-Ollama providers */} + {llmProvider !== 'ollama' && ( setAiPrompt(e.target.value)} - label="Extraction Prompt" + type="password" + value={llmApiKey} + onChange={(e) => setLlmApiKey(e.target.value)} + label="API Key (Optional if set in .env)" /> + )} + {llmProvider === 'ollama' && ( setUrl(e.target.value)} - label="Website URL (Optional)" + value={llmBaseUrl} + onChange={(e) => setLlmBaseUrl(e.target.value)} + label="Ollama Base URL (Optional)" /> + )} - - - LLM Provider - - - - - Model - - - + - - )} + } catch (error: any) { + console.error('Error in AI robot creation:', error); + removeOptimisticRobot(tempRobotId); + invalidateRecordings(); + notify('error', error?.message || 'Failed to create and run AI robot'); + } + }} + disabled={!extractRobotName.trim() || !aiPrompt.trim() || isLoading} + sx={{ + bgcolor: '#ff00c3', + py: 1.4, + fontSize: '1rem', + textTransform: 'none', + borderRadius: 2 + }} + startIcon={isLoading ? : null} + > + {isLoading ? 'Creating & Running...' : 'Create & Run Robot'} + + + )} - {generationMode === 'recorder' && ( + {generationMode === 'recorder' && ( <> { - )} -
+ )} + @@ -942,13 +946,13 @@ const RobotCreate: React.FC = () => { @@ -1102,38 +1106,38 @@ const RobotCreate: React.FC = () => { - Mode - + Mode + - Time Range - + Time Range + @@ -1195,38 +1199,50 @@ const RobotCreate: React.FC = () => { - - { - setWarningModalOpen(false); - setIsLoading(false); - }} modalStyle={modalStyle}> -
- {t('recordingtable.warning_modal.title')} - + { + setWarningModalOpen(false); + setIsLoading(false); + }} + maxWidth="xs" + fullWidth + PaperProps={{ + sx: { + p: 0, + borderRadius: 2 + } + }} + > + + {t('recordingtable.warning_modal.title')} + + + + {t('recordingtable.warning_modal.message')} + - - - - -
-
- + + + + + ); From b3a2f9d95e3e03b9a3a807943c258554197af331 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Thu, 2 Apr 2026 23:17:02 +0530 Subject: [PATCH 16/16] feat: replace generic modal w dialog --- src/components/robot/RecordingsTable.tsx | 56 +++++++++++++++--------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/src/components/robot/RecordingsTable.tsx b/src/components/robot/RecordingsTable.tsx index 358edc10c..dfb69de00 100644 --- a/src/components/robot/RecordingsTable.tsx +++ b/src/components/robot/RecordingsTable.tsx @@ -625,30 +625,44 @@ export const RecordingsTable = ({ /> )} - setWarningModalOpen(false)} modalStyle={modalStyle}> -
- {t('recordingtable.warning_modal.title')} - + setWarningModalOpen(false)} + maxWidth="xs" + fullWidth + PaperProps={{ + sx: { + p: 0, + borderRadius: 2 + } + }} + > + + {t('recordingtable.warning_modal.title')} + + + + {t('recordingtable.warning_modal.message')} + - - - - -
-
+ + + + + setModalOpen(false)} modalStyle={modalStyle}>
{t('recordingtable.modal.title')}