From a28c59b82e26b8257480bee54efb27c78fb60f6d Mon Sep 17 00:00:00 2001 From: Rohit Date: Thu, 30 Jan 2025 23:25:13 +0530 Subject: [PATCH 01/13] feat: add global info for robot state --- src/context/globalInfo.tsx | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/context/globalInfo.tsx b/src/context/globalInfo.tsx index 28d65b34..3a9203b1 100644 --- a/src/context/globalInfo.tsx +++ b/src/context/globalInfo.tsx @@ -1,6 +1,44 @@ import React, { createContext, useContext, useState } from "react"; import { AlertSnackbarProps } from "../components/ui/AlertSnackbar"; +import { WhereWhatPair } from "maxun-core"; +interface RobotMeta { + name: string; + id: string; + createdAt: string; + pairs: number; + updatedAt: string; + params: any[]; +} + +interface RobotWorkflow { + workflow: WhereWhatPair[]; +} + +interface ScheduleConfig { + runEvery: number; + runEveryUnit: 'MINUTES' | 'HOURS' | 'DAYS' | 'WEEKS' | 'MONTHS'; + startFrom: 'SUNDAY' | 'MONDAY' | 'TUESDAY' | 'WEDNESDAY' | 'THURSDAY' | 'FRIDAY' | 'SATURDAY'; + atTimeStart?: string; + atTimeEnd?: string; + timezone: string; + lastRunAt?: Date; + nextRunAt?: Date; + cronExpression?: string; +} + +export interface RobotSettings { + id: string; + userId?: number; + recording_meta: RobotMeta; + recording: RobotWorkflow; + google_sheet_email?: string | null; + google_sheet_name?: string | null; + google_sheet_id?: string | null; + google_access_token?: string | null; + google_refresh_token?: string | null; + schedule?: ScheduleConfig | null; +} interface GlobalInfo { browserId: string | null; @@ -12,6 +50,8 @@ interface GlobalInfo { closeNotify: () => void; isLogin: boolean; setIsLogin: (isLogin: boolean) => void; + robot: RobotSettings | null; + setRobot: (robot: RobotSettings | null | ((prev: RobotSettings | null) => RobotSettings | null)) => void; recordings: string[]; setRecordings: (recordings: string[]) => void; rerenderRuns: boolean; @@ -50,6 +90,7 @@ class GlobalInfoStore implements Partial { isOpen: false, }; recordingId = null; + robot = null; recordings: string[] = []; rerenderRuns = false; recordingName = ''; @@ -83,6 +124,7 @@ export const GlobalInfoProvider = ({ children }: { children: JSX.Element }) => { const [recordingUrl, setRecordingUrl] = useState(globalInfoStore.recordingUrl); const [currentWorkflowActionsState, setCurrentWorkflowActionsState] = useState(globalInfoStore.currentWorkflowActionsState); const [shouldResetInterpretationLog, setShouldResetInterpretationLog] = useState(globalInfoStore.shouldResetInterpretationLog); + const [robot, setRobot] = useState(null); const notify = (severity: 'error' | 'warning' | 'info' | 'success', message: string) => { setNotification({ severity, message, isOpen: true }); @@ -117,6 +159,8 @@ export const GlobalInfoProvider = ({ children }: { children: JSX.Element }) => { notification, notify, closeNotify, + robot, + setRobot, recordings, setRecordings, rerenderRuns, From 61ae28ef4dde0c2e0fe2d7a9f0ab872e50ec6704 Mon Sep 17 00:00:00 2001 From: Rohit Date: Thu, 30 Jan 2025 23:26:26 +0530 Subject: [PATCH 02/13] feat: globally set robot state --- src/components/robot/RobotSettings.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/robot/RobotSettings.tsx b/src/components/robot/RobotSettings.tsx index fdbf90e2..59b959b8 100644 --- a/src/components/robot/RobotSettings.tsx +++ b/src/components/robot/RobotSettings.tsx @@ -54,9 +54,8 @@ interface RobotSettingsProps { export const RobotSettingsModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => { const { t } = useTranslation(); - const [robot, setRobot] = useState(null); const [userEmail, setUserEmail] = useState(null); - const { recordingId, notify } = useGlobalInfoStore(); + const { recordingId, notify, robot, setRobot } = useGlobalInfoStore(); useEffect(() => { if (isOpen) { From 4926f7c5d981c9ab38e1eccd9ee4057ab17bbaa6 Mon Sep 17 00:00:00 2001 From: Rohit Date: Thu, 30 Jan 2025 23:26:56 +0530 Subject: [PATCH 03/13] feat: globally set robot state --- src/components/robot/RobotEdit.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/robot/RobotEdit.tsx b/src/components/robot/RobotEdit.tsx index f1f79b77..05c4b847 100644 --- a/src/components/robot/RobotEdit.tsx +++ b/src/components/robot/RobotEdit.tsx @@ -7,6 +7,7 @@ import { modalStyle } from "../recorder/AddWhereCondModal"; import { useGlobalInfoStore } from '../../context/globalInfo'; import { getStoredRecording, updateRecording } from '../../api/storage'; import { WhereWhatPair } from 'maxun-core'; +import { useNavigate } from 'react-router-dom'; interface RobotMeta { name: string; @@ -75,9 +76,8 @@ interface GroupedCredentials { export const RobotEditModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => { const { t } = useTranslation(); - const [robot, setRobot] = useState(null); const [credentials, setCredentials] = useState({}); - const { recordingId, notify } = useGlobalInfoStore(); + const { recordingId, notify, robot, setRobot } = useGlobalInfoStore(); const [credentialGroups, setCredentialGroups] = useState({ passwords: [], emails: [], @@ -85,6 +85,7 @@ export const RobotEditModal = ({ isOpen, handleStart, handleClose, initialSettin others: [] }); const [showPasswords, setShowPasswords] = useState({}); + const navigate = useNavigate(); const isEmailPattern = (value: string): boolean => { return value.includes('@'); @@ -370,9 +371,7 @@ export const RobotEditModal = ({ isOpen, handleStart, handleClose, initialSettin handleStart(robot); handleClose(); - setTimeout(() => { - window.location.reload(); - }, 1000); + navigate('/robots'); } else { notify('error', t('robot_edit.notifications.update_failed')); } From 0b1966a9e0d8c1785e21c6f2dbaa526f924bfcb5 Mon Sep 17 00:00:00 2001 From: Rohit Date: Thu, 30 Jan 2025 23:27:16 +0530 Subject: [PATCH 04/13] feat: globally set robot state --- src/components/robot/RobotDuplicate.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/components/robot/RobotDuplicate.tsx b/src/components/robot/RobotDuplicate.tsx index efde9b2a..4e0ef887 100644 --- a/src/components/robot/RobotDuplicate.tsx +++ b/src/components/robot/RobotDuplicate.tsx @@ -55,9 +55,8 @@ interface RobotSettingsProps { export const RobotDuplicationModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => { const { t } = useTranslation(); - const [robot, setRobot] = useState(null); const [targetUrl, setTargetUrl] = useState(''); - const { recordingId, notify } = useGlobalInfoStore(); + const { recordingId, notify, robot, setRobot } = useGlobalInfoStore(); useEffect(() => { if (isOpen) { @@ -99,10 +98,6 @@ export const RobotDuplicationModal = ({ isOpen, handleStart, handleClose, initia notify('success', t('robot_duplication.notifications.duplicate_success')); handleStart(robot); handleClose(); - - setTimeout(() => { - window.location.reload(); - }, 1000); } else { notify('error', t('robot_duplication.notifications.duplicate_error')); } From 03ec2a53940499b0630ce8ba19cba98356471e70 Mon Sep 17 00:00:00 2001 From: Rohit Date: Sat, 1 Feb 2025 11:11:05 +0530 Subject: [PATCH 05/13] feat: update based on recording state --- src/components/robot/RecordingsTable.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/robot/RecordingsTable.tsx b/src/components/robot/RecordingsTable.tsx index 8b4143a2..3d76b03f 100644 --- a/src/components/robot/RecordingsTable.tsx +++ b/src/components/robot/RecordingsTable.tsx @@ -161,6 +161,8 @@ export const RecordingsTable = ({ const { notify, + robot, + recordings, setRecordings, browserId, setBrowserId, @@ -260,10 +262,10 @@ export const RecordingsTable = ({ } useEffect(() => { - if (rows.length === 0) { + if (recordings.length >= 0) { fetchRecordings(); } - }, [fetchRecordings]); + }, [recordings, fetchRecordings]); function useDebounce(value: T, delay: number): T { const [debouncedValue, setDebouncedValue] = React.useState(value); From 8a1c0db89d4c8acb8569ddb4a56f44e609121eb5 Mon Sep 17 00:00:00 2001 From: Rohit Date: Sat, 1 Feb 2025 11:30:35 +0530 Subject: [PATCH 06/13] feat: set rerender true on edit --- src/components/robot/RobotEdit.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/robot/RobotEdit.tsx b/src/components/robot/RobotEdit.tsx index 05c4b847..89b6e701 100644 --- a/src/components/robot/RobotEdit.tsx +++ b/src/components/robot/RobotEdit.tsx @@ -77,7 +77,7 @@ interface GroupedCredentials { export const RobotEditModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => { const { t } = useTranslation(); const [credentials, setCredentials] = useState({}); - const { recordingId, notify, robot, setRobot } = useGlobalInfoStore(); + const { recordingId, notify, robot, setRobot, setRerenderRobots } = useGlobalInfoStore(); const [credentialGroups, setCredentialGroups] = useState({ passwords: [], emails: [], @@ -85,7 +85,6 @@ export const RobotEditModal = ({ isOpen, handleStart, handleClose, initialSettin others: [] }); const [showPasswords, setShowPasswords] = useState({}); - const navigate = useNavigate(); const isEmailPattern = (value: string): boolean => { return value.includes('@'); @@ -367,11 +366,11 @@ export const RobotEditModal = ({ isOpen, handleStart, handleClose, initialSettin const success = await updateRecording(robot.recording_meta.id, payload); if (success) { + setRerenderRobots(true); + notify('success', t('robot_edit.notifications.update_success')); handleStart(robot); handleClose(); - - navigate('/robots'); } else { notify('error', t('robot_edit.notifications.update_failed')); } From fa36e5282fa584dc5f640d29525d0c88cf70edf7 Mon Sep 17 00:00:00 2001 From: Rohit Date: Sat, 1 Feb 2025 11:32:14 +0530 Subject: [PATCH 07/13] feat: rm set robot global state --- src/components/robot/RobotEdit.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/robot/RobotEdit.tsx b/src/components/robot/RobotEdit.tsx index 89b6e701..25edaa3f 100644 --- a/src/components/robot/RobotEdit.tsx +++ b/src/components/robot/RobotEdit.tsx @@ -77,7 +77,8 @@ interface GroupedCredentials { export const RobotEditModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => { const { t } = useTranslation(); const [credentials, setCredentials] = useState({}); - const { recordingId, notify, robot, setRobot, setRerenderRobots } = useGlobalInfoStore(); + const { recordingId, notify, setRerenderRobots } = useGlobalInfoStore(); + const [robot, setRobot] = useState(null); const [credentialGroups, setCredentialGroups] = useState({ passwords: [], emails: [], From 1f0c5885c1e15e1271bd968358560abcb8bf32f5 Mon Sep 17 00:00:00 2001 From: Rohit Date: Sat, 1 Feb 2025 11:32:57 +0530 Subject: [PATCH 08/13] feat: rm set robot global state --- src/components/robot/RobotSettings.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/robot/RobotSettings.tsx b/src/components/robot/RobotSettings.tsx index 59b959b8..6ae59f89 100644 --- a/src/components/robot/RobotSettings.tsx +++ b/src/components/robot/RobotSettings.tsx @@ -55,7 +55,8 @@ interface RobotSettingsProps { export const RobotSettingsModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => { const { t } = useTranslation(); const [userEmail, setUserEmail] = useState(null); - const { recordingId, notify, robot, setRobot } = useGlobalInfoStore(); + const [robot, setRobot] = useState(null); + const { recordingId, notify } = useGlobalInfoStore(); useEffect(() => { if (isOpen) { From f54f8a2323ea9c8f3a47ced1a79aa79e08498bb3 Mon Sep 17 00:00:00 2001 From: Rohit Date: Sat, 1 Feb 2025 11:34:29 +0530 Subject: [PATCH 09/13] feat: rerender robots on robot update --- src/components/robot/RecordingsTable.tsx | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/components/robot/RecordingsTable.tsx b/src/components/robot/RecordingsTable.tsx index 3d76b03f..f5f96125 100644 --- a/src/components/robot/RecordingsTable.tsx +++ b/src/components/robot/RecordingsTable.tsx @@ -161,8 +161,6 @@ export const RecordingsTable = ({ const { notify, - robot, - recordings, setRecordings, browserId, setBrowserId, @@ -171,6 +169,8 @@ export const RecordingsTable = ({ setRecordingUrl, isLogin, setIsLogin, + rerenderRobots, + setRerenderRobots, recordingName, setRecordingName, recordingId, @@ -262,10 +262,18 @@ export const RecordingsTable = ({ } useEffect(() => { - if (recordings.length >= 0) { + if (rows.length === 0) { fetchRecordings(); } - }, [recordings, fetchRecordings]); + }, [fetchRecordings]); + + useEffect(() => { + if (rerenderRobots) { + fetchRecordings().then(() => { + setRerenderRobots(false); + }); + } + }, [rerenderRobots, fetchRecordings, setRerenderRobots]); function useDebounce(value: T, delay: number): T { const [debouncedValue, setDebouncedValue] = React.useState(value); From 8176e68c1484ddabd289424c355df3b69ab08b3d Mon Sep 17 00:00:00 2001 From: Rohit Date: Sat, 1 Feb 2025 11:36:19 +0530 Subject: [PATCH 10/13] feat: set rerender true on duplicate --- src/components/robot/RobotDuplicate.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/robot/RobotDuplicate.tsx b/src/components/robot/RobotDuplicate.tsx index 4e0ef887..2591f95f 100644 --- a/src/components/robot/RobotDuplicate.tsx +++ b/src/components/robot/RobotDuplicate.tsx @@ -56,7 +56,7 @@ interface RobotSettingsProps { export const RobotDuplicationModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => { const { t } = useTranslation(); const [targetUrl, setTargetUrl] = useState(''); - const { recordingId, notify, robot, setRobot } = useGlobalInfoStore(); + const { recordingId, notify, robot, setRobot, setRerenderRobots } = useGlobalInfoStore(); useEffect(() => { if (isOpen) { @@ -95,6 +95,8 @@ export const RobotDuplicationModal = ({ isOpen, handleStart, handleClose, initia const success = await duplicateRecording(robot.recording_meta.id, targetUrl); if (success) { + setRerenderRobots(true); + notify('success', t('robot_duplication.notifications.duplicate_success')); handleStart(robot); handleClose(); From 28a1ab80b8d5da4ce2f93d24f8dd3b2d05b7e8ca Mon Sep 17 00:00:00 2001 From: Rohit Date: Sat, 1 Feb 2025 11:37:00 +0530 Subject: [PATCH 11/13] feat: rm set robot global state --- src/components/robot/RobotDuplicate.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/robot/RobotDuplicate.tsx b/src/components/robot/RobotDuplicate.tsx index 2591f95f..bee1ef5b 100644 --- a/src/components/robot/RobotDuplicate.tsx +++ b/src/components/robot/RobotDuplicate.tsx @@ -56,7 +56,8 @@ interface RobotSettingsProps { export const RobotDuplicationModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => { const { t } = useTranslation(); const [targetUrl, setTargetUrl] = useState(''); - const { recordingId, notify, robot, setRobot, setRerenderRobots } = useGlobalInfoStore(); + const [robot, setRobot] = useState(null); + const { recordingId, notify, setRerenderRobots } = useGlobalInfoStore(); useEffect(() => { if (isOpen) { From 251e22fe9db1c4b0786990406b939f5ace844946 Mon Sep 17 00:00:00 2001 From: Rohit Date: Sat, 1 Feb 2025 11:39:43 +0530 Subject: [PATCH 12/13] feat: add robot rerender state --- src/context/globalInfo.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/context/globalInfo.tsx b/src/context/globalInfo.tsx index 3a9203b1..3fb676aa 100644 --- a/src/context/globalInfo.tsx +++ b/src/context/globalInfo.tsx @@ -56,6 +56,8 @@ interface GlobalInfo { setRecordings: (recordings: string[]) => void; rerenderRuns: boolean; setRerenderRuns: (rerenderRuns: boolean) => void; + rerenderRobots: boolean; + setRerenderRobots: (rerenderRuns: boolean) => void; recordingLength: number; setRecordingLength: (recordingLength: number) => void; recordingId: string | null; @@ -93,6 +95,7 @@ class GlobalInfoStore implements Partial { robot = null; recordings: string[] = []; rerenderRuns = false; + rerenderRobots = false; recordingName = ''; initialUrl = 'https://'; recordingUrl = 'https://'; @@ -116,6 +119,7 @@ export const GlobalInfoProvider = ({ children }: { children: JSX.Element }) => { const [notification, setNotification] = useState(globalInfoStore.notification); const [recordings, setRecordings] = useState(globalInfoStore.recordings); const [rerenderRuns, setRerenderRuns] = useState(globalInfoStore.rerenderRuns); + const [rerenderRobots, setRerenderRobots] = useState(globalInfoStore.rerenderRobots); const [recordingLength, setRecordingLength] = useState(globalInfoStore.recordingLength); const [recordingId, setRecordingId] = useState(globalInfoStore.recordingId); const [recordingName, setRecordingName] = useState(globalInfoStore.recordingName); @@ -165,6 +169,8 @@ export const GlobalInfoProvider = ({ children }: { children: JSX.Element }) => { setRecordings, rerenderRuns, setRerenderRuns, + rerenderRobots, + setRerenderRobots, recordingLength, setRecordingLength, recordingId, From 6ee3a2c0a5ad73def2d83e1ddfc9cd1d462852a8 Mon Sep 17 00:00:00 2001 From: Rohit Date: Sat, 1 Feb 2025 11:40:47 +0530 Subject: [PATCH 13/13] feat: rm set robot global state --- src/context/globalInfo.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/context/globalInfo.tsx b/src/context/globalInfo.tsx index 3fb676aa..eaa6ded7 100644 --- a/src/context/globalInfo.tsx +++ b/src/context/globalInfo.tsx @@ -50,8 +50,6 @@ interface GlobalInfo { closeNotify: () => void; isLogin: boolean; setIsLogin: (isLogin: boolean) => void; - robot: RobotSettings | null; - setRobot: (robot: RobotSettings | null | ((prev: RobotSettings | null) => RobotSettings | null)) => void; recordings: string[]; setRecordings: (recordings: string[]) => void; rerenderRuns: boolean; @@ -92,7 +90,6 @@ class GlobalInfoStore implements Partial { isOpen: false, }; recordingId = null; - robot = null; recordings: string[] = []; rerenderRuns = false; rerenderRobots = false; @@ -128,7 +125,6 @@ export const GlobalInfoProvider = ({ children }: { children: JSX.Element }) => { const [recordingUrl, setRecordingUrl] = useState(globalInfoStore.recordingUrl); const [currentWorkflowActionsState, setCurrentWorkflowActionsState] = useState(globalInfoStore.currentWorkflowActionsState); const [shouldResetInterpretationLog, setShouldResetInterpretationLog] = useState(globalInfoStore.shouldResetInterpretationLog); - const [robot, setRobot] = useState(null); const notify = (severity: 'error' | 'warning' | 'info' | 'success', message: string) => { setNotification({ severity, message, isOpen: true }); @@ -163,8 +159,6 @@ export const GlobalInfoProvider = ({ children }: { children: JSX.Element }) => { notification, notify, closeNotify, - robot, - setRobot, recordings, setRecordings, rerenderRuns,