@@ -12,13 +12,15 @@ export namespace Configurations {
1212 temperature ?: number
1313 reasoning_effort ?: string
1414 cache_enabled ?: boolean
15+ is_pinned ?: boolean
1516 }
1617
1718 export type Props = {
1819 api_mode : 'edit-context' | 'code-completions'
1920 configurations : Configuration [ ]
2021 on_configuration_click : ( id : string ) => void
2122 on_reorder ?: ( configurations : Configuration [ ] ) => void
23+ on_toggle_pinned ?: ( id : string ) => void
2224 selected_configuration_id ?: string
2325 on_manage_configurations : ( ) => void
2426 is_collapsed : boolean
@@ -27,8 +29,83 @@ export namespace Configurations {
2729}
2830
2931export const Configurations : React . FC < Configurations . Props > = ( props ) => {
32+ const pinned_configurations = props . configurations . filter ( ( c ) => c . is_pinned )
33+ const unpinned_configurations = props . configurations . filter (
34+ ( c ) => ! c . is_pinned
35+ )
36+
37+ const renderConfigurationItem = (
38+ configuration : Configurations . Configuration
39+ ) => {
40+ const description_parts = [ configuration . provider ]
41+ if ( configuration . reasoning_effort ) {
42+ description_parts . push ( `${ configuration . reasoning_effort } ` )
43+ }
44+ if (
45+ configuration . temperature &&
46+ configuration . temperature != DEFAULT_TEMPERATURE [ props . api_mode ]
47+ ) {
48+ description_parts . push ( `${ configuration . temperature } ` )
49+ }
50+ if ( configuration . cache_enabled ) {
51+ description_parts . push ( 'cache-enabled' )
52+ }
53+
54+ const description = description_parts . join ( ' · ' )
55+
56+ return (
57+ < div
58+ key = { configuration . id }
59+ className = { cn ( styles . configurations__item , {
60+ [ styles [ 'configurations__item--highlighted' ] ] :
61+ props . selected_configuration_id == configuration . id
62+ } ) }
63+ onClick = { ( ) => {
64+ props . on_configuration_click ( configuration . id )
65+ } }
66+ role = "button"
67+ >
68+ < div className = { styles . configurations__item__left } >
69+ < div
70+ className = { cn ( styles . configurations__item__left__drag_handle , {
71+ [ styles [ 'configurations__item__left__drag_handle--disabled' ] ] :
72+ ! props . on_reorder || configuration . is_pinned
73+ } ) }
74+ onClick = { ( e ) => e . stopPropagation ( ) }
75+ >
76+ < span className = "codicon codicon-gripper" />
77+ </ div >
78+ < div className = { styles . configurations__item__left__text } >
79+ < span > { configuration . model } </ span >
80+ < span > { description } </ span >
81+ </ div >
82+ </ div >
83+ { props . on_toggle_pinned && (
84+ < div
85+ className = { styles . configurations__item__right }
86+ onClick = { ( e ) => e . stopPropagation ( ) }
87+ >
88+ < IconButton
89+ codicon_icon = { configuration . is_pinned ? 'pinned' : 'pin' }
90+ title = { configuration . is_pinned ? 'Unpin' : 'Pin' }
91+ on_click = { ( e ) => {
92+ e . stopPropagation ( )
93+ props . on_toggle_pinned ?.( configuration . id )
94+ } }
95+ />
96+ </ div >
97+ ) }
98+ </ div >
99+ )
100+ }
101+
30102 return (
31103 < div className = { styles . container } >
104+ { pinned_configurations . length > 0 && (
105+ < div className = { styles . configurations } >
106+ { pinned_configurations . map ( renderConfigurationItem ) }
107+ </ div >
108+ ) }
32109 < div
33110 className = { styles . header }
34111 onClick = { ( ) => props . on_toggle_collapsed ( ! props . is_collapsed ) }
@@ -58,68 +135,17 @@ export const Configurations: React.FC<Configurations.Props> = (props) => {
58135 < >
59136 < div className = { styles . configurations } >
60137 < ReactSortable
61- list = { props . configurations }
138+ list = { unpinned_configurations }
62139 setList = { ( new_state ) => {
63140 if ( props . on_reorder ) {
64- props . on_reorder ( new_state )
141+ props . on_reorder ( [ ... pinned_configurations , ... new_state ] )
65142 }
66143 } }
67144 animation = { 150 }
68145 handle = { `.${ styles . configurations__item__left__drag_handle } ` }
69146 disabled = { ! props . on_reorder }
70147 >
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- }
86-
87- const description = description_parts . join ( ' · ' )
88-
89- return (
90- < div
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"
100- >
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 >
120- </ div >
121- )
122- } ) }
148+ { unpinned_configurations . map ( renderConfigurationItem ) }
123149 </ ReactSortable >
124150 </ div >
125151 </ >
0 commit comments