Merge pull request #59 from amhsirak/develop
feat: handle one custom action per robot
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
import React, { useState, useCallback } from 'react';
|
import React, { useState, useCallback, useEffect } from 'react';
|
||||||
import { Button, Paper, Box, TextField } from "@mui/material";
|
import { Button, Paper, Box, TextField } from "@mui/material";
|
||||||
import EditIcon from '@mui/icons-material/Edit';
|
import EditIcon from '@mui/icons-material/Edit';
|
||||||
import TextFieldsIcon from '@mui/icons-material/TextFields';
|
import TextFieldsIcon from '@mui/icons-material/TextFields';
|
||||||
import DocumentScannerIcon from '@mui/icons-material/DocumentScanner';
|
import DocumentScannerIcon from '@mui/icons-material/DocumentScanner';
|
||||||
import { SimpleBox } from "../atoms/Box";
|
import { SimpleBox } from "../atoms/Box";
|
||||||
|
import { WorkflowFile } from "maxun-core";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
import { useGlobalInfoStore } from "../../context/globalInfo";
|
import { useGlobalInfoStore } from "../../context/globalInfo";
|
||||||
import { PaginationType, useActionContext, LimitType } from '../../context/browserActions';
|
import { PaginationType, useActionContext, LimitType } from '../../context/browserActions';
|
||||||
@@ -17,6 +18,20 @@ import FormControl from '@mui/material/FormControl';
|
|||||||
import FormLabel from '@mui/material/FormLabel';
|
import FormLabel from '@mui/material/FormLabel';
|
||||||
import Radio from '@mui/material/Radio';
|
import Radio from '@mui/material/Radio';
|
||||||
import RadioGroup from '@mui/material/RadioGroup';
|
import RadioGroup from '@mui/material/RadioGroup';
|
||||||
|
import { emptyWorkflow } from "../../shared/constants";
|
||||||
|
import { getActiveWorkflow } from "../../api/workflow";
|
||||||
|
|
||||||
|
const fetchWorkflow = (id: string, callback: (response: WorkflowFile) => void) => {
|
||||||
|
getActiveWorkflow(id).then(
|
||||||
|
(response) => {
|
||||||
|
if (response) {
|
||||||
|
callback(response);
|
||||||
|
} else {
|
||||||
|
throw new Error("No workflow found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).catch((error) => { console.log(error.message) })
|
||||||
|
};
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// 1. Add description for each browser step
|
// 1. Add description for each browser step
|
||||||
@@ -26,18 +41,74 @@ interface RightSidePanelProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture }) => {
|
export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture }) => {
|
||||||
|
const [workflow, setWorkflow] = useState<WorkflowFile>(emptyWorkflow);
|
||||||
const [textLabels, setTextLabels] = useState<{ [id: string]: string }>({});
|
const [textLabels, setTextLabels] = useState<{ [id: string]: string }>({});
|
||||||
const [errors, setErrors] = useState<{ [id: string]: string }>({});
|
const [errors, setErrors] = useState<{ [id: string]: string }>({});
|
||||||
const [confirmedTextSteps, setConfirmedTextSteps] = useState<{ [id: string]: boolean }>({});
|
const [confirmedTextSteps, setConfirmedTextSteps] = useState<{ [id: string]: boolean }>({});
|
||||||
const [confirmedListTextFields, setConfirmedListTextFields] = useState<{ [listId: string]: { [fieldKey: string]: boolean } }>({});
|
const [confirmedListTextFields, setConfirmedListTextFields] = useState<{ [listId: string]: { [fieldKey: string]: boolean } }>({});
|
||||||
const [showPaginationOptions, setShowPaginationOptions] = useState(false);
|
const [showPaginationOptions, setShowPaginationOptions] = useState(false);
|
||||||
const [showLimitOptions, setShowLimitOptions] = useState(false);
|
const [showLimitOptions, setShowLimitOptions] = useState(false);
|
||||||
|
const [showCaptureList, setShowCaptureList] = useState(true);
|
||||||
|
const [showCaptureScreenshot, setShowCaptureScreenshot] = useState(true);
|
||||||
|
const [showCaptureText, setShowCaptureText] = useState(true);
|
||||||
const [captureStage, setCaptureStage] = useState<'initial' | 'pagination' | 'limit' | 'complete'>('initial');
|
const [captureStage, setCaptureStage] = useState<'initial' | 'pagination' | 'limit' | 'complete'>('initial');
|
||||||
|
|
||||||
const { lastAction, notify } = useGlobalInfoStore();
|
const { lastAction, notify } = useGlobalInfoStore();
|
||||||
const { getText, startGetText, stopGetText, getScreenshot, startGetScreenshot, stopGetScreenshot, getList, startGetList, stopGetList, startPaginationMode, stopPaginationMode, paginationType, updatePaginationType, limitType, customLimit, updateLimitType, updateCustomLimit, stopLimitMode, startLimitMode } = useActionContext();
|
const { getText, startGetText, stopGetText, getScreenshot, startGetScreenshot, stopGetScreenshot, getList, startGetList, stopGetList, startPaginationMode, stopPaginationMode, paginationType, updatePaginationType, limitType, customLimit, updateLimitType, updateCustomLimit, stopLimitMode, startLimitMode } = useActionContext();
|
||||||
const { browserSteps, updateBrowserTextStepLabel, deleteBrowserStep, addScreenshotStep, updateListTextFieldLabel, removeListTextField } = useBrowserSteps();
|
const { browserSteps, updateBrowserTextStepLabel, deleteBrowserStep, addScreenshotStep, updateListTextFieldLabel, removeListTextField } = useBrowserSteps();
|
||||||
const { socket } = useSocketStore();
|
const { id, socket } = useSocketStore();
|
||||||
|
|
||||||
|
const workflowHandler = useCallback((data: WorkflowFile) => {
|
||||||
|
setWorkflow(data);
|
||||||
|
//setRecordingLength(data.workflow.length);
|
||||||
|
}, [workflow])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (socket) {
|
||||||
|
socket.on("workflow", workflowHandler);
|
||||||
|
}
|
||||||
|
// fetch the workflow every time the id changes
|
||||||
|
if (id) {
|
||||||
|
fetchWorkflow(id, workflowHandler);
|
||||||
|
}
|
||||||
|
// fetch workflow in 15min intervals
|
||||||
|
let interval = setInterval(() => {
|
||||||
|
if (id) {
|
||||||
|
fetchWorkflow(id, workflowHandler);
|
||||||
|
}
|
||||||
|
}, (1000 * 60 * 15));
|
||||||
|
return () => {
|
||||||
|
socket?.off("workflow", workflowHandler);
|
||||||
|
clearInterval(interval);
|
||||||
|
};
|
||||||
|
}, [id, socket, workflowHandler]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const hasPairs = workflow.workflow.length > 0;
|
||||||
|
|
||||||
|
if (!hasPairs) {
|
||||||
|
setShowCaptureList(true);
|
||||||
|
setShowCaptureScreenshot(true);
|
||||||
|
setShowCaptureText(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasScrapeListAction = workflow.workflow.some(pair =>
|
||||||
|
pair.what.some(action => action.action === "scrapeList")
|
||||||
|
);
|
||||||
|
|
||||||
|
const hasScreenshotAction = workflow.workflow.some(pair =>
|
||||||
|
pair.what.some(action => action.action === "screenshot")
|
||||||
|
);
|
||||||
|
|
||||||
|
const hasScrapeSchemaAction = workflow.workflow.some(pair =>
|
||||||
|
pair.what.some(action => action.action === "scrapeSchema")
|
||||||
|
);
|
||||||
|
|
||||||
|
setShowCaptureList(!(hasScrapeListAction || hasScrapeSchemaAction || hasScreenshotAction));
|
||||||
|
setShowCaptureScreenshot(!(hasScrapeListAction || hasScrapeSchemaAction || hasScreenshotAction));
|
||||||
|
setShowCaptureText(!(hasScrapeListAction || hasScreenshotAction));
|
||||||
|
}, [workflow]);
|
||||||
|
|
||||||
const handleTextLabelChange = (id: number, label: string, listId?: number, fieldKey?: string) => {
|
const handleTextLabelChange = (id: number, label: string, listId?: number, fieldKey?: string) => {
|
||||||
if (listId !== undefined && fieldKey !== undefined) {
|
if (listId !== undefined && fieldKey !== undefined) {
|
||||||
@@ -291,7 +362,7 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
</SimpleBox>
|
</SimpleBox>
|
||||||
<SidePanelHeader />
|
<SidePanelHeader />
|
||||||
<Box display="flex" flexDirection="column" gap={2} style={{ margin: '15px' }}>
|
<Box display="flex" flexDirection="column" gap={2} style={{ margin: '15px' }}>
|
||||||
{!getText && !getScreenshot && !getList && <Button variant="contained" onClick={startGetList}>Capture List</Button>}
|
{!getText && !getScreenshot && !getList && showCaptureList && <Button variant="contained" onClick={startGetList}>Capture List</Button>}
|
||||||
{getList && (
|
{getList && (
|
||||||
<>
|
<>
|
||||||
<Box display="flex" justifyContent="space-between" gap={2} style={{ margin: '15px' }}>
|
<Box display="flex" justifyContent="space-between" gap={2} style={{ margin: '15px' }}>
|
||||||
@@ -350,7 +421,7 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
{!getText && !getScreenshot && !getList && <Button variant="contained" onClick={startGetText}>Capture Text</Button>}
|
{!getText && !getScreenshot && !getList && showCaptureText && <Button variant="contained" onClick={startGetText}>Capture Text</Button>}
|
||||||
{getText &&
|
{getText &&
|
||||||
<>
|
<>
|
||||||
<Box display="flex" justifyContent="space-between" gap={2} style={{ margin: '15px' }}>
|
<Box display="flex" justifyContent="space-between" gap={2} style={{ margin: '15px' }}>
|
||||||
@@ -359,7 +430,7 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
{!getText && !getScreenshot && !getList && <Button variant="contained" onClick={startGetScreenshot}>Capture Screenshot</Button>}
|
{!getText && !getScreenshot && !getList && showCaptureScreenshot && <Button variant="contained" onClick={startGetScreenshot}>Capture Screenshot</Button>}
|
||||||
{getScreenshot && (
|
{getScreenshot && (
|
||||||
<Box display="flex" flexDirection="column" gap={2}>
|
<Box display="flex" flexDirection="column" gap={2}>
|
||||||
<Button variant="contained" onClick={() => captureScreenshot(true)}>Capture Fullpage</Button>
|
<Button variant="contained" onClick={() => captureScreenshot(true)}>Capture Fullpage</Button>
|
||||||
|
|||||||
Reference in New Issue
Block a user