Skip to content

Commit 23e20cd

Browse files
committed
feat: discard captured action tab data
1 parent 653a332 commit 23e20cd

File tree

1 file changed

+168
-6
lines changed

1 file changed

+168
-6
lines changed

src/components/run/InterpretationLog.tsx

Lines changed: 168 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { useThemeMode } from '../../context/theme-provider';
2121
import { useTranslation } from 'react-i18next';
2222
import { useBrowserSteps } from '../../context/browserSteps';
2323
import { useActionContext } from '../../context/browserActions';
24+
import { useSocketStore } from '../../context/socket';
2425

2526
interface InterpretationLogProps {
2627
isOpen: boolean;
@@ -57,11 +58,12 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
5758
const previousGetText = useRef<boolean>(false);
5859
const autoFocusedScreenshotIndices = useRef<Set<number>>(new Set());
5960

60-
const { browserSteps, updateListTextFieldLabel, removeListTextField, updateListStepName, updateScreenshotStepName, updateBrowserTextStepLabel, deleteBrowserStep, emitForStepId } = useBrowserSteps();
61+
const { browserSteps, updateListTextFieldLabel, removeListTextField, updateListStepName, updateScreenshotStepName, updateBrowserTextStepLabel, deleteBrowserStep, deleteStepsByActionId, emitForStepId } = useBrowserSteps();
6162
const { captureStage, getText } = useActionContext();
63+
const { socket } = useSocketStore();
6264

6365
const { browserWidth, outputPreviewHeight, outputPreviewWidth } = useBrowserDimensionsStore();
64-
const { currentWorkflowActionsState, shouldResetInterpretationLog, currentTextGroupName, setCurrentTextGroupName } = useGlobalInfoStore();
66+
const { currentWorkflowActionsState, shouldResetInterpretationLog, currentTextGroupName, setCurrentTextGroupName, notify } = useGlobalInfoStore();
6567

6668
const [showPreviewData, setShowPreviewData] = useState<boolean>(false);
6769
const userClosedDrawer = useRef<boolean>(false);
@@ -154,6 +156,76 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
154156
}
155157
};
156158

