diff --git a/src/components/recorder/RightSidePanel.tsx b/src/components/recorder/RightSidePanel.tsx index 6027e26d..54bcc506 100644 --- a/src/components/recorder/RightSidePanel.tsx +++ b/src/components/recorder/RightSidePanel.tsx @@ -34,9 +34,6 @@ const fetchWorkflow = (id: string, callback: (response: WorkflowFile) => void) = ).catch((error) => { console.log(error.message) }) }; -// TODO: -// 1. Add description for each browser step -// 2. Handle non custom action steps interface RightSidePanelProps { onFinishCapture: () => void; } @@ -46,8 +43,6 @@ export const RightSidePanel: React.FC = ({ onFinishCapture const [errors, setErrors] = useState<{ [id: string]: string }>({}); const [confirmedTextSteps, setConfirmedTextSteps] = useState<{ [id: string]: boolean }>({}); const [confirmedListTextFields, setConfirmedListTextFields] = useState<{ [listId: string]: { [fieldKey: string]: boolean } }>({}); - // const [showPaginationOptions, setShowPaginationOptions] = useState(false); - // const [showLimitOptions, setShowLimitOptions] = useState(false); const [showCaptureList, setShowCaptureList] = useState(true); const [showCaptureScreenshot, setShowCaptureScreenshot] = useState(true); const [showCaptureText, setShowCaptureText] = useState(true); @@ -58,15 +53,31 @@ export const RightSidePanel: React.FC = ({ onFinishCapture const { panelHeight } = useBrowserDimensionsStore(); const { lastAction, notify, currentWorkflowActionsState, setCurrentWorkflowActionsState, resetInterpretationLog } = useGlobalInfoStore(); - const { getText, startGetText, stopGetText, getScreenshot, startGetScreenshot, stopGetScreenshot, getList, startGetList, stopGetList, startPaginationMode, stopPaginationMode, paginationType, updatePaginationType, limitType, customLimit, updateLimitType, updateCustomLimit, stopLimitMode, startLimitMode, captureStage, setCaptureStage, showPaginationOptions, setShowPaginationOptions, showLimitOptions, setShowLimitOptions, workflow, setWorkflow } = useActionContext(); + const { + getText, startGetText, stopGetText, + getList, startGetList, stopGetList, + getScreenshot, startGetScreenshot, stopGetScreenshot, + startPaginationMode, stopPaginationMode, + paginationType, updatePaginationType, + limitType, customLimit, updateLimitType, updateCustomLimit, + stopLimitMode, startLimitMode, + captureStage, setCaptureStage, + showPaginationOptions, setShowPaginationOptions, + showLimitOptions, setShowLimitOptions, + workflow, setWorkflow, + activeAction, setActiveAction, + startAction, finishAction + } = useActionContext(); + const { browserSteps, updateBrowserTextStepLabel, deleteBrowserStep, addScreenshotStep, updateListTextFieldLabel, removeListTextField } = useBrowserSteps(); const { id, socket } = useSocketStore(); const { t } = useTranslation(); + const isAnyActionActive = activeAction !== 'none'; + const workflowHandler = useCallback((data: WorkflowFile) => { setWorkflow(data); - //setRecordingLength(data.workflow.length); - }, []) + }, [setWorkflow]); useEffect(() => { if (socket) { @@ -113,12 +124,10 @@ export const RightSidePanel: React.FC = ({ onFinishCapture hasScrapeSchemaAction, }); - const shouldHideActions = hasScrapeListAction || hasScrapeSchemaAction || hasScreenshotAction; - - setShowCaptureList(!shouldHideActions); - setShowCaptureScreenshot(!shouldHideActions); - setShowCaptureText(!(hasScrapeListAction || hasScreenshotAction)); - }, [workflow]); + setShowCaptureList(true); + setShowCaptureScreenshot(true); + setShowCaptureText(true); + }, [workflow, setCurrentWorkflowActionsState]); const handleMouseEnter = (id: number) => { setHoverStates(prev => ({ ...prev, [id]: true })); @@ -128,8 +137,6 @@ export const RightSidePanel: React.FC = ({ onFinishCapture setHoverStates(prev => ({ ...prev, [id]: false })); }; - const handlePairDelete = () => { } - const handleStartGetText = () => { setIsCaptureTextConfirmed(false); startGetText(); @@ -140,6 +147,10 @@ export const RightSidePanel: React.FC = ({ onFinishCapture startGetList(); } + const handleStartGetScreenshot = () => { + startGetScreenshot(); + }; + const handleTextLabelChange = (id: number, label: string, listId?: number, fieldKey?: string) => { if (listId !== undefined && fieldKey !== undefined) { // Prevent editing if the field is confirmed @@ -253,7 +264,6 @@ export const RightSidePanel: React.FC = ({ onFinishCapture return settings; }, [browserSteps, browserStepIdList]); - const stopCaptureAndEmitGetTextSettings = useCallback(() => { const hasUnconfirmedTextSteps = browserSteps.some(step => step.type === 'text' && !confirmedTextSteps[step.id]); if (hasUnconfirmedTextSteps) { @@ -268,8 +278,9 @@ export const RightSidePanel: React.FC = ({ onFinishCapture } setIsCaptureTextConfirmed(true); resetInterpretationLog(); + finishAction('text'); onFinishCapture(); - }, [stopGetText, getTextSettingsObject, socket, browserSteps, confirmedTextSteps, resetInterpretationLog]); + }, [stopGetText, getTextSettingsObject, socket, browserSteps, confirmedTextSteps, resetInterpretationLog, finishAction, notify, onFinishCapture, t]); const getListSettingsObject = useCallback(() => { let settings: { @@ -311,7 +322,7 @@ export const RightSidePanel: React.FC = ({ onFinishCapture setShowLimitOptions(false); updateLimitType(''); updateCustomLimit(''); - }, [updatePaginationType, updateLimitType, updateCustomLimit]); + }, [setShowPaginationOptions, updatePaginationType, setShowLimitOptions, updateLimitType, updateCustomLimit]); const handleStopGetList = useCallback(() => { stopGetList(); @@ -326,10 +337,15 @@ export const RightSidePanel: React.FC = ({ onFinishCapture notify('error', t('right_panel.errors.unable_create_settings')); } handleStopGetList(); + finishAction('list'); onFinishCapture(); - }, [stopGetList, getListSettingsObject, socket, notify, handleStopGetList]); + }, [getListSettingsObject, socket, notify, handleStopGetList, finishAction, onFinishCapture, t]); - const hasUnconfirmedListTextFields = browserSteps.some(step => step.type === 'list' && Object.values(step.fields).some(field => !confirmedListTextFields[step.id]?.[field.id])); + const hasUnconfirmedListTextFields = browserSteps.some(step => + step.type === 'list' && Object.values(step.fields).some(field => + !confirmedListTextFields[step.id]?.[field.id] + ) + ); const handleConfirmListCapture = useCallback(() => { switch (captureStage) { @@ -378,7 +394,7 @@ export const RightSidePanel: React.FC = ({ onFinishCapture setCaptureStage('initial'); break; } - }, [captureStage, paginationType, limitType, customLimit, startPaginationMode, stopPaginationMode, startLimitMode, stopLimitMode, notify, stopCaptureAndEmitGetListSettings, getListSettingsObject]); + }, [captureStage, paginationType, limitType, customLimit, startPaginationMode, setShowPaginationOptions, setCaptureStage, getListSettingsObject, notify, stopPaginationMode, startLimitMode, setShowLimitOptions, stopLimitMode, setIsCaptureListConfirmed, stopCaptureAndEmitGetListSettings, t]); const handleBackCaptureList = useCallback(() => { switch (captureStage) { @@ -395,7 +411,7 @@ export const RightSidePanel: React.FC = ({ onFinishCapture setCaptureStage('initial'); break; } - }, [captureStage, stopLimitMode, startPaginationMode, stopPaginationMode]); + }, [captureStage, stopLimitMode, setShowLimitOptions, startPaginationMode, setShowPaginationOptions, setCaptureStage, stopPaginationMode]); const handlePaginationSettingSelect = (option: PaginationType) => { updatePaginationType(option); @@ -413,7 +429,7 @@ export const RightSidePanel: React.FC = ({ onFinishCapture setConfirmedTextSteps({}); setIsCaptureTextConfirmed(false); notify('error', t('right_panel.errors.capture_text_discarded')); - }, [browserSteps, stopGetText, deleteBrowserStep]); + }, [browserSteps, stopGetText, deleteBrowserStep, notify, t]); const discardGetList = useCallback(() => { stopGetList(); @@ -429,8 +445,7 @@ export const RightSidePanel: React.FC = ({ onFinishCapture setConfirmedListTextFields({}); setIsCaptureListConfirmed(false); notify('error', t('right_panel.errors.capture_list_discarded')); - }, [browserSteps, stopGetList, deleteBrowserStep, resetListState]); - + }, [browserSteps, stopGetList, deleteBrowserStep, resetListState, setShowPaginationOptions, setShowLimitOptions, setCaptureStage, notify, t]); const captureScreenshot = (fullPage: boolean) => { const screenshotSettings: ScreenshotSettings = { @@ -444,10 +459,11 @@ export const RightSidePanel: React.FC = ({ onFinishCapture socket?.emit('action', { action: 'screenshot', settings: screenshotSettings }); addScreenshotStep(fullPage); stopGetScreenshot(); + finishAction('screenshot'); + onFinishCapture(); }; const isConfirmCaptureDisabled = useMemo(() => { - // Check if we are in the initial stage and if there are no browser steps or no valid list selectors with fields if (captureStage !== 'initial') return false; const hasValidListSelector = browserSteps.some(step => @@ -456,7 +472,6 @@ export const RightSidePanel: React.FC = ({ onFinishCapture Object.keys(step.fields).length > 0 ); - // Disable the button if there are no valid list selectors or if there are unconfirmed list text fields return !hasValidListSelector || hasUnconfirmedListTextFields; }, [captureStage, browserSteps, hasUnconfirmedListTextFields]); @@ -465,15 +480,41 @@ export const RightSidePanel: React.FC = ({ onFinishCapture return ( - {/* - Last action: {` ${lastAction}`} - */} - {!getText && !getScreenshot && !getList && showCaptureList && } + {!isAnyActionActive && ( + <> + {showCaptureList && ( + + )} + + {showCaptureText && ( + + )} + + {showCaptureScreenshot && ( + + )} + + )} {getList && ( - <> + {(captureStage === 'pagination' || captureStage === 'limit') && ( - - )} - {showPaginationOptions && ( - - {t('right_panel.pagination.title')} - - - - - + + {showPaginationOptions && ( + + {t('right_panel.pagination.title')} + + + + + + + )} + + {showLimitOptions && ( + + +

