Skip to content

Commit 549be80

Browse files
committed
Implement collapsible sections for Presets and Configurations in the panel UI, persisting their collapsed state globally
1 parent 3dcecae commit 549be80

13 files changed

Lines changed: 528 additions & 303 deletions

File tree

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,29 @@
33
flex-direction: column;
44
}
55

6+
.header {
7+
height: var(--list-item-height);
8+
padding: 0 var(--padding-12px);
9+
display: flex;
10+
justify-content: space-between;
11+
align-items: center;
12+
cursor: pointer;
13+
14+
&:hover {
15+
background-color: var(--vscode-list-hoverBackground);
16+
}
17+
18+
&__left {
19+
display: flex;
20+
align-items: center;
21+
gap: var(--padding-4px);
22+
}
23+
24+
&__right {
25+
display: flex;
26+
}
27+
}
28+
629
.missing-config {
730
padding: var(--padding-2px) var(--padding-12px) 0 var(--padding-12px);
831
font-weight: 500;

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

Lines changed: 93 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import styles from './Configurations.module.scss'
22
import { DEFAULT_TEMPERATURE } from '@shared/constants/api-tools'
33
import cn from 'classnames'
44
import { ReactSortable } from 'react-sortablejs'
5-
import { Button } from '../Button/Button'
5+
import { IconButton } from '../IconButton/IconButton'
66

77
export namespace Configurations {
88
export type Configuration = {
@@ -21,82 +21,109 @@ export namespace Configurations {
2121
on_reorder?: (configurations: Configuration[]) => void
2222
selected_configuration_id?: string
2323
on_manage_configurations: () => void
24+
is_collapsed: boolean
25+
on_toggle_collapsed: (is_collapsed: boolean) => void
2426
}
2527
}
2628

2729
export const Configurations: React.FC<Configurations.Props> = (props) => {
2830
return (
2931
<div className={styles.container}>
30-
<div className={styles.configurations}>
31-
<ReactSortable
32-
list={props.configurations}
33-
setList={(new_state) => {
34-
if (props.on_reorder) {
35-
props.on_reorder(new_state)
36-
}
37-
}}
38-
animation={150}
39-
handle={`.${styles.configurations__item__left__drag_handle}`}
40-
disabled={!props.on_reorder}
41-
>
42-
{props.configurations.map((configuration) => {
43-
const description_parts = [configuration.provider]
44-
if (configuration.reasoning_effort) {
45-
description_parts.push(`${configuration.reasoning_effort}`)
46-
}
47-
if (
48-
configuration.temperature &&
49-
configuration.temperature != DEFAULT_TEMPERATURE[props.api_mode]
50-
) {
51-
description_parts.push(`${configuration.temperature}`)
52-
}
53-
if (configuration.cache_enabled) {
54-
description_parts.push('cache-enabled')
55-
}
32+
<div
33+
className={styles.header}
34+
onClick={() => props.on_toggle_collapsed(!props.is_collapsed)}
35+
role="button"
36+
>
37+
<div className={styles.header__left}>
38+
<span
39+
className={cn('codicon', {
40+
'codicon-chevron-down': !props.is_collapsed,
41+
'codicon-chevron-right': props.is_collapsed
42+
})}
43+
/>
44+
<span>Configurations</span>
45+
</div>
46+
<div className={styles.header__right}>
47+
<IconButton
48+
codicon_icon="edit"
49+
on_click={(e) => {
50+
e.stopPropagation()
51+
props.on_manage_configurations()
52+
}}
53+
title="Edit Configurations"
54+
/>
55+
</div>
56+
</div>
57+
{!props.is_collapsed && (
58+
<>
59+
<div className={styles.configurations}>
60+
<ReactSortable
61+
list={props.configurations}
62+
setList={(new_state) => {
63+
if (props.on_reorder) {
64+
props.on_reorder(new_state)
65+
}
66+
}}
67+
animation={150}
68+
handle={`.${styles.configurations__item__left__drag_handle}`}
69+
disabled={!props.on_reorder}
70+
>
71+
{props.configurations.map((configuration) => {
72+
const description_parts = [configuration.provider]
73+
if (configuration.reasoning_effort) {
74+
description_parts.push(`${configuration.reasoning_effort}`)
75+
}
76+
if (
77+
configuration.temperature &&
78+
configuration.temperature !=
79+
DEFAULT_TEMPERATURE[props.api_mode]
80+
) {
81+
description_parts.push(`${configuration.temperature}`)
82+
}
83+
if (configuration.cache_enabled) {
84+
description_parts.push('cache-enabled')
85+
}
5686

57-
const description = description_parts.join(' · ')
87+
const description = description_parts.join(' · ')
5888

59-
return (
60-
<div
61-
key={configuration.id}
62-
className={cn(styles.configurations__item, {
63-
[styles['configurations__item--highlighted']]:
64-
props.selected_configuration_id == configuration.id
65-
})}
66-
onClick={() => {
67-
props.on_configuration_click(configuration.id)
68-
}}
69-
role="button"
70-
>
71-
<div className={styles.configurations__item__left}>
89+
return (
7290
<div
73-
className={cn(
74-
styles.configurations__item__left__drag_handle,
75-
{
76-
[styles[
77-
'configurations__item__left__drag_handle--disabled'
78-
]]: !props.on_reorder
79-
}
80-
)}
81-
onClick={(e) => e.stopPropagation()}
91+
key={configuration.id}
92+
className={cn(styles.configurations__item, {
93+
[styles['configurations__item--highlighted']]:
94+
props.selected_configuration_id == configuration.id
95+
})}
96+
onClick={() => {
97+
props.on_configuration_click(configuration.id)
98+
}}
99+
role="button"
82100
>
83-
<span className="codicon codicon-gripper" />
84-
</div>
85-
<div className={styles.configurations__item__left__text}>
86-
<span>{configuration.model}</span>
87-
<span>{description}</span>
101+
<div className={styles.configurations__item__left}>
102+
<div
103+
className={cn(
104+
styles.configurations__item__left__drag_handle,
105+
{
106+
[styles[
107+
'configurations__item__left__drag_handle--disabled'
108+
]]: !props.on_reorder
109+
}
110+
)}
111+
onClick={(e) => e.stopPropagation()}
112+
>
113+
<span className="codicon codicon-gripper" />
114+
</div>
115+
<div className={styles.configurations__item__left__text}>
116+
<span>{configuration.model}</span>
117+
<span>{description}</span>
118+
</div>
119+
</div>
88120
</div>
89-
</div>
90-
</div>
91-
)
92-
})}
93-
</ReactSortable>
94-
</div>
95-
<div className={styles.footer}>
96-
<Button on_click={props.on_manage_configurations}>
97-
Edit Configurations
98-
</Button>
99-
</div>
121+
)
122+
})}
123+
</ReactSortable>
124+
</div>
125+
</>
126+
)}
100127
</div>
101128
)
102129
}

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ export const Page: React.FC<Props> = (props) => {
2828
<div>{props.header_slot}</div>
2929
</div>
3030
{props.children}
31-
{props.footer_slot && (
32-
<div className={styles.footer}>{props.footer_slot}</div>
33-
)}
3431
</div>
3532
)
3633
}

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,29 @@
33
flex-direction: column;
44
}
55

6+
.header {
7+
height: var(--list-item-height);
8+
padding: 0 var(--padding-12px);
9+
display: flex;
10+
justify-content: space-between;
11+
align-items: center;
12+
cursor: pointer;
13+
14+
&:hover {
15+
background-color: var(--vscode-list-hoverBackground);
16+
}
17+
18+
&__left {
19+
display: flex;
20+
align-items: center;
21+
gap: var(--padding-4px);
22+
}
23+
24+
&__right {
25+
display: flex;
26+
}
27+
}
28+
629
.presets {
730
display: flex;
831
flex-direction: column;
@@ -92,7 +115,6 @@
92115
display: none;
93116
align-items: center;
94117
cursor: default;
95-
padding-right: var(--padding-4px);
96118
}
97119
}
98120
}

0 commit comments

Comments
 (0)