Skip to content

Commit 085190e

Browse files
committed
Refactor ResponsePreview to manage text item expansion state and apply Scrollable wrapper, while removing redundant Scrollable usage from Page
1 parent 01cde41 commit 085190e

5 files changed

Lines changed: 178 additions & 149 deletions

File tree

‎packages/ui/src/components/editor/panel/Page/Page.tsx‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import styles from './Page.module.scss'
2-
import { Scrollable } from '../Scrollable'
32
import { IconButton } from '../IconButton'
43

54
type Props = {
@@ -28,7 +27,7 @@ export const Page: React.FC<Props> = (props) => {
2827
</div>
2928
<div>{props.header_slot}</div>
3029
</div>
31-
<Scrollable>{props.children}</Scrollable>
30+
{props.children}
3231
{props.footer_slot && (
3332
<div className={styles.footer}>{props.footer_slot}</div>
3433
)}

‎packages/ui/src/components/editor/panel/ResponsePreview/ResponsePreview.module.scss‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
border: 1px solid var(--vscode-sideBarSectionHeader-border);
1313
opacity: var(--dimmed-opacity);
1414
margin: 0 var(--padding-12px);
15-
border-radius: var(--border-radius-5px);
15+
border-radius: var(--border-radius-8px);
1616

1717
> span {
1818
vertical-align: middle;

‎packages/ui/src/components/editor/panel/ResponsePreview/ResponsePreview.tsx‎

Lines changed: 164 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import styles from './ResponsePreview.module.scss'
55
import { Checkbox } from '../../common/Checkbox'
66
import { IconButton } from '../IconButton/IconButton'
77
import { TextItem } from './components'
8+
import { Scrollable } from '../Scrollable'
89

910
type Props = {
1011
items: ItemInPreview[]
@@ -25,163 +26,190 @@ type Props = {
2526

2627
export const ResponsePreview: FC<Props> = (props) => {
2728
const [last_clicked_file_index, set_last_clicked_file_index] = useState(0)
29+
const [expanded_text_items, set_expanded_text_items] = useState<Set<number>>(
30+
new Set()
31+
)
32+
33+
const toggle_expanded_text_item = (index: number) => {
34+
set_expanded_text_items((prev) => {
35+
const new_set = new Set(prev)
36+
if (new_set.has(index)) {
37+
new_set.delete(index)
38+
} else {
39+
new_set.add(index)
40+
}
41+
return new_set
42+
})
43+
}
2844

2945
const files_in_preview = props.items.filter(
3046
(i) => 'file_path' in i
3147
) as FileInPreview[]
3248
const fallback_count = files_in_preview.filter((f) => f.is_fallback).length
3349

3450
return (
35-
<div className={styles.container}>
36-
{props.raw_instructions && (
37-
<div className={styles.instructions} title={props.raw_instructions}>
38-
{props.raw_instructions}
39-
</div>
40-
)}
41-
{fallback_count > 0 && (
42-
<div className={styles.info}>
43-
{files_in_preview.length > 1
44-
? `${fallback_count} of ${files_in_preview.length} files`
45-
: 'The file'}{' '}
46-
required a fallback diff integration method, which may lead to
47-
inaccuracies. Looks off? Click{' '}
48-
<span className="codicon codicon-sparkle" /> action to fix a file with
49-
the Intelligent Update API tool.
50-
</div>
51-
)}
52-
<div className={styles.list}>
53-
{props.items.map((item, index) => {
54-
if ('file_path' in item) {
55-
const file = item
56-
const last_slash_index = file.file_path.lastIndexOf('/')
57-
const file_name = file.file_path.substring(last_slash_index + 1)
58-
const dir_path =
59-
last_slash_index > -1
60-
? file.file_path.substring(0, last_slash_index)
61-
: ''
62-
return (
63-
<div
64-
key={index}
65-
className={cn(styles.list__file, {
66-
[styles['list__file--selected']]:
67-
index == last_clicked_file_index
68-
})}
69-
onClick={() => {
70-
set_last_clicked_file_index(index)
71-
props.on_focus_file({
72-
file_path: file.file_path,
73-
workspace_name: file.workspace_name
74-
})
75-
}}
76-
role="button"
77-
title={`${file.file_path}${
78-
file.diff_fallback_method == 'search_and_replace'
79-
? '\nUsed aggressive fallback method. Call Intelligent Update API tool, if needed.'
80-
: ''
81-
}`}
82-
>
83-
<div className={styles['list__file__left']}>
84-
{files_in_preview.length > 1 && (
85-
<Checkbox
86-
checked={file.is_checked}
87-
on_change={(checked) => {
88-
props.on_toggle_file({
89-
file_path: file.file_path,
90-
workspace_name: file.workspace_name,
91-
is_checked: checked
92-
})
93-
}}
94-
/>
95-
)}
96-
<div
97-
className={cn(styles['list__file__left__label'], {
98-
[styles['list__file__left__label--new']]: file.is_new,
99-
[styles['list__file__left__label--deleted']]:
100-
file.is_deleted
101-
})}
102-
>
103-
<span>
104-
{file.diff_fallback_method == 'search_and_replace' &&
105-
'⚠ '}
106-
{file_name}
107-
</span>
51+
<Scrollable key={expanded_text_items.size}>
52+
<div className={styles.container}>
53+
{props.raw_instructions && (
54+
<div className={styles.instructions} title={props.raw_instructions}>
55+
{props.raw_instructions}
56+
</div>
57+
)}
58+
{fallback_count > 0 && (
59+
<div className={styles.info}>
60+
{files_in_preview.length > 1
61+
? `${fallback_count} of ${files_in_preview.length} files`
62+
: 'The file'}{' '}
63+
required a fallback diff integration method, which may lead to
64+
inaccuracies. Looks off? Click{' '}
65+
<span className="codicon codicon-sparkle" /> action to fix a file
66+
with the Intelligent Update API tool.
67+
</div>
68+
)}
69+
<div className={styles.list}>
70+
{props.items.map((item, index) => {
71+
if ('file_path' in item) {
72+
const file = item
73+
const last_slash_index = file.file_path.lastIndexOf('/')
74+
const file_name = file.file_path.substring(last_slash_index + 1)
75+
const dir_path =
76+
last_slash_index > -1
77+
? file.file_path.substring(0, last_slash_index)
78+
: ''
79+
return (
80+
<div
81+
key={index}
82+
className={cn(styles.list__file, {
83+
[styles['list__file--selected']]:
84+
index == last_clicked_file_index
85+
})}
86+
onClick={() => {
87+
set_last_clicked_file_index(index)
88+
props.on_focus_file({
89+
file_path: file.file_path,
90+
workspace_name: file.workspace_name
91+
})
92+
}}
93+
role="button"
94+
title={`${file.file_path}${
95+
file.diff_fallback_method == 'search_and_replace'
96+
? '\nUsed aggressive fallback method. Call Intelligent Update API tool, if needed.'
97+
: ''
98+
}`}
99+
>
100+
<div className={styles['list__file__left']}>
101+
{files_in_preview.length > 1 && (
102+
<Checkbox
103+
checked={file.is_checked}
104+
on_change={(checked) => {
105+
props.on_toggle_file({
106+
file_path: file.file_path,
107+
workspace_name: file.workspace_name,
108+
is_checked: checked
109+
})
110+
}}
111+
/>
112+
)}
113+
<div
114+
className={cn(styles['list__file__left__label'], {
115+
[styles['list__file__left__label--new']]: file.is_new,
116+
[styles['list__file__left__label--deleted']]:
117+
file.is_deleted
118+
})}
119+
>
120+
<span>
121+
{file.diff_fallback_method == 'search_and_replace' &&
122+
'⚠ '}
123+
{file_name}
124+
</span>
108125

109-
<span>
110-
{props.has_multiple_workspaces && file.workspace_name
111-
? `${file.workspace_name}/`
112-
: ''}
113-
{dir_path}
114-
</span>
126+
<span>
127+
{props.has_multiple_workspaces && file.workspace_name
128+
? `${file.workspace_name}/`
129+
: ''}
130+
{dir_path}
131+
</span>
132+
</div>
115133
</div>
116-
</div>
117-
<div className={styles.list__file__right}>
118-
<div className={styles['list__file__actions']}>
119-
{(file.is_fallback || file.is_replaced) && (
134+
<div className={styles.list__file__right}>
135+
<div className={styles['list__file__actions']}>
136+
{(file.is_fallback || file.is_replaced) && (
137+
<IconButton
138+
codicon_icon="sparkle"
139+
title={`Call Intelligent Update API tool${
140+
file.diff_fallback_method == 'recount'
141+
? ' (fallback used: git apply with --recount flag)'
142+
: file.diff_fallback_method ==
143+
'search_and_replace'
144+
? ' (fallback used: search and replace matching fragments)'
145+
: ''
146+
}`}
147+
on_click={(e) => {
148+
e.stopPropagation()
149+
set_last_clicked_file_index(index)
150+
props.on_intelligent_update({
151+
file_path: file.file_path,
152+
workspace_name: file.workspace_name
153+
})
154+
}}
155+
/>
156+
)}
120157
<IconButton
121-
codicon_icon="sparkle"
122-
title={`Call Intelligent Update API tool${
123-
file.diff_fallback_method == 'recount'
124-
? ' (fallback used: git apply with --recount flag)'
125-
: file.diff_fallback_method == 'search_and_replace'
126-
? ' (fallback used: search and replace matching fragments)'
127-
: ''
128-
}`}
158+
codicon_icon="diff-single"
159+
title="Open Changes"
129160
on_click={(e) => {
130161
e.stopPropagation()
131162
set_last_clicked_file_index(index)
132-
props.on_intelligent_update({
163+
props.on_focus_file({
133164
file_path: file.file_path,
134165
workspace_name: file.workspace_name
135166
})
136167
}}
137168
/>
169+
<IconButton
170+
codicon_icon="go-to-file"
171+
title="Go To File"
172+
on_click={(e) => {
173+
e.stopPropagation()
174+
props.on_go_to_file({
175+
file_path: file.file_path,
176+
workspace_name: file.workspace_name
177+
})
178+
}}
179+
/>
180+
</div>
181+
{!file.is_deleted && (
182+
<div className={styles['list__file__line-numbers']}>
183+
<span
184+
className={styles['list__file__line-numbers__added']}
185+
>
186+
+{file.lines_added}
187+
</span>
188+
<span
189+
className={
190+
styles['list__file__line-numbers__removed']
191+
}
192+
>
193+
-{file.lines_removed}
194+
</span>
195+
</div>
138196
)}
139-
<IconButton
140-
codicon_icon="diff-single"
141-
title="Open Changes"
142-
on_click={(e) => {
143-
e.stopPropagation()
144-
set_last_clicked_file_index(index)
145-
props.on_focus_file({
146-
file_path: file.file_path,
147-
workspace_name: file.workspace_name
148-
})
149-
}}
150-
/>
151-
<IconButton
152-
codicon_icon="go-to-file"
153-
title="Go To File"
154-
on_click={(e) => {
155-
e.stopPropagation()
156-
props.on_go_to_file({
157-
file_path: file.file_path,
158-
workspace_name: file.workspace_name
159-
})
160-
}}
161-
/>
162197
</div>
163-
{!file.is_deleted && (
164-
<div className={styles['list__file__line-numbers']}>
165-
<span
166-
className={styles['list__file__line-numbers__added']}
167-
>
168-
+{file.lines_added}
169-
</span>
170-
<span
171-
className={styles['list__file__line-numbers__removed']}
172-
>
173-
-{file.lines_removed}
174-
</span>
175-
</div>
176-
)}
177198
</div>
178-
</div>
179-
)
180-
} else {
181-
return <TextItem key={index} content={item.content} />
182-
}
183-
})}
199+
)
200+
} else {
201+
return (
202+
<TextItem
203+
key={index}
204+
content={item.content}
205+
is_expanded={expanded_text_items.has(index)}
206+
on_toggle={() => toggle_expanded_text_item(index)}
207+
/>
208+
)
209+
}
210+
})}
211+
</div>
184212
</div>
185-
</div>
213+
</Scrollable>
186214
)
187215
}

‎packages/ui/src/components/editor/panel/ResponsePreview/components/TextItem.module.scss‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
> * {
1111
margin: 0;
12-
font-size: var(--font-size-12px);
12+
font-size: var(--font-size-13px);
1313
}
1414
> * + * {
1515
margin-top: 0.5em;
@@ -29,6 +29,11 @@
2929
max-height: 50px;
3030
overflow: hidden;
3131
position: relative;
32+
33+
> * {
34+
margin: 0;
35+
font-size: var(--font-size-12px);
36+
}
3237
}
3338

3439
&--expandable {

0 commit comments

Comments
 (0)