Skip to content

Commit bbbcb90

Browse files
authored
Merge branch 'develop' into disable-ripple
2 parents 25256e3 + 8ebc134 commit bbbcb90

File tree

11 files changed

+1415
-67
lines changed

11 files changed

+1415
-67
lines changed

legacy/src/RobotDuplicate.tsx

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
import React, { useState, useEffect } from 'react';
2+
import { GenericModal } from "../ui/GenericModal";
3+
import { TextField, Typography, Box, Button } from "@mui/material";
4+
import { modalStyle } from "../recorder/AddWhereCondModal";
5+
import { useGlobalInfoStore } from '../../context/globalInfo';
6+
import { duplicateRecording, getStoredRecording } from '../../api/storage';
7+
import { WhereWhatPair } from 'maxun-core';
8+
import { useTranslation } from 'react-i18next';
9+
10+
interface RobotMeta {
11+
name: string;
12+
id: string;
13+
createdAt: string;
14+
pairs: number;
15+
updatedAt: string;
16+
params: any[];
17+
}
18+
19+
interface RobotWorkflow {
20+
workflow: WhereWhatPair[];
21+
}
22+
23+
interface ScheduleConfig {
24+
runEvery: number;
25+
runEveryUnit: 'MINUTES' | 'HOURS' | 'DAYS' | 'WEEKS' | 'MONTHS';
26+
startFrom: 'SUNDAY' | 'MONDAY' | 'TUESDAY' | 'WEDNESDAY' | 'THURSDAY' | 'FRIDAY' | 'SATURDAY';
27+
atTimeStart?: string;
28+
atTimeEnd?: string;
29+
timezone: string;
30+
lastRunAt?: Date;
31+
nextRunAt?: Date;
32+
cronExpression?: string;
33+
}
34+
35+
export interface RobotSettings {
36+
id: string;
37+
userId?: number;
38+
recording_meta: RobotMeta;
39+
recording: RobotWorkflow;
40+
google_sheet_email?: string | null;
41+
google_sheet_name?: string | null;
42+
google_sheet_id?: string | null;
43+
google_access_token?: string | null;
44+
google_refresh_token?: string | null;
45+
schedule?: ScheduleConfig | null;
46+
}
47+
48+
interface RobotSettingsProps {
49+
isOpen: boolean;
50+
handleStart: (settings: RobotSettings) => void;
51+
handleClose: () => void;
52+
initialSettings?: RobotSettings | null;
53+
54+
}
55+
56+
export const RobotDuplicationModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => {
57+
const { t } = useTranslation();
58+
const [targetUrl, setTargetUrl] = useState<string | undefined>('');
59+
const [robot, setRobot] = useState<RobotSettings | null>(null);
60+
const { recordingId, notify, setRerenderRobots } = useGlobalInfoStore();
61+
62+
useEffect(() => {
63+
if (isOpen) {
64+
getRobot();
65+
}
66+
}, [isOpen]);
67+
68+
useEffect(() => {
69+
if (robot) {
70+
const lastPair = robot?.recording.workflow[robot?.recording.workflow.length - 1];
71+
const url = lastPair?.what.find(action => action.action === "goto")?.args?.[0];
72+
setTargetUrl(url);
73+
}
74+
}, [robot]);
75+
76+
const getRobot = async () => {
77+
if (recordingId) {
78+
const robot = await getStoredRecording(recordingId);
79+
setRobot(robot);
80+
} else {
81+
notify('error', t('robot_duplication.notifications.robot_not_found'));
82+
}
83+
}
84+
85+
const handleTargetUrlChange = (e: React.ChangeEvent<HTMLInputElement>) => {
86+
setTargetUrl(e.target.value);
87+
};
88+
89+
const handleSave = async () => {
90+
if (!robot || !targetUrl) {
91+
notify('error', t('robot_duplication.notifications.url_required'));
92+
return;
93+
}
94+
95+
try {
96+
const success = await duplicateRecording(robot.recording_meta.id, targetUrl);
97+
98+
if (success) {
99+
setRerenderRobots(true);
100+
101+
notify('success', t('robot_duplication.notifications.duplicate_success'));
102+
handleStart(robot);
103+
handleClose();
104+
} else {
105+
notify('error', t('robot_duplication.notifications.duplicate_error'));
106+
}
107+
} catch (error) {
108+
notify('error', t('robot_duplication.notifications.unknown_error'));
109+
console.error('Error updating Target URL:', error);
110+
}
111+
};
112+
113+
return (
114+
<GenericModal
115+
isOpen={isOpen}
116+
onClose={handleClose}
117+
modalStyle={modalStyle}
118+
>
119+
<>
120+
<Typography variant="h5" style={{ marginBottom: '20px' }}>
121+
{t('robot_duplication.title')}
122+
</Typography>
123+
<Box style={{ display: 'flex', flexDirection: 'column' }}>
124+
{
125+
robot && (
126+
<>
127+
<span>
128+
{t('robot_duplication.descriptions.purpose')}
129+
</span>
130+
<br />
131+
<span dangerouslySetInnerHTML={{
132+
__html: t('robot_duplication.descriptions.example', {
133+
url1: '<code>producthunt.com/topics/api</code>',
134+
url2: '<code>producthunt.com/topics/database</code>'
135+
})
136+
}} />
137+
<br />
138+
<span>
139+
<b>{t('robot_duplication.descriptions.warning')}</b>
140+
</span>
141+
<TextField
142+
label={t('robot_duplication.fields.target_url')}
143+
key={t('robot_duplication.fields.target_url')}
144+
value={targetUrl}
145+
onChange={handleTargetUrlChange}
146+
style={{ marginBottom: '20px', marginTop: '30px' }}
147+
/>
148+
<Box mt={2} display="flex" justifyContent="flex-end">
149+
<Button variant="contained" color="primary" onClick={handleSave}>
150+
{t('robot_duplication.buttons.duplicate')}
151+
</Button>
152+
<Button
153+
onClick={handleClose}
154+
color="primary"
155+
variant="outlined"
156+
style={{ marginLeft: '10px' }}
157+
sx={{
158+
color: '#ff00c3 !important',
159+
borderColor: '#ff00c3 !important',
160+
backgroundColor: 'whitesmoke !important',
161+
}} >
162+
{t('robot_duplication.buttons.cancel')}
163+
</Button>
164+
</Box>
165+
</>
166+
)
167+
}
168+
</Box>
169+
</>
170+
</GenericModal>
171+
);
172+
};

0 commit comments

Comments
 (0)