11import { useRef , useState } from "react" ;
2+ import { Icon } from "@iconify/react" ;
23import { Modal } from "../../../components/modal" ;
34import { SettingsSectionContainer , SettingsSectionTitle } from "./components" ;
4- import { Button } from "@heroui/react" ;
5+ import { Button , Tooltip } from "@heroui/react" ;
56import { useSettingStore } from "../../../stores/setting-store" ;
67import { useLanguageModels } from "../../../hooks/useLanguageModels" ;
78
@@ -101,20 +102,21 @@ type CustomModelSectionProps = NewCustomModelSectionProps | ExistingCustomModelS
101102
102103const CustomModelSection = ( { isNew, onChange, model : customModel } : CustomModelSectionProps ) => {
103104 const { models } = useLanguageModels ( ) ;
105+ const { settings } = useSettingStore ( ) ;
104106
105107 const [ isEditing , setIsEditing ] = useState ( isNew ) ;
106- const [ modelName , setModelName ] = useState ( isNew ? "New Model" : customModel . name ) ;
107108 const [ baseUrl , setBaseUrl ] = useState ( customModel ?. baseUrl || "" ) ;
108109 const [ slug , setSlug ] = useState ( customModel ?. slug || "" ) ;
109110 const [ apiKey , setApiKey ] = useState ( customModel ?. apiKey || "" ) ;
110111 const [ contextWindow , setContextWindow ] = useState < number > ( customModel ?. contextWindow || 0 ) ;
111112 const [ maxOutput , setMaxOutput ] = useState < number > ( customModel ?. maxOutput || 0 ) ;
112113 const [ inputPrice , setInputPrice ] = useState < number > ( customModel ?. inputPrice || 0 ) ;
113114 const [ outputPrice , setOutputPrice ] = useState < number > ( customModel ?. outputPrice || 0 ) ;
115+ const [ modelName , setModelName ] = useState ( isNew ? models [ 0 ] . name : customModel . name ) ;
114116 const isModelNameEdited = useRef ( false ) ;
115117
116118 const baseInputClassName = "hover:cursor-pointer bg-transparent p-1 focus:outline-none" ;
117- const nameInputClassName = `${ baseInputClassName } text-sm text-default-900 font-bold ` ;
119+ const nameInputClassName = `${ baseInputClassName } text-sm text-default-900 font-medium ` ;
118120 const labelClassName = `${ baseInputClassName } text-xs text-default-900 w-auto` ;
119121 const detailInputClassName = `${ baseInputClassName } text-xs text-default-400 font-normal flex-1` ;
120122
@@ -137,7 +139,7 @@ const CustomModelSection = ({ isNew, onChange, model: customModel }: CustomModel
137139 ) ;
138140
139141 if ( isNew ) {
140- setModelName ( "New Model" ) ;
142+ setModelName ( models [ 0 ] . name ) ;
141143 setBaseUrl ( "" ) ;
142144 setSlug ( "" ) ;
143145 setApiKey ( "" ) ;
@@ -148,89 +150,102 @@ const CustomModelSection = ({ isNew, onChange, model: customModel }: CustomModel
148150 }
149151 } ;
150152
151- // TODO: 1 key per model
152153 // TODO: Multiple models per key
153154 return (
154- < div className = "flex flex-col w-full" >
155- { isNew ? (
156- < Button size = "sm" onPress = { ( ) => handleOnChange ( false ) } >
157- Add (TODO)
158- </ Button >
159- ) : (
160- < >
161- < Button size = "sm" onPress = { ( ) => handleOnChange ( true ) } >
162- Delete (TODO)
163- </ Button >
164- < Button size = "sm" onPress = { ( ) => setIsEditing ( true ) } >
165- Edit (TODO)
166- </ Button >
167- < Button
168- size = "sm"
169- onPress = { ( ) => {
170- setIsEditing ( false ) ;
171- handleOnChange ( false ) ;
172- } }
173- >
174- Save (TODO)
175- </ Button >
176- </ >
177- ) }
178-
179- < input
180- className = { nameInputClassName }
181- value = { modelName }
182- type = "text"
183- disabled = { ! isEditing }
184- onChange = { ( e ) => {
185- isModelNameEdited . current = true ;
186- setModelName ( e . target . value ) ;
187- } }
188- > </ input >
189-
190- < div className = "flex flex-row" >
191- < label className = { labelClassName } > Slug</ label >
192- < select
193- className = { detailInputClassName }
155+ < div className = "flex flex-col w-full pl-1" >
156+ < div className = "flex flex-row justify-between" >
157+ < input
158+ className = { nameInputClassName }
159+ value = { modelName }
160+ type = "text"
194161 disabled = { ! isEditing }
195162 onChange = { ( e ) => {
196- setSlug ( e . target . value ) ;
197- if ( ! isModelNameEdited . current ) {
198- // Custom name not yet defined, default to the selected model's name
199- setModelName ( models . filter ( ( m ) => m . slug == e . target . value ) [ 0 ] . name ) ;
200- }
163+ isModelNameEdited . current = true ;
164+ setModelName ( e . target . value ) ;
201165 } }
202- >
203- { models . map ( ( m ) => (
204- < option selected = { slug == m . slug } key = { m . slug } value = { m . slug } >
205- { m . slug }
206- </ option >
207- ) ) }
208- </ select >
209- </ div >
166+ > </ input >
210167
211- < div className = "flex flex-row" >
212- < label className = { labelClassName } > Base URL</ label >
213- < input
214- className = { detailInputClassName }
215- value = { baseUrl }
216- type = "text"
217- disabled = { ! isEditing }
218- onChange = { ( e ) => setBaseUrl ( e . target . value ) }
219- />
168+ { isNew ? (
169+ < Tooltip content = "Add" placement = "bottom" className = "noselect" delay = { 500 } >
170+ < button onClick = { ( ) => handleOnChange ( false ) } className = "p-1 hover:bg-default-100 rounded" >
171+ < Icon icon = "tabler:device-floppy" width = "16" />
172+ </ button >
173+ </ Tooltip >
174+ ) : (
175+ < div >
176+ < Tooltip content = "Edit" placement = "bottom" className = "noselect" delay = { 500 } >
177+ < button
178+ onClick = { ( ) => {
179+ if ( isEditing ) {
180+ handleOnChange ( false ) ;
181+ }
182+ setIsEditing ( ( i ) => ! i ) ;
183+ } }
184+ className = "p-1 hover:bg-default-100 rounded"
185+ >
186+ < Icon icon = { isEditing ? "tabler:device-floppy" : "tabler:pencil" } width = "16" />
187+ </ button >
188+ </ Tooltip >
189+ < Tooltip content = "Delete" placement = "bottom" className = "noselect" delay = { 500 } >
190+ < button onClick = { ( ) => handleOnChange ( true ) } className = "p-1 hover:bg-default-100 rounded" >
191+ < Icon icon = "tabler:trash" width = "16" />
192+ </ button >
193+ </ Tooltip >
194+ </ div >
195+ ) }
220196 </ div >
221197
222- < div className = "flex flex-row" >
223- < label className = { labelClassName } > API Key</ label >
224- < input
225- className = { detailInputClassName }
226- value = { apiKey }
227- type = "text"
228- disabled = { ! isEditing }
229- onChange = { ( e ) => setApiKey ( e . target . value ) }
230- />
231- </ div >
198+ < div className = "pr-1" >
199+ < div className = "flex flex-row" >
200+ < label className = { labelClassName } > Slug</ label >
201+ < select
202+ className = { detailInputClassName }
203+ disabled = { ! isEditing }
204+ onChange = { ( e ) => {
205+ setSlug ( e . target . value ) ;
206+ if ( ! isModelNameEdited . current ) {
207+ // Custom name not yet defined, default to the selected model's name
208+ setModelName ( models . filter ( ( m ) => m . slug == e . target . value ) [ 0 ] . name ) ;
209+ }
210+ } }
211+ >
212+ { models
213+ . filter (
214+ ( m ) =>
215+ ( ! isNew && m . slug == slug ) ||
216+ ! Array . from ( settings ?. customModels || [ ] ) . some ( ( cm ) => cm . slug == m . slug ) ,
217+ )
218+ . map ( ( m ) => (
219+ < option selected = { slug == m . slug } key = { m . slug } value = { m . slug } >
220+ { m . slug }
221+ </ option >
222+ ) ) }
223+ </ select >
224+ </ div >
232225
233- < div className = "flex flex-row" >
226+ < div className = "flex flex-row" >
227+ < label className = { labelClassName } > Base URL</ label >
228+ < input
229+ className = { detailInputClassName }
230+ value = { baseUrl }
231+ type = "text"
232+ disabled = { ! isEditing }
233+ onChange = { ( e ) => setBaseUrl ( e . target . value ) }
234+ />
235+ </ div >
236+
237+ < div className = "flex flex-row" >
238+ < label className = { labelClassName } > API Key</ label >
239+ < input
240+ className = { detailInputClassName }
241+ value = { apiKey }
242+ type = { ! isEditing && ! isNew ? "password" : "text" }
243+ disabled = { ! isEditing }
244+ onChange = { ( e ) => setApiKey ( e . target . value ) }
245+ />
246+ </ div >
247+
248+ { /* <div className="flex flex-row">
234249 <label className={labelClassName}>Context Window</label>
235250 <input
236251 className={detailInputClassName}
@@ -272,6 +287,7 @@ const CustomModelSection = ({ isNew, onChange, model: customModel }: CustomModel
272287 disabled={!isEditing}
273288 onChange={(e) => setOutputPrice(e.target.valueAsNumber)}
274289 />
290+ </div> */ }
275291 </ div >
276292 </ div >
277293 ) ;
0 commit comments