Skip to content

Commit f2453a3

Browse files
authored
Merge pull request #861 from getmaxun/tabswitch-fix
fix: switch to active action data tab on capture
2 parents 674ce9a + 6b0fac6 commit f2453a3

File tree

1 file changed

+82
-140
lines changed

1 file changed

+82
-140
lines changed

src/components/run/InterpretationLog.tsx

Lines changed: 82 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,14 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
4141
const [editingField, setEditingField] = useState<{listId: number, fieldKey: string} | null>(null);
4242
const [editingValue, setEditingValue] = useState<string>('');
4343

44-
const [editingListName, setEditingListName] = useState<number | null>(null);
45-
const [editingListNameValue, setEditingListNameValue] = useState<string>('');
46-
4744
const [editingTextGroupName, setEditingTextGroupName] = useState<boolean>(false);
4845
const [editingTextGroupNameValue, setEditingTextGroupNameValue] = useState<string>('Text Data');
4946

50-
const [editingTextLabel, setEditingTextLabel] = useState<number | null>(null);
51-
const [editingTextLabelValue, setEditingTextLabelValue] = useState<string>('');
52-
53-
const [editingScreenshotName, setEditingScreenshotName] = useState<number | null>(null);
54-
const [editingScreenshotNameValue, setEditingScreenshotNameValue] = useState<string>('');
47+
const [editing, setEditing] = useState<{
48+
stepId: number | null;
49+
type: 'list' | 'text' | 'screenshot' | null;
50+
value: string;
51+
}>({ stepId: null, type: null, value: '' });
5552

5653
const logEndRef = useRef<HTMLDivElement | null>(null);
5754
const autoFocusedListIds = useRef<Set<number>>(new Set());
@@ -125,30 +122,6 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
125122
}
126123
};
127124

128-
const handleStartEditListName = (listId: number, currentName: string) => {
129-
setEditingListName(listId);
130-
setEditingListNameValue(currentName);
131-
};
132-
133-
const handleSaveListName = () => {
134-
if (editingListName !== null) {
135-
const trimmedName = editingListNameValue.trim();
136-
const finalName = trimmedName || `List Data ${captureListData.findIndex(l => l.id === editingListName) + 1}`;
137-
138-
updateListStepName(editingListName, finalName);
139-
140-
// Use ref-synced version of browserSteps via emitForStepId
141-
const listStep = browserSteps.find(step => step.id === editingListName);
142-
if (listStep?.actionId) {
143-
// small async delay ensures React state commit
144-
setTimeout(() => emitForStepId(listStep.actionId!), 0);
145-
}
146-
147-
setEditingListName(null);
148-
setEditingListNameValue('');
149-
}
150-
};
151-
152125
const handleStartEditTextGroupName = () => {
153126
setEditingTextGroupName(true);
154127
setEditingTextGroupNameValue(currentTextGroupName);
@@ -158,7 +131,6 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
158131
const trimmedName = editingTextGroupNameValue.trim();
159132
const finalName = trimmedName || 'Text Data';
160133

161-
console.log("SAVING TEXT GROUP NAME:", finalName);
162134
setCurrentTextGroupName(finalName);
163135
setEditingTextGroupName(false);
164136

@@ -169,34 +141,6 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
169141
}, 0);
170142
};
171143

172-
173-
const handleStartEditTextLabel = (textId: number, currentLabel: string) => {
174-
setEditingTextLabel(textId);
175-
setEditingTextLabelValue(currentLabel);
176-
};
177-
178-
const handleSaveTextLabel = () => {
179-
if (editingTextLabel !== null && editingTextLabelValue.trim()) {
180-
const textStep = browserSteps.find(step => step.id === editingTextLabel);
181-
const actionId = textStep?.actionId;
182-
183-
updateBrowserTextStepLabel(editingTextLabel, editingTextLabelValue.trim());
184-
185-
// Emit updated action to backend after state update completes
186-
if (actionId) {
187-
setTimeout(() => emitForStepId(actionId), 0);
188-
}
189-
190-
setEditingTextLabel(null);
191-
setEditingTextLabelValue('');
192-
}
193-
};
194-
195-
const handleCancelTextLabel = () => {
196-
setEditingTextLabel(null);
197-
setEditingTextLabelValue('');
198-
};
199-
200144
const handleDeleteTextStep = (textId: number) => {
201145
const textStep = browserSteps.find(step => step.id === textId);
202146
const actionId = textStep?.actionId;
@@ -210,36 +154,36 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
210154
}
211155
};
212156