159+
const handleRemoveListAction = (listId: number, actionId: string | undefined) => {
160+
if (!actionId) return;
161+
162+
const listIndex = captureListData.findIndex(list => list.id === listId);
163+
const listItem = captureListData[listIndex];
164+
const listName = listItem?.name || `List Data ${listIndex + 1}`;
165+
const isActiveList = listIndex === activeListTab;
166+
167+
deleteStepsByActionId(actionId);
168+
169+
if (socket) {
170+
socket.emit('removeAction', { actionId });
171+
}
172+
173+
if (isActiveList && captureListData.length > 1) {
174+
if (listIndex === captureListData.length - 1) {
175+
setActiveListTab(listIndex - 1);
176+
}
177+
} else if (listIndex < activeListTab) {
178+
setActiveListTab(activeListTab - 1);
179+
}
180+
181+
notify('error', `List "${listName}" discarded`);
182+
};
183+
184+
const handleRemoveScreenshotAction = (screenshotId: number, actionId: string | undefined) => {
185+
if (!actionId) return;
186+
187+
const screenshotSteps = browserSteps.filter(step => step.type === 'screenshot' && step.screenshotData);
188+
const screenshotIndex = screenshotSteps.findIndex(step => step.id === screenshotId);
189+
const screenshotStep = screenshotSteps[screenshotIndex];
190+
const screenshotName = screenshotStep?.name || `Screenshot ${screenshotIndex + 1}`;
191+
const isActiveScreenshot = screenshotIndex === activeScreenshotTab;
192+
193+
deleteStepsByActionId(actionId);
194+
195+
if (socket) {
196+
socket.emit('removeAction', { actionId });
197+
}
198+
199+
if (isActiveScreenshot && screenshotData.length > 1) {
200+
if (screenshotIndex === screenshotData.length - 1) {
201+
setActiveScreenshotTab(screenshotIndex - 1);
202+
}
203+
} else if (screenshotIndex < activeScreenshotTab) {
204+
setActiveScreenshotTab(activeScreenshotTab - 1);
205+
}
206+
207+
notify('error', `Screenshot "${screenshotName}" discarded`);
208+
};
209+
210+
const handleRemoveAllTextActions = () => {
211+
const uniqueActionIds = new Set<string>();
212+
captureTextData.forEach(textStep => {
213+
if (textStep.actionId) {
214+
uniqueActionIds.add(textStep.actionId);
215+
}
216+
});
217+
218+
uniqueActionIds.forEach(actionId => {
219+
deleteStepsByActionId(actionId);
220+
221+
if (socket) {
222+
socket.emit('removeAction', { actionId });
223+
}
224+
});
225+
226+
notify('error', `Text data "${currentTextGroupName}" discarded`);
227+
};
228+
157229
const startEdit = (stepId: number, type: 'list' | 'text' | 'screenshot', currentValue: string) => {
158230
setEditing({ stepId, type, value: currentValue });
159231
};
@@ -577,13 +649,17 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
577649
: '2px solid #ffffff'
578650
: '2px solid transparent',
579651
transition: 'all 0.2s ease',
652+
position: 'relative',
580653
'&:hover': {
581654
backgroundColor: isActive
582655
? undefined
583656
: darkMode
584657
? '#161616'
585658
: '#e9ecef',
586659
},
660+
'&:hover .delete-icon': {
661+
opacity: 1
662+
},
587663
}}
588664
>
589665
{isEditing ? (
@@ -612,7 +688,33 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
612688
}}
613689
/>
614690
) : (
615-
listItem.name || `List Data ${index + 1}`
691+
<>
692+
{listItem.name || `List Data ${index + 1}`}
693+
<IconButton
694+
className="delete-icon"
695+
size="small"
696+
onClick={(e) => {
697+
e.stopPropagation();
698+
handleRemoveListAction(listItem.id, listItem.actionId);
699+
}}
700+
sx={{
701+
position: 'absolute',
702+
right: 4,
703+
top: '50%',
704+
transform: 'translateY(-50%)',
705+
opacity: 0,
706+
transition: 'opacity 0.2s',
707+
color: darkMode ? '#999' : '#666',
708+
padding: '2px',
709+
'&:hover': {
710+
color: '#f44336',
711+
backgroundColor: darkMode ? 'rgba(244, 67, 54, 0.1)' : 'rgba(244, 67, 54, 0.05)'
712+
}
713+
}}
714+
>
715+
<CloseIcon sx={{ fontSize: '14px' }} />
716+
</IconButton>
717+
</>
616718
)}
617719
</Box>
618720
</Tooltip>
@@ -783,7 +885,7 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
783885
}}
784886
>
785887
{(() => {
786-
const screenshotSteps = browserSteps.filter(step => step.type === 'screenshot' && step.screenshotData) as Array<{ id: number; name?: string; type: 'screenshot'; screenshotData?: string }>;
888+
const screenshotSteps = browserSteps.filter(step => step.type === 'screenshot' && step.screenshotData) as Array<{ id: number; name?: string; type: 'screenshot'; fullPage: boolean; actionId?: string; screenshotData?: string }>;
787889
return screenshotData.map((screenshot, index) => {
788890
const screenshotStep = screenshotSteps[index];
789891
if (!screenshotStep) return null;
@@ -829,13 +931,17 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
829931
: '2px solid #ffffff'
830932
: '2px solid transparent',
831933
transition: 'all 0.2s ease',
934+
position: 'relative',
832935
'&:hover': {
833936
backgroundColor: isActive
834937
? undefined
835938
: darkMode
836939
? '#161616'
837940
: '#e9ecef',
838941
},
942+
'&:hover .delete-icon': {
943+
opacity: 1
944+
},
839945
}}
840946
>
841947
{isEditing ? (
@@ -864,7 +970,33 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
864970
}}
865971
/>
866972
) : (
867-
screenshotName
973+
<>
974+
{screenshotName}
975+
<IconButton
976+
className="delete-icon"
977+
size="small"
978+
onClick={(e) => {
979+
e.stopPropagation();
980+
handleRemoveScreenshotAction(screenshotStep.id, screenshotStep.actionId);
981+
}}
982+
sx={{
983+
position: 'absolute',
984+
right: 4,
985+
top: '50%',
986+
transform: 'translateY(-50%)',
987+
opacity: 0,
988+
transition: 'opacity 0.2s',
989+
color: darkMode ? '#999' : '#666',
990+
padding: '2px',
991+
'&:hover': {
992+
color: '#f44336',
993+
backgroundColor: darkMode ? 'rgba(244, 67, 54, 0.1)' : 'rgba(244, 67, 54, 0.05)'
994+
}
995+
}}
996+
>
997+
<CloseIcon sx={{ fontSize: '14px' }} />
998+
</IconButton>
999+
</>
8681000
)}
8691001
</Box>
8701002
</Tooltip>
@@ -921,6 +1053,10 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
9211053
borderColor: darkMode ? '#2a2a2a' : '#d0d0d0',
9221054
borderBottom: darkMode ? '2px solid #1c1c1c' : '2px solid #ffffff',
9231055
transition: 'all 0.2s ease',
1056+
position: 'relative',
1057+
'&:hover .delete-icon': {
1058+
opacity: 1
1059+
},
9241060
}}
9251061
>
9261062
{editingTextGroupName ? (
@@ -952,7 +1088,33 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
9521088
}}
9531089
/>
9541090
) : (
955-
currentTextGroupName
1091+
<>
1092+
{currentTextGroupName}
1093+
<IconButton
1094+
className="delete-icon"
1095+
size="small"
1096+
onClick={(e) => {
1097+
e.stopPropagation();
1098+
handleRemoveAllTextActions();
1099+
}}
1100+
sx={{
1101+
position: 'absolute',
1102+
right: 4,
1103+
top: '50%',
1104+
transform: 'translateY(-50%)',
1105+
opacity: 0,
1106+
transition: 'opacity 0.2s',
1107+
color: darkMode ? '#999' : '#666',
1108+
padding: '2px',
1109+
'&:hover': {
1110+
color: '#f44336',
1111+
backgroundColor: darkMode ? 'rgba(244, 67, 54, 0.1)' : 'rgba(244, 67, 54, 0.05)'
1112+
}
1113+
}}
1114+
>
1115+
<CloseIcon sx={{ fontSize: '14px' }} />
1116+
</IconButton>
1117+
</>
9561118
)}
9571119
</Box>
9581120
</Tooltip>

0 commit comments

Comments
 (0)