Merge pull request #427 from getmaxun/rm-reload
feat: prevent hard reload on robot edit and duplication
This commit is contained in:
@@ -168,6 +168,8 @@ export const RecordingsTable = ({
|
|||||||
setRecordingUrl,
|
setRecordingUrl,
|
||||||
isLogin,
|
isLogin,
|
||||||
setIsLogin,
|
setIsLogin,
|
||||||
|
rerenderRobots,
|
||||||
|
setRerenderRobots,
|
||||||
recordingName,
|
recordingName,
|
||||||
setRecordingName,
|
setRecordingName,
|
||||||
recordingId,
|
recordingId,
|
||||||
@@ -261,6 +263,14 @@ export const RecordingsTable = ({
|
|||||||
}
|
}
|
||||||
}, [fetchRecordings]);
|
}, [fetchRecordings]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (rerenderRobots) {
|
||||||
|
fetchRecordings().then(() => {
|
||||||
|
setRerenderRobots(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [rerenderRobots, fetchRecordings, setRerenderRobots]);
|
||||||
|
|
||||||
function useDebounce<T>(value: T, delay: number): T {
|
function useDebounce<T>(value: T, delay: number): T {
|
||||||
const [debouncedValue, setDebouncedValue] = React.useState<T>(value);
|
const [debouncedValue, setDebouncedValue] = React.useState<T>(value);
|
||||||
|
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ interface RobotSettingsProps {
|
|||||||
|
|
||||||
export const RobotDuplicationModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => {
|
export const RobotDuplicationModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [robot, setRobot] = useState<RobotSettings | null>(null);
|
|
||||||
const [targetUrl, setTargetUrl] = useState<string | undefined>('');
|
const [targetUrl, setTargetUrl] = useState<string | undefined>('');
|
||||||
const { recordingId, notify } = useGlobalInfoStore();
|
const [robot, setRobot] = useState<RobotSettings | null>(null);
|
||||||
|
const { recordingId, notify, setRerenderRobots } = useGlobalInfoStore();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
@@ -96,13 +96,11 @@ export const RobotDuplicationModal = ({ isOpen, handleStart, handleClose, initia
|
|||||||
const success = await duplicateRecording(robot.recording_meta.id, targetUrl);
|
const success = await duplicateRecording(robot.recording_meta.id, targetUrl);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
setRerenderRobots(true);
|
||||||
|
|
||||||
notify('success', t('robot_duplication.notifications.duplicate_success'));
|
notify('success', t('robot_duplication.notifications.duplicate_success'));
|
||||||
handleStart(robot);
|
handleStart(robot);
|
||||||
handleClose();
|
handleClose();
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
window.location.reload();
|
|
||||||
}, 1000);
|
|
||||||
} else {
|
} else {
|
||||||
notify('error', t('robot_duplication.notifications.duplicate_error'));
|
notify('error', t('robot_duplication.notifications.duplicate_error'));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { modalStyle } from "../recorder/AddWhereCondModal";
|
|||||||
import { useGlobalInfoStore } from '../../context/globalInfo';
|
import { useGlobalInfoStore } from '../../context/globalInfo';
|
||||||
import { getStoredRecording, updateRecording } from '../../api/storage';
|
import { getStoredRecording, updateRecording } from '../../api/storage';
|
||||||
import { WhereWhatPair } from 'maxun-core';
|
import { WhereWhatPair } from 'maxun-core';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
interface RobotMeta {
|
interface RobotMeta {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -75,9 +76,9 @@ interface GroupedCredentials {
|
|||||||
|
|
||||||
export const RobotEditModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => {
|
export const RobotEditModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [robot, setRobot] = useState<RobotSettings | null>(null);
|
|
||||||
const [credentials, setCredentials] = useState<Credentials>({});
|
const [credentials, setCredentials] = useState<Credentials>({});
|
||||||
const { recordingId, notify } = useGlobalInfoStore();
|
const { recordingId, notify, setRerenderRobots } = useGlobalInfoStore();
|
||||||
|
const [robot, setRobot] = useState<RobotSettings | null>(null);
|
||||||
const [credentialGroups, setCredentialGroups] = useState<GroupedCredentials>({
|
const [credentialGroups, setCredentialGroups] = useState<GroupedCredentials>({
|
||||||
passwords: [],
|
passwords: [],
|
||||||
emails: [],
|
emails: [],
|
||||||
@@ -366,13 +367,11 @@ export const RobotEditModal = ({ isOpen, handleStart, handleClose, initialSettin
|
|||||||
const success = await updateRecording(robot.recording_meta.id, payload);
|
const success = await updateRecording(robot.recording_meta.id, payload);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
setRerenderRobots(true);
|
||||||
|
|
||||||
notify('success', t('robot_edit.notifications.update_success'));
|
notify('success', t('robot_edit.notifications.update_success'));
|
||||||
handleStart(robot);
|
handleStart(robot);
|
||||||
handleClose();
|
handleClose();
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
window.location.reload();
|
|
||||||
}, 1000);
|
|
||||||
} else {
|
} else {
|
||||||
notify('error', t('robot_edit.notifications.update_failed'));
|
notify('error', t('robot_edit.notifications.update_failed'));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,8 +54,8 @@ interface RobotSettingsProps {
|
|||||||
|
|
||||||
export const RobotSettingsModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => {
|
export const RobotSettingsModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [robot, setRobot] = useState<RobotSettings | null>(null);
|
|
||||||
const [userEmail, setUserEmail] = useState<string | null>(null);
|
const [userEmail, setUserEmail] = useState<string | null>(null);
|
||||||
|
const [robot, setRobot] = useState<RobotSettings | null>(null);
|
||||||
const { recordingId, notify } = useGlobalInfoStore();
|
const { recordingId, notify } = useGlobalInfoStore();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -1,6 +1,44 @@
|
|||||||
import React, { createContext, useContext, useState } from "react";
|
import React, { createContext, useContext, useState } from "react";
|
||||||
import { AlertSnackbarProps } from "../components/ui/AlertSnackbar";
|
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 {
|
interface GlobalInfo {
|
||||||
browserId: string | null;
|
browserId: string | null;
|
||||||
@@ -16,6 +54,8 @@ interface GlobalInfo {
|
|||||||
setRecordings: (recordings: string[]) => void;
|
setRecordings: (recordings: string[]) => void;
|
||||||
rerenderRuns: boolean;
|
rerenderRuns: boolean;
|
||||||
setRerenderRuns: (rerenderRuns: boolean) => void;
|
setRerenderRuns: (rerenderRuns: boolean) => void;
|
||||||
|
rerenderRobots: boolean;
|
||||||
|
setRerenderRobots: (rerenderRuns: boolean) => void;
|
||||||
recordingLength: number;
|
recordingLength: number;
|
||||||
setRecordingLength: (recordingLength: number) => void;
|
setRecordingLength: (recordingLength: number) => void;
|
||||||
recordingId: string | null;
|
recordingId: string | null;
|
||||||
@@ -52,6 +92,7 @@ class GlobalInfoStore implements Partial<GlobalInfo> {
|
|||||||
recordingId = null;
|
recordingId = null;
|
||||||
recordings: string[] = [];
|
recordings: string[] = [];
|
||||||
rerenderRuns = false;
|
rerenderRuns = false;
|
||||||
|
rerenderRobots = false;
|
||||||
recordingName = '';
|
recordingName = '';
|
||||||
initialUrl = 'https://';
|
initialUrl = 'https://';
|
||||||
recordingUrl = 'https://';
|
recordingUrl = 'https://';
|
||||||
@@ -75,6 +116,7 @@ export const GlobalInfoProvider = ({ children }: { children: JSX.Element }) => {
|
|||||||
const [notification, setNotification] = useState<AlertSnackbarProps>(globalInfoStore.notification);
|
const [notification, setNotification] = useState<AlertSnackbarProps>(globalInfoStore.notification);
|
||||||
const [recordings, setRecordings] = useState<string[]>(globalInfoStore.recordings);
|
const [recordings, setRecordings] = useState<string[]>(globalInfoStore.recordings);
|
||||||
const [rerenderRuns, setRerenderRuns] = useState<boolean>(globalInfoStore.rerenderRuns);
|
const [rerenderRuns, setRerenderRuns] = useState<boolean>(globalInfoStore.rerenderRuns);
|
||||||
|
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 [recordingName, setRecordingName] = useState<string>(globalInfoStore.recordingName);
|
const [recordingName, setRecordingName] = useState<string>(globalInfoStore.recordingName);
|
||||||
@@ -121,6 +163,8 @@ export const GlobalInfoProvider = ({ children }: { children: JSX.Element }) => {
|
|||||||
setRecordings,
|
setRecordings,
|
||||||
rerenderRuns,
|
rerenderRuns,
|
||||||
setRerenderRuns,
|
setRerenderRuns,
|
||||||
|
rerenderRobots,
|
||||||
|
setRerenderRobots,
|
||||||
recordingLength,
|
recordingLength,
|
||||||
setRecordingLength,
|
setRecordingLength,
|
||||||
recordingId,
|
recordingId,
|
||||||
|
|||||||
Reference in New Issue
Block a user