Merge pull request #530 from getmaxun/retrain-robot

feat: retrain robot
This commit is contained in:
Karishma Shukla
2025-04-22 00:52:19 +05:30
committed by GitHub
11 changed files with 228 additions and 52 deletions

View File

@@ -54,6 +54,7 @@
"label": "URL", "label": "URL",
"button": "Aufnahme starten" "button": "Aufnahme starten"
}, },
"retrain": "Neu trainieren",
"edit": "Bearbeiten", "edit": "Bearbeiten",
"delete": "Löschen", "delete": "Löschen",
"duplicate": "Duplizieren", "duplicate": "Duplizieren",
@@ -237,7 +238,9 @@
"confirm": "Bestätigen" "confirm": "Bestätigen"
}, },
"notifications": { "notifications": {
"save_success": "Roboter erfolgreich gespeichert" "save_success": "Roboter erfolgreich gespeichert",
"retrain_success": "Roboter erfolgreich neu trainiert",
"save_error": "Fehler beim Speichern des Roboters"
}, },
"errors": { "errors": {
"user_not_logged": "Benutzer nicht angemeldet. Aufnahme kann nicht gespeichert werden.", "user_not_logged": "Benutzer nicht angemeldet. Aufnahme kann nicht gespeichert werden.",

View File

@@ -60,6 +60,7 @@
"discard_and_create":"Discard & Create New", "discard_and_create":"Discard & Create New",
"cancel":"Cancel" "cancel":"Cancel"
}, },
"retrain": "Retrain",
"edit":"Edit", "edit":"Edit",
"delete":"Delete", "delete":"Delete",
"duplicate":"Duplicate", "duplicate":"Duplicate",
@@ -245,7 +246,9 @@
"confirm": "Confirm" "confirm": "Confirm"
}, },
"notifications": { "notifications": {
"save_success": "Robot saved successfully" "save_success": "Robot saved successfully",
"retrain_success": "Robot retrained successfully",
"save_error": "Error saving robot"
}, },
"errors": { "errors": {
"user_not_logged": "User not logged in. Cannot save recording.", "user_not_logged": "User not logged in. Cannot save recording.",

View File

@@ -54,6 +54,7 @@
"label": "URL", "label": "URL",
"button": "Comenzar grabación" "button": "Comenzar grabación"
}, },
"retrain": "Reentrenar",
"edit": "Editar", "edit": "Editar",
"delete": "Eliminar", "delete": "Eliminar",
"duplicate": "Duplicar", "duplicate": "Duplicar",
@@ -238,7 +239,9 @@
"confirm": "Confirmar" "confirm": "Confirmar"
}, },
"notifications": { "notifications": {
"save_success": "Robot guardado exitosamente" "save_success": "Robot guardado correctamente",
"retrain_success": "Robot reentrenado correctamente",
"save_error": "Error al guardar el robot"
}, },
"errors": { "errors": {
"user_not_logged": "Usuario no conectado. No se puede guardar la grabación.", "user_not_logged": "Usuario no conectado. No se puede guardar la grabación.",

View File

@@ -54,6 +54,7 @@
"label": "URL", "label": "URL",
"button": "録画を開始" "button": "録画を開始"
}, },
"retrain": "再学習",
"edit": "編集", "edit": "編集",
"delete": "削除", "delete": "削除",
"duplicate": "複製", "duplicate": "複製",
@@ -238,7 +239,9 @@
"confirm": "確認" "confirm": "確認"
}, },
"notifications": { "notifications": {
"save_success": "ロボットが正常に保存されました" "save_success": "ロボットの保存に成功しました",
"retrain_success": "ロボットの再トレーニングに成功しました",
"save_error": "ロボットの保存中にエラーが発生しました"
}, },
"errors": { "errors": {
"user_not_logged": "ユーザーがログインしていません。録画を保存できません。", "user_not_logged": "ユーザーがログインしていません。録画を保存できません。",

View File

@@ -54,6 +54,7 @@
"label": "URL", "label": "URL",
"button": "开始录制" "button": "开始录制"
}, },
"retrain": "重新训练",
"edit": "编辑", "edit": "编辑",
"delete": "删除", "delete": "删除",
"duplicate": "复制", "duplicate": "复制",
@@ -238,7 +239,9 @@
"confirm": "确认" "confirm": "确认"
}, },
"notifications": { "notifications": {
"save_success": "机器人保存成功" "save_success": "机器人保存成功",
"retrain_success": "机器人重新训练成功",
"save_error": "保存机器人时出错"
}, },
"errors": { "errors": {
"user_not_logged": "用户未登录。无法保存录制。", "user_not_logged": "用户未登录。无法保存录制。",

View File

@@ -139,12 +139,14 @@ export class WorkflowGenerator {
*/ */
private registerEventHandlers = (socket: Socket) => { private registerEventHandlers = (socket: Socket) => {
socket.on('save', (data) => { socket.on('save', (data) => {
const { fileName, userId, isLogin } = data; const { fileName, userId, isLogin, robotId } = data;
logger.log('debug', `Saving workflow ${fileName} for user ID ${userId}`); logger.log('debug', `Saving workflow ${fileName} for user ID ${userId}`);
this.saveNewWorkflow(fileName, userId, isLogin); this.saveNewWorkflow(fileName, userId, isLogin, robotId);
}); });
socket.on('new-recording', () => this.workflowRecord = { socket.on('new-recording', (data) => {
workflow: [], this.workflowRecord = {
workflow: [],
};
}); });
socket.on('activeIndex', (data) => this.generatedData.lastIndex = parseInt(data)); socket.on('activeIndex', (data) => this.generatedData.lastIndex = parseInt(data));
socket.on('decision', async ({ pair, actionType, decision, userId }) => { socket.on('decision', async ({ pair, actionType, decision, userId }) => {
@@ -764,38 +766,62 @@ export class WorkflowGenerator {
* @param fileName The name of the file. * @param fileName The name of the file.
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
public saveNewWorkflow = async (fileName: string, userId: number, isLogin: boolean) => { public saveNewWorkflow = async (fileName: string, userId: number, isLogin: boolean, robotId?: string) => {
const recording = this.optimizeWorkflow(this.workflowRecord); const recording = this.optimizeWorkflow(this.workflowRecord);
let actionType = 'saved';
try { try {
this.recordingMeta = { if (robotId) {
name: fileName, const robot = await Robot.findOne({ where: { 'recording_meta.id': robotId }});
id: uuid(),
createdAt: this.recordingMeta.createdAt || new Date().toLocaleString(),
pairs: recording.workflow.length,
updatedAt: new Date().toLocaleString(),
params: this.getParams() || [],
isLogin: isLogin,
}
const robot = await Robot.create({
userId,
recording_meta: this.recordingMeta,
recording: recording,
});
capture(
'maxun-oss-robot-created',
{
robot_meta: robot.recording_meta,
recording: robot.recording,
}
)
logger.log('info', `Robot saved with id: ${robot.id}`); if (robot) {
await robot.update({
recording: recording,
recording_meta: {
...robot.recording_meta,
pairs: recording.workflow.length,
params: this.getParams() || [],
updatedAt: new Date().toLocaleString(),
},
})
actionType = 'retrained';
logger.log('info', `Robot retrained with id: ${robot.id}`);
}
} else {
this.recordingMeta = {
name: fileName,
id: uuid(),
createdAt: this.recordingMeta.createdAt || new Date().toLocaleString(),
pairs: recording.workflow.length,
updatedAt: new Date().toLocaleString(),
params: this.getParams() || [],
isLogin: isLogin,
}
const robot = await Robot.create({
userId,
recording_meta: this.recordingMeta,
recording: recording,
});
capture(
'maxun-oss-robot-created',
{
robot_meta: robot.recording_meta,
recording: robot.recording,
}
)
actionType = 'saved';
logger.log('info', `Robot saved with id: ${robot.id}`);
}
} }
catch (e) { catch (e) {
const { message } = e as Error; const { message } = e as Error;
logger.log('warn', `Cannot save the file to the local file system ${e}`) logger.log('warn', `Cannot save the file to the local file system ${e}`)
actionType = 'error';
} }
this.socket.emit('fileSaved');
this.socket.emit('fileSaved', { actionType });
} }
/** /**

View File

@@ -55,6 +55,11 @@ const BrowserRecordingSave = () => {
type: 'recording-notification', type: 'recording-notification',
notification: notificationData notification: notificationData
}, '*'); }, '*');
window.opener.postMessage({
type: 'session-data-clear',
timestamp: Date.now()
}, '*');
} }
setBrowserId(null); setBrowserId(null);

View File

@@ -19,26 +19,32 @@ export const SaveRecording = ({ fileName }: SaveRecordingProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const [openModal, setOpenModal] = useState<boolean>(false); const [openModal, setOpenModal] = useState<boolean>(false);
const [needConfirm, setNeedConfirm] = useState<boolean>(false); const [needConfirm, setNeedConfirm] = useState<boolean>(false);
const [recordingName, setRecordingName] = useState<string>(fileName); const [saveRecordingName, setSaveRecordingName] = useState<string>(fileName);
const [waitingForSave, setWaitingForSave] = useState<boolean>(false); const [waitingForSave, setWaitingForSave] = useState<boolean>(false);
const { browserId, setBrowserId, notify, recordings, isLogin } = useGlobalInfoStore(); const { browserId, setBrowserId, notify, recordings, isLogin, recordingName, retrainRobotId } = useGlobalInfoStore();
const { socket } = useSocketStore(); const { socket } = useSocketStore();
const { state, dispatch } = useContext(AuthContext); const { state, dispatch } = useContext(AuthContext);
const { user } = state; const { user } = state;
const navigate = useNavigate(); const navigate = useNavigate();
useEffect(() => {
if (recordingName) {
setSaveRecordingName(recordingName);
}
}, [recordingName]);
const handleChangeOfTitle = (event: React.ChangeEvent<HTMLInputElement>) => { const handleChangeOfTitle = (event: React.ChangeEvent<HTMLInputElement>) => {
const { value } = event.target; const { value } = event.target;
if (needConfirm) { if (needConfirm) {
setNeedConfirm(false); setNeedConfirm(false);
} }
setRecordingName(value); setSaveRecordingName(value);
} }
const handleSaveRecording = async (event: React.SyntheticEvent) => { const handleSaveRecording = async (event: React.SyntheticEvent) => {
event.preventDefault(); event.preventDefault();
if (recordings.includes(recordingName)) { if (recordings.includes(saveRecordingName)) {
if (needConfirm) { return; } if (needConfirm) { return; }
setNeedConfirm(true); setNeedConfirm(true);
} else { } else {
@@ -46,19 +52,43 @@ export const SaveRecording = ({ fileName }: SaveRecordingProps) => {
} }
}; };
const exitRecording = useCallback(async () => { const handleFinishClick = () => {
if (recordingName && !recordings.includes(recordingName)) {
saveRecording();
} else {
setOpenModal(true);
}
};
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');
} else if (data.actionType === 'saved') {
successMessage = t('save_recording.notifications.save_success');
} else if (data.actionType === 'error') {
successMessage = t('save_recording.notifications.save_error');
}
}
const notificationData = { const notificationData = {
type: 'success', type: 'success',
message: t('save_recording.notifications.save_success'), message: successMessage,
timestamp: Date.now() timestamp: Date.now()
}; };
window.sessionStorage.setItem('pendingNotification', JSON.stringify(notificationData));
if (window.opener) { if (window.opener) {
window.opener.postMessage({ window.opener.postMessage({
type: 'recording-notification', type: 'recording-notification',
notification: notificationData notification: notificationData
}, '*'); }, '*');
window.opener.postMessage({
type: 'session-data-clear',
timestamp: Date.now()
}, '*');
} }
if (browserId) { if (browserId) {
@@ -67,16 +97,21 @@ export const SaveRecording = ({ fileName }: SaveRecordingProps) => {
setBrowserId(null); setBrowserId(null);
window.close(); window.close();
}, [setBrowserId, browserId]); }, [setBrowserId, browserId, t]);
// notifies backed to save the recording in progress, // notifies backed to save the recording in progress,
// releases resources and changes the view for main page by clearing the global browserId // releases resources and changes the view for main page by clearing the global browserId
const saveRecording = async () => { const saveRecording = async () => {
if (user) { if (user) {
const payload = { fileName: recordingName, userId: user.id, isLogin: isLogin }; const payload = {
fileName: saveRecordingName || recordingName,
userId: user.id,
isLogin: isLogin,
robotId: retrainRobotId,
};
socket?.emit('save', payload); socket?.emit('save', payload);
setWaitingForSave(true); setWaitingForSave(true);
console.log(`Saving the recording as ${recordingName} for userId ${user.id}`); console.log(`Saving the recording as ${saveRecordingName || recordingName} for userId ${user.id}`);
} else { } else {
console.error(t('save_recording.notifications.user_not_logged')); console.error(t('save_recording.notifications.user_not_logged'));
} }
@@ -92,7 +127,7 @@ export const SaveRecording = ({ fileName }: SaveRecordingProps) => {
return ( return (
<div> <div>
<Button <Button
onClick={() => setOpenModal(true)} onClick={handleFinishClick}
variant="outlined" variant="outlined"
color="success" color="success"
sx={{ sx={{
@@ -116,7 +151,7 @@ export const SaveRecording = ({ fileName }: SaveRecordingProps) => {
id="title" id="title"
label={t('save_recording.robot_name')} label={t('save_recording.robot_name')}
variant="outlined" variant="outlined"
defaultValue={recordingName ? recordingName : null} value={saveRecordingName}
/> />
{needConfirm {needConfirm
? ?

View File

@@ -35,7 +35,8 @@ import {
Settings, Settings,
Power, Power,
ContentCopy, ContentCopy,
MoreHoriz MoreHoriz,
Refresh
} from "@mui/icons-material"; } from "@mui/icons-material";
import { useGlobalInfoStore } from "../../context/globalInfo"; import { useGlobalInfoStore } from "../../context/globalInfo";
import { checkRunsForRecording, deleteRecordingFromStorage, getStoredRecordings } from "../../api/storage"; import { checkRunsForRecording, deleteRecordingFromStorage, getStoredRecordings } from "../../api/storage";
@@ -117,6 +118,7 @@ const TableRowMemoized = memo(({ row, columns, handlers }: any) => {
return ( return (
<MemoizedTableCell key={column.id} align={column.align}> <MemoizedTableCell key={column.id} align={column.align}>
<MemoizedOptionsButton <MemoizedOptionsButton
handleRetrain={() =>handlers.handleRetrainRobot(row.id, row.name)}
handleEdit={() => handlers.handleEditRobot(row.id, row.name, row.params || [])} handleEdit={() => handlers.handleEditRobot(row.id, row.name, row.params || [])}
handleDuplicate={() => handlers.handleDuplicateRobot(row.id, row.name, row.params || [])} handleDuplicate={() => handlers.handleDuplicateRobot(row.id, row.name, row.params || [])}
handleDelete={() => handlers.handleDelete(row.id)} handleDelete={() => handlers.handleDelete(row.id)}
@@ -185,7 +187,7 @@ export const RecordingsTable = ({
useEffect(() => { useEffect(() => {
const handleMessage = (event: any) => { const handleMessage = (event: any) => {
if (event.data && event.data.type === 'recording-notification') { if (event.origin === window.location.origin && event.data && event.data.type === 'recording-notification') {
const notificationData = event.data.notification; const notificationData = event.data.notification;
if (notificationData) { if (notificationData) {
notify(notificationData.type, notificationData.message); notify(notificationData.type, notificationData.message);
@@ -198,6 +200,17 @@ export const RecordingsTable = ({
} }
} }
} }
if (event.origin === window.location.origin && event.data && event.data.type === 'session-data-clear') {
window.sessionStorage.removeItem('browserId');
window.sessionStorage.removeItem('robotToRetrain');
window.sessionStorage.removeItem('robotName');
window.sessionStorage.removeItem('recordingUrl');
window.sessionStorage.removeItem('recordingSessionId');
window.sessionStorage.removeItem('pendingSessionData');
window.sessionStorage.removeItem('nextTabIsRecording');
window.sessionStorage.removeItem('initialUrl');
}
}; };
window.addEventListener('message', handleMessage); window.addEventListener('message', handleMessage);
@@ -303,6 +316,60 @@ export const RecordingsTable = ({
setModalOpen(true); setModalOpen(true);
}; };
const handleRetrainRobot = useCallback(async (id: string, name: string) => {
const activeBrowserId = await getActiveBrowserId();
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 =>
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);
}
if (activeBrowserId) {
setActiveBrowserId(activeBrowserId);
setWarningModalOpen(true);
} else {
startRetrainRecording(id, name, targetUrl);
}
}, [rows, setInitialUrl, setRecordingUrl]);
const startRetrainRecording = (id: string, name: string, url?: string) => {
setBrowserId('new-recording');
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 = () => { const startRecording = () => {
setModalOpen(false); setModalOpen(false);
@@ -381,6 +448,7 @@ export const RecordingsTable = ({
handleSettingsRecording, handleSettingsRecording,
handleEditRobot, handleEditRobot,
handleDuplicateRobot, handleDuplicateRobot,
handleRetrainRobot,
handleDelete: async (id: string) => { handleDelete: async (id: string) => {
const hasRuns = await checkRunsForRecording(id); const hasRuns = await checkRunsForRecording(id);
if (hasRuns) { if (hasRuns) {
@@ -395,7 +463,7 @@ export const RecordingsTable = ({
fetchRecordings(); fetchRecordings();
} }
} }
}), [handleRunRecording, handleScheduleRecording, handleIntegrateRecording, handleSettingsRecording, handleEditRobot, handleDuplicateRobot, notify, t]); }), [handleRunRecording, handleScheduleRecording, handleIntegrateRecording, handleSettingsRecording, handleEditRobot, handleDuplicateRobot, handleRetrainRobot, notify, t]);
return ( return (
<React.Fragment> <React.Fragment>
@@ -597,12 +665,13 @@ const SettingsButton = ({ handleSettings }: SettingsButtonProps) => {
} }
interface OptionsButtonProps { interface OptionsButtonProps {
handleRetrain: () => void;
handleEdit: () => void; handleEdit: () => void;
handleDelete: () => void; handleDelete: () => void;
handleDuplicate: () => void; handleDuplicate: () => void;
} }
const OptionsButton = ({ handleEdit, handleDelete, handleDuplicate }: OptionsButtonProps) => { const OptionsButton = ({ handleRetrain, handleEdit, handleDelete, handleDuplicate }: OptionsButtonProps) => {
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null); const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const handleClick = (event: React.MouseEvent<HTMLElement>) => { const handleClick = (event: React.MouseEvent<HTMLElement>) => {
@@ -629,6 +698,13 @@ const OptionsButton = ({ handleEdit, handleDelete, handleDuplicate }: OptionsBut
open={Boolean(anchorEl)} open={Boolean(anchorEl)}
onClose={handleClose} onClose={handleClose}
> >
<MenuItem onClick={() => { handleRetrain(); handleClose(); }}>
<ListItemIcon>
<Refresh fontSize="small" />
</ListItemIcon>
<ListItemText>{t('recordingtable.retrain')}</ListItemText>
</MenuItem>
<MenuItem onClick={() => { handleEdit(); handleClose(); }}> <MenuItem onClick={() => { handleEdit(); handleClose(); }}>
<ListItemIcon> <ListItemIcon>
<Edit fontSize="small" /> <Edit fontSize="small" />

View File

@@ -60,6 +60,8 @@ interface GlobalInfo {
setRecordingLength: (recordingLength: number) => void; setRecordingLength: (recordingLength: number) => void;
recordingId: string | null; recordingId: string | null;
setRecordingId: (newId: string | null) => void; setRecordingId: (newId: string | null) => void;
retrainRobotId: string | null;
setRetrainRobotId: (newId: string | null) => void;
recordingName: string; recordingName: string;
setRecordingName: (recordingName: string) => void; setRecordingName: (recordingName: string) => void;
initialUrl: string; initialUrl: string;
@@ -90,6 +92,7 @@ class GlobalInfoStore implements Partial<GlobalInfo> {
isOpen: false, isOpen: false,
}; };
recordingId = null; recordingId = null;
retrainRobotId = null;
recordings: string[] = []; recordings: string[] = [];
rerenderRuns = false; rerenderRuns = false;
rerenderRobots = false; rerenderRobots = false;
@@ -119,6 +122,7 @@ export const GlobalInfoProvider = ({ children }: { children: JSX.Element }) => {
const [rerenderRobots, setRerenderRobots] = useState<boolean>(globalInfoStore.rerenderRobots); const [rerenderRobots, setRerenderRobots] = useState<boolean>(globalInfoStore.rerenderRobots);
const [recordingLength, setRecordingLength] = useState<number>(globalInfoStore.recordingLength); const [recordingLength, setRecordingLength] = useState<number>(globalInfoStore.recordingLength);
const [recordingId, setRecordingId] = useState<string | null>(globalInfoStore.recordingId); const [recordingId, setRecordingId] = useState<string | null>(globalInfoStore.recordingId);
const [retrainRobotId, setRetrainRobotId] = useState<string | null>(globalInfoStore.retrainRobotId);
const [recordingName, setRecordingName] = useState<string>(globalInfoStore.recordingName); const [recordingName, setRecordingName] = useState<string>(globalInfoStore.recordingName);
const [isLogin, setIsLogin] = useState<boolean>(globalInfoStore.isLogin); const [isLogin, setIsLogin] = useState<boolean>(globalInfoStore.isLogin);
const [initialUrl, setInitialUrl] = useState<string>(globalInfoStore.initialUrl); const [initialUrl, setInitialUrl] = useState<string>(globalInfoStore.initialUrl);
@@ -169,6 +173,8 @@ export const GlobalInfoProvider = ({ children }: { children: JSX.Element }) => {
setRecordingLength, setRecordingLength,
recordingId, recordingId,
setRecordingId, setRecordingId,
retrainRobotId,
setRetrainRobotId,
recordingName, recordingName,
setRecordingName, setRecordingName,
initialUrl, initialUrl,

View File

@@ -43,7 +43,7 @@ export const RecordingPage = ({ recordingName }: RecordingPageProps) => {
const { setId, socket } = useSocketStore(); const { setId, socket } = useSocketStore();
const { setWidth } = useBrowserDimensionsStore(); const { setWidth } = useBrowserDimensionsStore();
const { browserId, setBrowserId, recordingId, recordingUrl, setRecordingUrl } = useGlobalInfoStore(); const { browserId, setBrowserId, recordingId, recordingUrl, setRecordingUrl, setRecordingName, setRetrainRobotId } = useGlobalInfoStore();
const handleShowOutputData = useCallback(() => { const handleShowOutputData = useCallback(() => {
setShowOutputData(true); setShowOutputData(true);
@@ -80,6 +80,19 @@ export const RecordingPage = ({ recordingName }: RecordingPageProps) => {
const storedUrl = window.sessionStorage.getItem('recordingUrl'); const storedUrl = window.sessionStorage.getItem('recordingUrl');
if (storedUrl && !recordingUrl) { if (storedUrl && !recordingUrl) {
setRecordingUrl(storedUrl); setRecordingUrl(storedUrl);
window.sessionStorage.removeItem('recordingUrl');
}
const robotName = window.sessionStorage.getItem('robotName');
if (robotName) {
setRecordingName(robotName);
window.sessionStorage.removeItem('robotName');
}
const recordingId = window.sessionStorage.getItem('robotToRetrain');
if (recordingId) {
setRetrainRobotId(recordingId);
window.sessionStorage.removeItem('robotToRetrain');
} }
const id = await getActiveBrowserId(); const id = await getActiveBrowserId();
@@ -101,7 +114,7 @@ export const RecordingPage = ({ recordingName }: RecordingPageProps) => {
return () => { return () => {
isCancelled = true; isCancelled = true;
} }
}, [setId, recordingUrl, setRecordingUrl]); }, [setId, recordingUrl, setRecordingUrl, setRecordingName, setRetrainRobotId]);
const changeBrowserDimensions = useCallback(() => { const changeBrowserDimensions = useCallback(() => {
if (browserContentRef.current) { if (browserContentRef.current) {
@@ -126,7 +139,7 @@ export const RecordingPage = ({ recordingName }: RecordingPageProps) => {
} }
setIsLoaded(true); setIsLoaded(true);
} }
}, [socket, browserId, recordingName, recordingId, isLoaded]) }, [socket, browserId, recordingName, recordingId, isLoaded]);
useEffect(() => { useEffect(() => {
socket?.on('loaded', handleLoaded); socket?.on('loaded', handleLoaded);