213-
const handleStartEditScreenshotName = (screenshotStepId: number, currentName: string) => {
214-
setEditingScreenshotName(screenshotStepId);
215-
setEditingScreenshotNameValue(currentName);
157+
const startEdit = (stepId: number, type: 'list' | 'text' | 'screenshot', currentValue: string) => {
158+
setEditing({ stepId, type, value: currentValue });
216159
};
217160

218-
const handleSaveScreenshotName = () => {
219-
if (editingScreenshotName !== null) {
220-
const trimmedName = editingScreenshotNameValue.trim();
221-
const screenshotSteps = browserSteps.filter(step => step.type === 'screenshot');
222-
const screenshotIndex = screenshotSteps.findIndex(s => s.id === editingScreenshotName);
223-
const finalName = trimmedName || `Screenshot ${screenshotIndex + 1}`;
224-
225-
updateScreenshotStepName(editingScreenshotName, finalName);
226-
227-
const screenshotStep = browserSteps.find(step => step.id === editingScreenshotName);
228-
if (screenshotStep?.actionId) {
229-
const originalName = screenshotStep.name?.trim() || "";
230-
const trimmedName = editingScreenshotNameValue.trim();
231-
232-
// 🚫 Only emit if name actually changed
233-
if (trimmedName && trimmedName !== originalName) {
234-
setTimeout(() => emitForStepId(screenshotStep.actionId!), 500);
235-
} else {
236-
console.log("🧠 Skipping emit — screenshot name unchanged.");
237-
}
238-
}
161+
const saveEdit = () => {
162+
const { stepId, type, value } = editing;
163+
if (stepId == null || !type) return;
239164

240-
setEditingScreenshotName(null);
241-
setEditingScreenshotNameValue('');
165+
const finalValue = value.trim();
166+
if (!finalValue) {
167+
setEditing({ stepId: null, type: null, value: '' });
168+
return;
242169
}
170+
171+
if (type === 'list') {
172+
updateListStepName(stepId, finalValue);
173+
} else if (type === 'text') {
174+
updateBrowserTextStepLabel(stepId, finalValue);
175+
} else if (type === 'screenshot') {
176+
updateScreenshotStepName(stepId, finalValue);
177+
}
178+
179+
const step = browserSteps.find(s => s.id === stepId);
180+
if (step?.actionId) setTimeout(() => emitForStepId(step.actionId!), 0);
181+
182+
setEditing({ stepId: null, type: null, value: '' });
183+
};
184+
185+
const cancelEdit = () => {
186+
setEditing({ stepId: null, type: null, value: '' });
243187
};
244188

245189

@@ -354,8 +298,6 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
354298

355299
useEffect(() => {
356300
let shouldOpenDrawer = false;
357-
let switchToTextTab = false;
358-
let switchToScreenshotTab = false;
359301

360302
if (hasScrapeListAction && captureListData.length > 0 && captureListData[0]?.data?.length > 0) {
361303
setShowPreviewData(true);
@@ -371,7 +313,6 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
371313
if (captureTextData.length > lastTextDataLength.current) {
372314
userClosedDrawer.current = false;
373315
shouldOpenDrawer = true;
374-
switchToTextTab = true;
375316
}
376317
lastTextDataLength.current = captureTextData.length;
377318
}
@@ -381,23 +322,35 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
381322
if (screenshotData.length > lastScreenshotDataLength.current) {
382323
userClosedDrawer.current = false;
383324
shouldOpenDrawer = true;
384-
switchToScreenshotTab = true;
385325
}
386326
lastScreenshotDataLength.current = screenshotData.length;
387327
}
388328

329+
const getLatestCaptureType = () => {
330+
for (let i = browserSteps.length - 1; i >= 0; i--) {
331+
const type = browserSteps[i].type;
332+
if (type === "list" || type === "text" || type === "screenshot") {
333+
return type;
334+
}
335+
}
336+
return null;
337+
};
338+
389339
if (shouldOpenDrawer) {
390340
setIsOpen(true);
391-
if (switchToTextTab) {
392-
setTimeout(() => {
393-
const textTabIndex = getAvailableTabs().findIndex(tab => tab.id === 'captureText');
394-
if (textTabIndex !== -1) {
395-
setActiveTab(textTabIndex);
396-
}
397-
}, 100);
398-
} else if (switchToScreenshotTab) {
399-
setTimeout(() => {
400-
const screenshotTabIndex = getAvailableTabs().findIndex(tab => tab.id === 'captureScreenshot');
341+
const latestType = getLatestCaptureType();
342+
343+
setTimeout(() => {
344+
if (latestType === "text") {
345+
const idx = getAvailableTabs().findIndex(t => t.id === "captureText");
346+
if (idx !== -1) setActiveTab(idx);
347+
348+
} else if (latestType === "list") {
349+
const idx = getAvailableTabs().findIndex(t => t.id === "captureList");
350+
if (idx !== -1) setActiveTab(idx);
351+
352+
} else if (latestType === "screenshot") {
353+
const screenshotTabIndex = getAvailableTabs().findIndex(tab => tab.id === "captureScreenshot");
401354
if (screenshotTabIndex !== -1) {
402355
setActiveTab(screenshotTabIndex);
403356
const latestIndex = screenshotData.length - 1;
@@ -406,25 +359,25 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
406359
if (!autoFocusedScreenshotIndices.current.has(latestIndex)) {
407360
autoFocusedScreenshotIndices.current.add(latestIndex);
408361
setTimeout(() => {
409-
const screenshotSteps = browserSteps.filter(step => step.type === 'screenshot') as Array<{ id: number; name?: string; type: 'screenshot' }>;
362+
const screenshotSteps = browserSteps.filter(step => step.type === "screenshot");
410363
const latestScreenshotStep = screenshotSteps[latestIndex];
411364
if (latestScreenshotStep) {
412365
const screenshotName = latestScreenshotStep.name || `Screenshot ${latestIndex + 1}`;
413-
handleStartEditScreenshotName(latestScreenshotStep.id, screenshotName);
366+
startEdit(latestScreenshotStep.id, 'screenshot', screenshotName);
414367
}
415368
}, 300);
416369
}
417370
}
418-
}, 100);
419-
}
371+
}
372+
}, 100);
420373
}
421374
}, [hasScrapeListAction, hasScrapeSchemaAction, hasScreenshotAction, captureListData, captureTextData, screenshotData, setIsOpen, getText]);
422375

423376
useEffect(() => {
424377
if (captureListData.length > 0 && isOpen && captureStage === 'initial') {
425378
const latestListIndex = captureListData.length - 1;
426379
const latestList = captureListData[latestListIndex];
427-
if (latestList && latestList.data && latestList.data.length > 0 && !editingListName) {
380+
if (latestList && latestList.data && latestList.data.length > 0 && editing.type !== 'list') {
428381
const previousLength = previousDataLengths.current.get(latestList.id) || 0;
429382
const currentLength = latestList.data.length;
430383

@@ -433,7 +386,7 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
433386
autoFocusedListIds.current.add(latestList.id);
434387
setActiveListTab(latestListIndex);
435388
setTimeout(() => {
436-
handleStartEditListName(latestList.id, latestList.name || `List Data ${latestListIndex + 1}`);
389+
startEdit(latestList.id, 'list', latestList.name || `List Data ${latestListIndex + 1}`);
437390
}, 300);
438391
}
439392
}
@@ -579,7 +532,7 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
579532
}}
580533
>
581534
{captureListData.map((listItem, index) => {
582-
const isEditing = editingListName === listItem.id;
535+
const isEditing = editing.stepId === listItem.id && editing.type === 'list';
583536
const isActive = activeListTab === index;
584537

585538
return (
@@ -597,10 +550,7 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
597550
}
598551
}}
599552
onDoubleClick={() => {
600-
handleStartEditListName(
601-
listItem.id,
602-
listItem.name || `List Data ${index + 1}`
603-
);
553+
startEdit(listItem.id, 'list', listItem.name || `List Data ${index + 1}`)
604554
}}
605555
sx={{
606556
px: 3,
@@ -638,15 +588,12 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
638588
>
639589
{isEditing ? (
640590
<TextField
641-
value={editingListNameValue}
642-
onChange={(e) => setEditingListNameValue(e.target.value)}
643-
onBlur={handleSaveListName}
591+
value={editing.value}
592+
onChange={(e) => setEditing({ ...editing, value: e.target.value })}
593+
onBlur={saveEdit}
644594
onKeyDown={(e) => {
645-
if (e.key === 'Enter') handleSaveListName();
646-
if (e.key === 'Escape') {
647-
setEditingListName(null);
648-
setEditingListNameValue('');
649-
}
595+
if (e.key === 'Enter') saveEdit();
596+
if (e.key === 'Escape') cancelEdit();
650597
}}
651598
autoFocus
652599
size="small"
@@ -842,7 +789,7 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
842789
if (!screenshotStep) return null;
843790

844791
const isActive = activeScreenshotTab === index;
845-
const isEditing = editingScreenshotName === screenshotStep.id;
792+
const isEditing = editing.stepId === screenshotStep.id && editing.type === 'screenshot';
846793
const screenshotName = screenshotStep.name || `Screenshot ${index + 1}`;
847794

848795
return (
@@ -858,9 +805,7 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
858805
setActiveScreenshotTab(index);
859806
}
860807
}}
861-
onDoubleClick={() => {
862-
handleStartEditScreenshotName(screenshotStep.id, screenshotName);
863-
}}
808+
onDoubleClick={() => startEdit(screenshotStep.id, 'screenshot', screenshotName)}
864809
sx={{
865810
px: 3,
866811
py: 1.25,
@@ -895,15 +840,12 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
895840
>
896841
{isEditing ? (
897842
<TextField
898-
value={editingScreenshotNameValue}
899-
onChange={(e) => setEditingScreenshotNameValue(e.target.value)}
900-
onBlur={handleSaveScreenshotName}
843+
value={editing.value}
844+
onChange={(e) => setEditing({ ...editing, value: e.target.value })}
845+
onBlur={saveEdit}
901846
onKeyDown={(e) => {
902-
if (e.key === 'Enter') handleSaveScreenshotName();
903-
if (e.key === 'Escape') {
904-
setEditingScreenshotName(null);
905-
setEditingScreenshotNameValue('');
906-
}
847+
if (e.key === 'Enter') saveEdit();
848+
if (e.key === 'Escape') cancelEdit();
907849
}}
908850
autoFocus
909851
size="small"
@@ -1059,7 +1001,7 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
10591001
</TableHead>
10601002
<TableBody>
10611003
{captureTextData.map((textStep: any, index) => {
1062-
const isEditing = editingTextLabel === textStep.id;
1004+
const isEditing = editing.stepId === textStep.id && editing.type === 'text';
10631005

10641006
return (
10651007
<TableRow
@@ -1083,12 +1025,12 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
10831025
{isEditing ? (
10841026
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, minWidth: '200px' }}>
10851027
<TextField
1086-
value={editingTextLabelValue}
1087-
onChange={(e) => setEditingTextLabelValue(e.target.value)}
1088-
onBlur={handleSaveTextLabel}
1028+
value={editing.value}
1029+
onChange={(e) => setEditing({ ...editing, value: e.target.value })}
1030+
onBlur={saveEdit}
10891031
onKeyDown={(e) => {
1090-
if (e.key === 'Enter') handleSaveTextLabel();
1091-
if (e.key === 'Escape') handleCancelTextLabel();
1032+
if (e.key === 'Enter') saveEdit();
1033+
if (e.key === 'Escape') cancelEdit();
10921034
}}
10931035
autoFocus
10941036
size="small"
@@ -1102,7 +1044,7 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
11021044
/>
11031045
<IconButton
11041046
size="small"
1105-
onClick={handleSaveTextLabel}
1047+
onClick={saveEdit}
11061048
sx={{
11071049
color: '#4caf50',
11081050
padding: '4px'
@@ -1124,7 +1066,7 @@ export const InterpretationLog: React.FC<InterpretationLogProps> = ({ isOpen, se
11241066
textDecoration: 'underline'
11251067
}
11261068
}}
1127-
onClick={() => handleStartEditTextLabel(textStep.id, textStep.label)}
1069+
onClick={() => startEdit(textStep.id, 'text', textStep.label)}
11281070
>
11291071
{textStep.label}
11301072
</Typography>

0 commit comments

Comments
 (0)