Skip to content

Commit fb3e41e

Browse files
authored
Merge pull request #882 from getmaxun/rm-actions
feat: discard captured action tab data
2 parents 42f851f + 3ddce1a commit fb3e41e

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,8 +58,9 @@ 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();
6466
const { currentWorkflowActionsState, shouldResetInterpretationLog, currentTextGroupName, setCurrentTextGroupName, notify } = useGlobalInfoStore();
@@ -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 checkForDuplicateName = (stepId: number, type: 'list' | 'text' | 'screenshot', newName: string): boolean => {
158230
const trimmedName = newName.trim();
159231

@@ -174,7 +246,7 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
174246
}
175247

176248
return false;
177-
};
249+
}
178250

179251
const startEdit = (stepId: number, type: 'list' | 'text' | 'screenshot', currentValue: string) => {
180252
setEditing({ stepId, type, value: currentValue });
@@ -609,13 +681,17 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
609681
: '2px solid #ffffff'
610682
: '2px solid transparent',
611683
transition: 'all 0.2s ease',
684+
position: 'relative',
612685
'&:hover': {
613686
backgroundColor: isActive
614687
? undefined
615688
: darkMode
616689
? '#161616'
617690
: '#e9ecef',
618691
},
692+
'&:hover .delete-icon': {
693+
opacity: 1
694+
},
619695
}}
620696
>
621697
{isEditing ? (
@@ -644,7 +720,33 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
644720
}}
645721
/>
646722
) : (
647-
listItem.name || `List Data ${index + 1}`
723+
<>
724+
{listItem.name || `List Data ${index + 1}`}
725+
<IconButton
726+
className="delete-icon"
727+
size="small"
728+
onClick={(e) => {
729+
e.stopPropagation();
730+
handleRemoveListAction(listItem.id, listItem.actionId);
731+
}}
732+
sx={{
733+
position: 'absolute',
734+
right: 4,
735+
top: '50%',
736+
transform: 'translateY(-50%)',
737+
opacity: 0,
738+
transition: 'opacity 0.2s',
739+
color: darkMode ? '#999' : '#666',
740+
padding: '2px',
741+
'&:hover': {
742+
color: '#f44336',
743+
backgroundColor: darkMode ? 'rgba(244, 67, 54, 0.1)' : 'rgba(244, 67, 54, 0.05)'
744+
}
745+
}}
746+
>
747+
<CloseIcon sx={{ fontSize: '14px' }} />
748+
</IconButton>
749+
</>
648750
)}
649751
</Box>
650752
</Tooltip>
@@ -815,7 +917,7 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
815917
}}
816918
>
817919
{(() => {
818-
const screenshotSteps = browserSteps.filter(step => step.type === 'screenshot' && step.screenshotData) as Array<{ id: number; name?: string; type: 'screenshot'; screenshotData?: string }>;
920+
const screenshotSteps = browserSteps.filter(step => step.type === 'screenshot' && step.screenshotData) as Array<{ id: number; name?: string; type: 'screenshot'; fullPage: boolean; actionId?: string; screenshotData?: string }>;
819921
return screenshotData.map((screenshot, index) => {
820922
const screenshotStep = screenshotSteps[index];
821923
if (!screenshotStep) return null;
@@ -861,13 +963,17 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
861963
: '2px solid #ffffff'
862964
: '2px solid transparent',
863965
transition: 'all 0.2s ease',
966+
position: 'relative',
864967
'&:hover': {
865968
backgroundColor: isActive
866969
? undefined
867970
: darkMode
868971
? '#161616'
869972
: '#e9ecef',
870973
},
974+
'&:hover .delete-icon': {
975+
opacity: 1
976+
},
871977
}}
872978
>
873979
{isEditing ? (
@@ -896,7 +1002,33 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
8961002
}}
8971003
/>
8981004
) : (
899-
screenshotName
1005+
<>
1006+
{screenshotName}
1007+
<IconButton
1008+
className="delete-icon"
1009+
size="small"
1010+
onClick={(e) => {
1011+
e.stopPropagation();
1012+
handleRemoveScreenshotAction(screenshotStep.id, screenshotStep.actionId);
1013+
}}
1014+
sx={{
1015+
position: 'absolute',
1016+
right: 4,
1017+
top: '50%',
1018+
transform: 'translateY(-50%)',
1019+
opacity: 0,
1020+
transition: 'opacity 0.2s',
1021+
color: darkMode ? '#999' : '#666',
1022+
padding: '2px',
1023+
'&:hover': {
1024+
color: '#f44336',
1025+
backgroundColor: darkMode ? 'rgba(244, 67, 54, 0.1)' : 'rgba(244, 67, 54, 0.05)'
1026+
}
1027+
}}
1028+
>
1029+
<CloseIcon sx={{ fontSize: '14px' }} />
1030+
</IconButton>
1031+
</>
9001032
)}
9011033
</Box>
9021034
</Tooltip>
@@ -953,6 +1085,10 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
9531085
borderColor: darkMode ? '#2a2a2a' : '#d0d0d0',
9541086
borderBottom: darkMode ? '2px solid #1c1c1c' : '2px solid #ffffff',
9551087
transition: 'all 0.2s ease',
1088+
position: 'relative',
1089+
'&:hover .delete-icon': {
1090+
opacity: 1
1091+
},
9561092
}}
9571093
>
9581094
{editingTextGroupName ? (
@@ -984,7 +1120,33 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
9841120
}}
9851121
/>
9861122
) : (
987-
currentTextGroupName
1123+
<>
1124+
{currentTextGroupName}
1125+
<IconButton
1126+
className="delete-icon"
1127+
size="small"
1128+
onClick={(e) => {
1129+
e.stopPropagation();
1130+
handleRemoveAllTextActions();
1131+
}}
1132+
sx={{
1133+
position: 'absolute',
1134+
right: 4,
1135+
top: '50%',
1136+
transform: 'translateY(-50%)',
1137+
opacity: 0,
1138+
transition: 'opacity 0.2s',
1139+
color: darkMode ? '#999' : '#666',
1140+
padding: '2px',
1141+
'&:hover': {
1142+
color: '#f44336',
1143+
backgroundColor: darkMode ? 'rgba(244, 67, 54, 0.1)' : 'rgba(244, 67, 54, 0.05)'
1144+
}
1145+
}}
1146+
>
1147+
<CloseIcon sx={{ fontSize: '14px' }} />
1148+
</IconButton>
1149+
</>
9881150
)}
9891151
</Box>
9901152
</Tooltip>

0 commit comments

Comments
 (0)