feat: enhance notifs on confirm captures
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useCallback, useEffect, useMemo } from 'react';
|
import React, { useState, useCallback, useEffect, useMemo } from 'react';
|
||||||
import { Button, Paper, Box, TextField, IconButton } from "@mui/material";
|
import { Button, Paper, Box, TextField, IconButton, Tooltip } 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';
|
||||||
@@ -21,6 +21,7 @@ import ActionDescriptionBox from '../action/ActionDescriptionBox';
|
|||||||
import { useThemeMode } from '../../context/theme-provider';
|
import { useThemeMode } from '../../context/theme-provider';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useBrowserDimensionsStore } from '../../context/browserDimensions';
|
import { useBrowserDimensionsStore } from '../../context/browserDimensions';
|
||||||
|
import { emptyWorkflow } from '../../shared/constants';
|
||||||
import { clientListExtractor } from '../../helpers/clientListExtractor';
|
import { clientListExtractor } from '../../helpers/clientListExtractor';
|
||||||
import { clientSelectorGenerator } from '../../helpers/clientSelectorGenerator';
|
import { clientSelectorGenerator } from '../../helpers/clientSelectorGenerator';
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
const [isCaptureListConfirmed, setIsCaptureListConfirmed] = useState(false);
|
const [isCaptureListConfirmed, setIsCaptureListConfirmed] = useState(false);
|
||||||
const { panelHeight } = useBrowserDimensionsStore();
|
const { panelHeight } = useBrowserDimensionsStore();
|
||||||
|
|
||||||
const { lastAction, notify, currentWorkflowActionsState, setCurrentWorkflowActionsState, resetInterpretationLog, currentListActionId, setCurrentListActionId, currentTextActionId, setCurrentTextActionId, currentScreenshotActionId, setCurrentScreenshotActionId, updateDOMMode, currentSnapshot, isDOMMode } = useGlobalInfoStore();
|
const { lastAction, notify, currentWorkflowActionsState, setCurrentWorkflowActionsState, resetInterpretationLog, currentListActionId, setCurrentListActionId, currentTextActionId, setCurrentTextActionId, currentScreenshotActionId, setCurrentScreenshotActionId, isDOMMode, setIsDOMMode, currentSnapshot, setCurrentSnapshot, updateDOMMode, initialUrl, setRecordingUrl } = useGlobalInfoStore();
|
||||||
const {
|
const {
|
||||||
getText, startGetText, stopGetText,
|
getText, startGetText, stopGetText,
|
||||||
getList, startGetList, stopGetList,
|
getList, startGetList, stopGetList,
|
||||||
@@ -89,12 +90,6 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const screenshotModeHandler = (data: any) => {
|
|
||||||
if (!data.userId || data.userId === id) {
|
|
||||||
updateDOMMode(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const domcastHandler = (data: any) => {
|
const domcastHandler = (data: any) => {
|
||||||
if (!data.userId || data.userId === id) {
|
if (!data.userId || data.userId === id) {
|
||||||
if (data.snapshotData && data.snapshotData.snapshot) {
|
if (data.snapshotData && data.snapshotData.snapshot) {
|
||||||
@@ -104,12 +99,10 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
};
|
};
|
||||||
|
|
||||||
socket.on("dom-mode-enabled", domModeHandler);
|
socket.on("dom-mode-enabled", domModeHandler);
|
||||||
socket.on("screenshot-mode-enabled", screenshotModeHandler);
|
|
||||||
socket.on("domcast", domcastHandler);
|
socket.on("domcast", domcastHandler);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
socket.off("dom-mode-enabled", domModeHandler);
|
socket.off("dom-mode-enabled", domModeHandler);
|
||||||
socket.off("screenshot-mode-enabled", screenshotModeHandler);
|
|
||||||
socket.off("domcast", domcastHandler);
|
socket.off("domcast", domcastHandler);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -243,36 +236,18 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.entries(fields).forEach(([key, field]) => {
|
|
||||||
if (field.selectorObj?.selector) {
|
|
||||||
const isFieldXPath =
|
|
||||||
field.selectorObj.selector.startsWith("//") ||
|
|
||||||
field.selectorObj.selector.startsWith("/");
|
|
||||||
console.log(
|
|
||||||
`Field "${key}" selector:`,
|
|
||||||
field.selectorObj.selector,
|
|
||||||
`(XPath: ${isFieldXPath})`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const extractedData = clientListExtractor.extractListData(
|
const extractedData = clientListExtractor.extractListData(
|
||||||
iframeDoc,
|
iframeDoc,
|
||||||
listSelector,
|
listSelector,
|
||||||
fields,
|
fields,
|
||||||
5
|
5
|
||||||
);
|
);
|
||||||
|
|
||||||
updateListStepData(currentListId, extractedData);
|
updateListStepData(currentListId, extractedData);
|
||||||
|
|
||||||
if (extractedData.length === 0) {
|
if (extractedData.length === 0) {
|
||||||
console.warn(
|
console.warn("⚠️ No data extracted - this might indicate selector issues");
|
||||||
"⚠️ No data extracted - this might indicate selector issues"
|
notify("warning", "No data was extracted. Please verify your selections.");
|
||||||
);
|
|
||||||
notify(
|
|
||||||
"warning",
|
|
||||||
"No data was extracted. Please verify your selections."
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error in client-side data extraction:", error);
|
console.error("Error in client-side data extraction:", error);
|
||||||
@@ -346,12 +321,32 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
|
|
||||||
const handleTextStepConfirm = (id: number) => {
|
const handleTextStepConfirm = (id: number) => {
|
||||||
const label = textLabels[id]?.trim();
|
const label = textLabels[id]?.trim();
|
||||||
if (label) {
|
if (!label) {
|
||||||
updateBrowserTextStepLabel(id, label);
|
|
||||||
setConfirmedTextSteps(prev => ({ ...prev, [id]: true }));
|
|
||||||
} else {
|
|
||||||
setErrors(prevErrors => ({ ...prevErrors, [id]: t('right_panel.errors.label_required') }));
|
setErrors(prevErrors => ({ ...prevErrors, [id]: t('right_panel.errors.label_required') }));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const existingLabels = browserSteps
|
||||||
|
.filter(step =>
|
||||||
|
step.type === 'text' &&
|
||||||
|
step.id !== id &&
|
||||||
|
confirmedTextSteps[step.id] &&
|
||||||
|
'label' in step &&
|
||||||
|
step.label
|
||||||
|
)
|
||||||
|
.map(step => (step as any).label);
|
||||||
|
|
||||||
|
if (existingLabels.includes(label)) {
|
||||||
|
setErrors(prevErrors => ({
|
||||||
|
...prevErrors,
|
||||||
|
[id]: t('right_panel.errors.duplicate_label') || `Label "${label}" already exists. Please use a unique label.`
|
||||||
|
}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateBrowserTextStepLabel(id, label);
|
||||||
|
setConfirmedTextSteps(prev => ({ ...prev, [id]: true }));
|
||||||
|
setErrors(prevErrors => ({ ...prevErrors, [id]: '' }));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTextStepDiscard = (id: number) => {
|
const handleTextStepDiscard = (id: number) => {
|
||||||
@@ -425,14 +420,22 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getTextSettingsObject = useCallback(() => {
|
const getTextSettingsObject = useCallback(() => {
|
||||||
const settings: Record<string, { selector: string; tag?: string;[key: string]: any }> = {};
|
const settings: Record<string, {
|
||||||
|
selector: string;
|
||||||
|
tag?: string;
|
||||||
|
[key: string]: any
|
||||||
|
}> = {};
|
||||||
|
|
||||||
browserSteps.forEach(step => {
|
browserSteps.forEach(step => {
|
||||||
if (browserStepIdList.includes(step.id)) {
|
if (browserStepIdList.includes(step.id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (step.type === 'text' && step.label && step.selectorObj?.selector) {
|
if (step.type === 'text' && step.label && step.selectorObj?.selector) {
|
||||||
settings[step.label] = step.selectorObj;
|
settings[step.label] = {
|
||||||
|
...step.selectorObj,
|
||||||
|
selector: step.selectorObj.selector
|
||||||
|
};
|
||||||
}
|
}
|
||||||
setBrowserStepIdList(prevList => [...prevList, step.id]);
|
setBrowserStepIdList(prevList => [...prevList, step.id]);
|
||||||
});
|
});
|
||||||
@@ -441,15 +444,24 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
}, [browserSteps, browserStepIdList]);
|
}, [browserSteps, browserStepIdList]);
|
||||||
|
|
||||||
const stopCaptureAndEmitGetTextSettings = useCallback(() => {
|
const stopCaptureAndEmitGetTextSettings = useCallback(() => {
|
||||||
const hasUnconfirmedTextSteps = browserSteps.some(step => step.type === 'text' && !confirmedTextSteps[step.id]);
|
const hasTextStepsForCurrentAction = browserSteps.some(step => step.type === 'text' && step.actionId === currentTextActionId);
|
||||||
if (hasUnconfirmedTextSteps) {
|
if (!hasTextStepsForCurrentAction) {
|
||||||
|
notify('error', t('right_panel.errors.no_text_captured'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasUnconfirmedTextStepsForCurrentAction = browserSteps.some(step =>
|
||||||
|
step.type === 'text' &&
|
||||||
|
step.actionId === currentTextActionId &&
|
||||||
|
!confirmedTextSteps[step.id]
|
||||||
|
);
|
||||||
|
if (hasUnconfirmedTextStepsForCurrentAction) {
|
||||||
notify('error', t('right_panel.errors.confirm_text_fields'));
|
notify('error', t('right_panel.errors.confirm_text_fields'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
stopGetText();
|
stopGetText();
|
||||||
const settings = getTextSettingsObject();
|
const settings = getTextSettingsObject();
|
||||||
const hasTextSteps = browserSteps.some(step => step.type === 'text');
|
if (hasTextStepsForCurrentAction) {
|
||||||
if (hasTextSteps) {
|
|
||||||
socket?.emit('action', { action: 'scrapeSchema', settings });
|
socket?.emit('action', { action: 'scrapeSchema', settings });
|
||||||
}
|
}
|
||||||
setIsCaptureTextConfirmed(true);
|
setIsCaptureTextConfirmed(true);
|
||||||
@@ -463,15 +475,29 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
const getListSettingsObject = useCallback(() => {
|
const getListSettingsObject = useCallback(() => {
|
||||||
let settings: {
|
let settings: {
|
||||||
listSelector?: string;
|
listSelector?: string;
|
||||||
fields?: Record<string, { selector: string; tag?: string; [key: string]: any; isShadow?: boolean }>;
|
fields?: Record<string, {
|
||||||
pagination?: { type: string; selector?: string; isShadow?: boolean };
|
selector: string;
|
||||||
|
tag?: string;
|
||||||
|
[key: string]: any;
|
||||||
|
isShadow?: boolean;
|
||||||
|
}>;
|
||||||
|
pagination?: {
|
||||||
|
type: string;
|
||||||
|
selector?: string;
|
||||||
|
isShadow?: boolean;
|
||||||
|
};
|
||||||
limit?: number;
|
limit?: number;
|
||||||
isShadow?: boolean
|
isShadow?: boolean;
|
||||||
} = {};
|
} = {};
|
||||||
|
|
||||||
browserSteps.forEach(step => {
|
browserSteps.forEach(step => {
|
||||||
if (step.type === 'list' && step.listSelector && Object.keys(step.fields).length > 0) {
|
if (step.type === 'list' && step.listSelector && Object.keys(step.fields).length > 0) {
|
||||||
const fields: Record<string, { selector: string; tag?: string;[key: string]: any; isShadow?: boolean }> = {};
|
const fields: Record<string, {
|
||||||
|
selector: string;
|
||||||
|
tag?: string;
|
||||||
|
[key: string]: any;
|
||||||
|
isShadow?: boolean;
|
||||||
|
}> = {};
|
||||||
|
|
||||||
Object.entries(step.fields).forEach(([id, field]) => {
|
Object.entries(step.fields).forEach(([id, field]) => {
|
||||||
if (field.selectorObj?.selector) {
|
if (field.selectorObj?.selector) {
|
||||||
@@ -487,7 +513,11 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
settings = {
|
settings = {
|
||||||
listSelector: step.listSelector,
|
listSelector: step.listSelector,
|
||||||
fields: fields,
|
fields: fields,
|
||||||
pagination: { type: paginationType, selector: step.pagination?.selector, isShadow: step.isShadow },
|
pagination: {
|
||||||
|
type: paginationType,
|
||||||
|
selector: step.pagination?.selector,
|
||||||
|
isShadow: step.isShadow
|
||||||
|
},
|
||||||
limit: parseInt(limitType === 'custom' ? customLimit : limitType),
|
limit: parseInt(limitType === 'custom' ? customLimit : limitType),
|
||||||
isShadow: step.isShadow
|
isShadow: step.isShadow
|
||||||
};
|
};
|
||||||
@@ -503,7 +533,7 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
setShowLimitOptions(false);
|
setShowLimitOptions(false);
|
||||||
updateLimitType('');
|
updateLimitType('');
|
||||||
updateCustomLimit('');
|
updateCustomLimit('');
|
||||||
}, [setShowPaginationOptions, updatePaginationType, setShowLimitOptions, updateLimitType, updateCustomLimit]);
|
}, [updatePaginationType, updateLimitType, updateCustomLimit]);
|
||||||
|
|
||||||
const handleStopGetList = useCallback(() => {
|
const handleStopGetList = useCallback(() => {
|
||||||
stopGetList();
|
stopGetList();
|
||||||
@@ -512,8 +542,6 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
|
|
||||||
const stopCaptureAndEmitGetListSettings = useCallback(() => {
|
const stopCaptureAndEmitGetListSettings = useCallback(() => {
|
||||||
const settings = getListSettingsObject();
|
const settings = getListSettingsObject();
|
||||||
|
|
||||||
console.log("rrwebSnapshotHandler", settings);
|
|
||||||
|
|
||||||
const latestListStep = getLatestListStep(browserSteps);
|
const latestListStep = getLatestListStep(browserSteps);
|
||||||
if (latestListStep && settings) {
|
if (latestListStep && settings) {
|
||||||
@@ -534,6 +562,7 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
|
|
||||||
const hasUnconfirmedListTextFields = browserSteps.some(step =>
|
const hasUnconfirmedListTextFields = browserSteps.some(step =>
|
||||||
step.type === 'list' &&
|
step.type === 'list' &&
|
||||||
|
step.actionId === currentListActionId &&
|
||||||
Object.entries(step.fields).some(([fieldKey]) =>
|
Object.entries(step.fields).some(([fieldKey]) =>
|
||||||
!confirmedListTextFields[step.id]?.[fieldKey]
|
!confirmedListTextFields[step.id]?.[fieldKey]
|
||||||
)
|
)
|
||||||
@@ -549,6 +578,31 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
const handleConfirmListCapture = useCallback(() => {
|
const handleConfirmListCapture = useCallback(() => {
|
||||||
switch (captureStage) {
|
switch (captureStage) {
|
||||||
case 'initial':
|
case 'initial':
|
||||||
|
const hasValidListSelectorForCurrentAction = browserSteps.some(step =>
|
||||||
|
step.type === 'list' &&
|
||||||
|
step.actionId === currentListActionId &&
|
||||||
|
step.listSelector &&
|
||||||
|
Object.keys(step.fields).length > 0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!hasValidListSelectorForCurrentAction) {
|
||||||
|
notify('error', t('right_panel.errors.capture_list_first'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasUnconfirmedListTextFieldsForCurrentAction = browserSteps.some(step =>
|
||||||
|
step.type === 'list' &&
|
||||||
|
step.actionId === currentListActionId &&
|
||||||
|
Object.entries(step.fields).some(([fieldKey]) =>
|
||||||
|
!confirmedListTextFields[step.id]?.[fieldKey]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hasUnconfirmedListTextFieldsForCurrentAction) {
|
||||||
|
notify('error', t('right_panel.errors.confirm_all_list_fields'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
startPaginationMode();
|
startPaginationMode();
|
||||||
setShowPaginationOptions(true);
|
setShowPaginationOptions(true);
|
||||||
setCaptureStage('pagination');
|
setCaptureStage('pagination');
|
||||||
@@ -599,7 +653,7 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
setCaptureStage('initial');
|
setCaptureStage('initial');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}, [captureStage, paginationType, limitType, customLimit, startPaginationMode, setShowPaginationOptions, setCaptureStage, getListSettingsObject, notify, stopPaginationMode, startLimitMode, setShowLimitOptions, stopLimitMode, setIsCaptureListConfirmed, stopCaptureAndEmitGetListSettings, t]);
|
}, [captureStage, paginationType, limitType, customLimit, startPaginationMode, setShowPaginationOptions, setCaptureStage, getListSettingsObject, notify, stopPaginationMode, startLimitMode, setShowLimitOptions, stopLimitMode, setIsCaptureListConfirmed, stopCaptureAndEmitGetListSettings, t, browserSteps, currentListActionId, confirmedListTextFields]);
|
||||||
|
|
||||||
const handleBackCaptureList = useCallback(() => {
|
const handleBackCaptureList = useCallback(() => {
|
||||||
switch (captureStage) {
|
switch (captureStage) {
|
||||||
@@ -616,7 +670,7 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
setCaptureStage('initial');
|
setCaptureStage('initial');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}, [captureStage, stopLimitMode, setShowLimitOptions, startPaginationMode, setShowPaginationOptions, setCaptureStage, stopPaginationMode]);
|
}, [captureStage, stopLimitMode, startPaginationMode, stopPaginationMode]);
|
||||||
|
|
||||||
const handlePaginationSettingSelect = (option: PaginationType) => {
|
const handlePaginationSettingSelect = (option: PaginationType) => {
|
||||||
updatePaginationType(option);
|
updatePaginationType(option);
|
||||||
@@ -716,14 +770,23 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
const isConfirmCaptureDisabled = useMemo(() => {
|
const isConfirmCaptureDisabled = useMemo(() => {
|
||||||
if (captureStage !== 'initial') return false;
|
if (captureStage !== 'initial') return false;
|
||||||
|
|
||||||
const hasValidListSelector = browserSteps.some(step =>
|
const hasValidListSelectorForCurrentAction = browserSteps.some(step =>
|
||||||
step.type === 'list' &&
|
step.type === 'list' &&
|
||||||
|
step.actionId === currentListActionId &&
|
||||||
step.listSelector &&
|
step.listSelector &&
|
||||||
Object.keys(step.fields).length > 0
|
Object.keys(step.fields).length > 0
|
||||||
);
|
);
|
||||||
|
|
||||||
return !hasValidListSelector || hasUnconfirmedListTextFields;
|
const hasUnconfirmedListTextFieldsForCurrentAction = browserSteps.some(step =>
|
||||||
}, [captureStage, browserSteps, hasUnconfirmedListTextFields]);
|
step.type === 'list' &&
|
||||||
|
step.actionId === currentListActionId &&
|
||||||
|
Object.entries(step.fields).some(([fieldKey]) =>
|
||||||
|
!confirmedListTextFields[step.id]?.[fieldKey]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return !hasValidListSelectorForCurrentAction || hasUnconfirmedListTextFieldsForCurrentAction;
|
||||||
|
}, [captureStage, browserSteps, currentListActionId, confirmedListTextFields]);
|
||||||
|
|
||||||
const theme = useThemeMode();
|
const theme = useThemeMode();
|
||||||
const isDarkMode = theme.darkMode;
|
const isDarkMode = theme.darkMode;
|
||||||
@@ -779,21 +842,33 @@ export const RightSidePanel: React.FC<RightSidePanelProps> = ({ onFinishCapture
|
|||||||
{t('right_panel.buttons.back')}
|
{t('right_panel.buttons.back')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<Button
|
<Tooltip
|
||||||
variant="outlined"
|
title={
|
||||||
onClick={handleConfirmListCapture}
|
captureStage !== 'initial' && hasUnconfirmedListTextFields
|
||||||
disabled={captureStage === 'initial' ? isConfirmCaptureDisabled : hasUnconfirmedListTextFields}
|
? t('right_panel.tooltips.confirm_all_list_fields')
|
||||||
sx={{
|
: ''
|
||||||
color: '#ff00c3 !important',
|
}
|
||||||
borderColor: '#ff00c3 !important',
|
placement="top"
|
||||||
backgroundColor: 'whitesmoke !important',
|
arrow
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
|
<span>
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
onClick={handleConfirmListCapture}
|
||||||
|
disabled={captureStage !== 'initial' && hasUnconfirmedListTextFields}
|
||||||
|
sx={{
|
||||||
|
color: '#ff00c3 !important',
|
||||||
|
borderColor: '#ff00c3 !important',
|
||||||
|
backgroundColor: 'whitesmoke !important',
|
||||||
|
}}
|
||||||
|
>
|
||||||
{captureStage === 'initial' ? t('right_panel.buttons.confirm_capture') :
|
{captureStage === 'initial' ? t('right_panel.buttons.confirm_capture') :
|
||||||
captureStage === 'pagination' ? t('right_panel.buttons.confirm_pagination') :
|
captureStage === 'pagination' ? t('right_panel.buttons.confirm_pagination') :
|
||||||
captureStage === 'limit' ? t('right_panel.buttons.confirm_limit') :
|
captureStage === 'limit' ? t('right_panel.buttons.confirm_limit') :
|
||||||
t('right_panel.buttons.finish_capture')}
|
t('right_panel.buttons.finish_capture')}
|
||||||
</Button>
|
</Button>
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
<Button
|
<Button
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
color="error"
|
color="error"
|
||||||
|
|||||||
Reference in New Issue
Block a user