{t('right_panel.limit.title')}

+
+ updateLimitType(e.target.value as LimitType)} + sx={{ + display: 'flex', + flexDirection: 'column', + width: '500px' + }} + > + } label="10" /> + } label="100" /> +
+ } label={t('right_panel.limit.custom')} /> + {limitType === 'custom' && ( + ) => { + const value = parseInt(e.target.value); + if (e.target.value === '' || value >= 1) { + updateCustomLimit(e.target.value); + } + }} + inputProps={{ + min: 1, + onKeyPress: (e: React.KeyboardEvent) => { + const value = (e.target as HTMLInputElement).value + e.key; + if (parseInt(value) < 1) { + e.preventDefault(); + } + } + }} + placeholder={t('right_panel.limit.enter_number')} + sx={{ + marginLeft: '10px', + '& input': { + padding: '10px', + }, + width: '150px', + background: isDarkMode ? "#1E2124" : 'white', + color: isDarkMode ? "white" : 'black', + }} + /> + )} +
+
+
+ )}
)} - {showLimitOptions && ( - - -

{t('right_panel.limit.title')}

-
- updateLimitType(e.target.value as LimitType)} - sx={{ - display: 'flex', - flexDirection: 'column', - width: '500px' - }} - > - } label="10" /> - } label="100" /> -
- } label={t('right_panel.limit.custom')} /> - {limitType === 'custom' && ( - ) => { - const value = parseInt(e.target.value); - // Only update if the value is greater than or equal to 1 or if the field is empty - if (e.target.value === '' || value >= 1) { - updateCustomLimit(e.target.value); - } - }} - inputProps={{ - min: 1, - onKeyPress: (e: React.KeyboardEvent) => { - const value = (e.target as HTMLInputElement).value + e.key; - if (parseInt(value) < 1) { - e.preventDefault(); - } - } - }} - placeholder={t('right_panel.limit.enter_number')} - sx={{ - marginLeft: '10px', - '& input': { - padding: '10px', - - }, - width: '150px', - background: isDarkMode ? "#1E2124" : 'white', - color: isDarkMode ? "white" : 'black', // Ensure the text field does not go outside the panel - }} - /> - )} -
-
-
- )} - {/* {!getText && !getScreenshot && !getList && showCaptureText && } */} - - {!getText && !getScreenshot && !getList && showCaptureText && } - {getText && - <> + + {getText && ( + - - } - {/* {!getText && !getScreenshot && !getList && showCaptureScreenshot && } */} - {!getText && !getScreenshot && !getList && showCaptureScreenshot && } + + )} + {getScreenshot && ( - - + + )}
+ {browserSteps.map(step => ( handleMouseEnter(step.id)} onMouseLeave={() => handleMouseLeave(step.id)} sx={{ padding: '10px', margin: '11px', borderRadius: '5px', position: 'relative', background: isDarkMode ? "#1E2124" : 'white', color: isDarkMode ? "white" : 'black' }}> @@ -714,7 +764,6 @@ export const RightSidePanel: React.FC = ({ onFinishCapture ) }} - /> {!confirmedTextSteps[step.id] ? (