@@ -21,6 +21,7 @@ import { useThemeMode } from '../../context/theme-provider';
2121import { useTranslation } from 'react-i18next' ;
2222import { useBrowserSteps } from '../../context/browserSteps' ;
2323import { useActionContext } from '../../context/browserActions' ;
24+ import { useSocketStore } from '../../context/socket' ;
2425
2526interface 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