|
1 | 1 | <template> |
2 | | - <div class="mt-4"> |
3 | | - <div class="d-flex align-center ga-2 mb-2"> |
4 | | - <h3 class="text-h5 font-weight-bold mb-0">{{ tm('models.configured') }}</h3> |
5 | | - <small style="color: grey;" v-if="availableCount">{{ tm('models.available') }} {{ availableCount }}</small> |
| 2 | + <div class="provider-models-panel"> |
| 3 | + <div class="provider-models-head"> |
| 4 | + <div class="provider-models-title-wrap"> |
| 5 | + <h3 class="provider-models-title">{{ tm('models.configured') }}</h3> |
| 6 | + <small v-if="availableCount" class="provider-models-subtitle">{{ tm('models.available') }} {{ availableCount }}</small> |
| 7 | + </div> |
6 | 8 | <v-text-field |
7 | 9 | v-model="modelSearchProxy" |
8 | 10 | density="compact" |
|
11 | 13 | hide-details |
12 | 14 | variant="solo-filled" |
13 | 15 | flat |
14 | | - class="ml-1" |
15 | | - style="max-width: 240px;" |
| 16 | + class="provider-models-search" |
16 | 17 | :placeholder="tm('models.searchPlaceholder')" |
17 | 18 | /> |
18 | | - <v-spacer></v-spacer> |
19 | | - <v-btn |
20 | | - color="primary" |
21 | | - prepend-icon="mdi-download" |
22 | | - :loading="loadingModels" |
23 | | - @click="emit('fetch-models')" |
24 | | - variant="tonal" |
25 | | - size="small" |
26 | | - > |
27 | | - {{ isSourceModified ? tm('providerSources.saveAndFetchModels') : tm('providerSources.fetchModels') }} |
28 | | - </v-btn> |
29 | | - <v-btn |
30 | | - color="primary" |
31 | | - prepend-icon="mdi-pencil-plus" |
32 | | - variant="text" |
33 | | - size="small" |
34 | | - class="ml-1" |
35 | | - @click="emit('open-manual-model')" |
36 | | - > |
37 | | - {{ tm('models.manualAddButton') }} |
38 | | - </v-btn> |
| 19 | + <div class="provider-models-actions"> |
| 20 | + <v-btn |
| 21 | + color="primary" |
| 22 | + prepend-icon="mdi-download" |
| 23 | + :loading="loadingModels" |
| 24 | + @click="emit('fetch-models')" |
| 25 | + variant="tonal" |
| 26 | + size="small" |
| 27 | + > |
| 28 | + {{ isSourceModified ? tm('providerSources.saveAndFetchModels') : tm('providerSources.fetchModels') }} |
| 29 | + </v-btn> |
| 30 | + <v-btn |
| 31 | + color="primary" |
| 32 | + prepend-icon="mdi-pencil-plus" |
| 33 | + variant="text" |
| 34 | + size="small" |
| 35 | + @click="emit('open-manual-model')" |
| 36 | + > |
| 37 | + {{ tm('models.manualAddButton') }} |
| 38 | + </v-btn> |
| 39 | + </div> |
39 | 40 | </div> |
40 | 41 |
|
41 | 42 | <v-list |
42 | 43 | density="compact" |
43 | | - class="rounded-lg border" |
44 | | - style="max-height: 520px; overflow-y: auto; font-family:system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;" |
| 44 | + class="provider-models-list" |
45 | 45 | > |
46 | 46 | <template v-if="entries.length > 0"> |
47 | 47 | <template v-for="entry in entries" :key="entry.type === 'configured' ? `provider-${entry.provider.id}` : `model-${entry.model}`"> |
|
55 | 55 | <v-list-item-title class="font-weight-medium text-truncate"> |
56 | 56 | {{ entry.provider.id }} |
57 | 57 | </v-list-item-title> |
58 | | - <v-list-item-subtitle class="text-caption text-grey d-flex align-center ga-1" style="font-family: monospace;"> |
| 58 | + <v-list-item-subtitle class="provider-model-subtitle d-flex align-center ga-1"> |
59 | 59 | <span>{{ entry.provider.model }}</span> |
60 | 60 | <v-icon v-if="supportsImageInput(entry.metadata)" size="14" color="grey"> |
61 | 61 | mdi-eye-outline |
|
124 | 124 | <template #activator="{ props }"> |
125 | 125 | <v-list-item v-bind="props" class="cursor-pointer" @click="emit('add-model-provider', entry.model)"> |
126 | 126 | <v-list-item-title>{{ entry.model }}</v-list-item-title> |
127 | | - <v-list-item-subtitle class="text-caption text-grey d-flex align-center ga-1"> |
| 127 | + <v-list-item-subtitle class="provider-model-subtitle d-flex align-center ga-1"> |
128 | 128 | <span>{{ entry.model }}</span> |
129 | 129 | <v-icon v-if="supportsImageInput(entry.metadata)" size="14" color="grey"> |
130 | 130 | mdi-eye-outline |
@@ -231,11 +231,87 @@ const isProviderTesting = (providerId) => props.testingProviders.includes(provid |
231 | 231 | </script> |
232 | 232 |
|
233 | 233 | <style scoped> |
234 | | -.border { |
235 | | - border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity)); |
| 234 | +.provider-models-panel { |
| 235 | + display: grid; |
| 236 | + gap: 14px; |
| 237 | +} |
| 238 | +
|
| 239 | +.provider-models-head { |
| 240 | + display: flex; |
| 241 | + align-items: center; |
| 242 | + gap: 10px; |
| 243 | + flex-wrap: wrap; |
| 244 | +} |
| 245 | +
|
| 246 | +.provider-models-title-wrap { |
| 247 | + min-width: 0; |
| 248 | +} |
| 249 | +
|
| 250 | +.provider-models-title { |
| 251 | + margin: 0; |
| 252 | + font-size: 18px; |
| 253 | + line-height: 1.3; |
| 254 | + font-weight: 650; |
| 255 | +} |
| 256 | +
|
| 257 | +.provider-models-subtitle { |
| 258 | + display: block; |
| 259 | + margin-top: 6px; |
| 260 | + color: rgba(var(--v-theme-on-surface), 0.6); |
| 261 | + font-size: 12px; |
| 262 | +} |
| 263 | +
|
| 264 | +.provider-models-search { |
| 265 | + max-width: 240px; |
| 266 | +} |
| 267 | +
|
| 268 | +.provider-models-actions { |
| 269 | + margin-left: auto; |
| 270 | + display: flex; |
| 271 | + align-items: center; |
| 272 | + gap: 6px; |
| 273 | + flex-wrap: wrap; |
| 274 | +} |
| 275 | +
|
| 276 | +.provider-models-list { |
| 277 | + max-height: 520px; |
| 278 | + overflow-y: auto; |
| 279 | + border: 1px solid rgba(var(--v-theme-on-surface), 0.1); |
| 280 | + border-radius: 14px; |
| 281 | + background: rgb(var(--v-theme-surface)); |
| 282 | + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; |
| 283 | +} |
| 284 | +
|
| 285 | +.provider-compact-item { |
| 286 | + border-bottom: 1px solid rgba(var(--v-theme-on-surface), 0.08); |
| 287 | +} |
| 288 | +
|
| 289 | +.provider-models-list :deep(.v-list-item:last-child) { |
| 290 | + border-bottom: 0; |
| 291 | +} |
| 292 | +
|
| 293 | +.provider-model-subtitle { |
| 294 | + color: rgba(var(--v-theme-on-surface), 0.62); |
| 295 | + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; |
236 | 296 | } |
237 | 297 |
|
238 | 298 | .cursor-pointer { |
239 | 299 | cursor: pointer; |
240 | 300 | } |
| 301 | +
|
| 302 | +@media (max-width: 900px) { |
| 303 | + .provider-models-head { |
| 304 | + align-items: stretch; |
| 305 | + } |
| 306 | +
|
| 307 | + .provider-models-search { |
| 308 | + max-width: none; |
| 309 | + width: 100%; |
| 310 | + } |
| 311 | +
|
| 312 | + .provider-models-actions { |
| 313 | + margin-left: 0; |
| 314 | + width: 100%; |
| 315 | + } |
| 316 | +} |
241 | 317 | </style> |
0 commit comments