@@ -3,16 +3,22 @@ import { Plus } from 'lucide-vue-next'
33import { onMounted , ref , watchEffect } from ' vue'
44import { useI18n } from ' vue-i18n'
55import { Badge } from ' @/components/ui/badge'
6+ import { Card , CardContent , CardFooter , CardHeader , CardTitle } from ' @/components/ui/card'
67import { useProvidersStore } from ' @/stores'
78import AddProviderDialog from ' ./AddProviderDialog.vue'
9+ import ManualConfigCard from ' ./ManualConfigCard.vue'
10+ import SiliconFlowConfigDialog from ' ./SiliconFlowConfigDialog.vue'
811import Button from ' ./ui/button/Button.vue'
912
13+ const props = defineProps <{
14+ compact? : boolean
15+ }>()
1016const selectedProviderId = defineModel <string >()
11-
1217const { t } = useI18n ()
1318const providersStore = useProvidersStore ()
1419
1520const openAddProviderDialog = ref (false )
21+ const showSiliconFlowConfig = ref (false )
1622
1723onMounted (() => providersStore .loadProviders ())
1824
@@ -28,47 +34,89 @@ watchEffect(() => {
2834
2935<template >
3036 <div class =" space-y-2" >
31- <div class =" text-sm font-medium" >
32- {{ t('providers.selectProvider') }}:
33- </div >
3437 <div v-if =" providersStore.loading" class =" text-sm text-muted-foreground" >
3538 {{ t('providers.loadingProviders') }}
3639 </div >
3740 <div v-else-if =" providersStore.providers.length === 0" class =" text-sm text-muted-foreground" >
38- <span class =" text-red-500 dark:text-red-600" >
39- {{ t('providers.noProvidersAvailable') }}
40- </span >
41+ <template v-if =" props .compact " >
42+ <span class =" text-red-500 dark:text-red-600" >
43+ {{ t('providers.noProvidersAvailable') }}
44+ </span >
45+
46+ <Button variant =" link" class =" text-blue-600 dark:text-blue-400 underline hover:opacity-80" @click =" openAddProviderDialog = true" >
47+ {{ t('providers.addNewProvider') }}
48+ </Button >
49+ </template >
50+ <template v-else >
51+ <div class =" grid gap-4 grid-cols-2 mb-4" >
52+ <!-- SiliconFlow configuration card (if not configured) -->
53+ <Card class =" relative gap-2" >
54+ <CardHeader >
55+ <div class =" flex items-center justify-between" >
56+ <CardTitle class =" text-lg" >
57+ {{ t('providers.siliconFlow') }}
58+ </CardTitle >
59+ </div >
60+ </CardHeader >
61+
62+ <CardContent >
63+ <div class =" text-sm text-muted-foreground" >
64+ <p >
65+ {{ t('providers.siliconFlowDescription1') }}
66+ <a href =" https://www.siliconflow.cn" target =" _blank" class =" text-blue-900 dark:text-blue-200 hover:underline" >
67+ {{ t('providers.siliconFlow') }}
68+ </a >
69+ {{ t('providers.siliconFlowDescription2') }}
70+ </p >
71+ </div >
72+ </CardContent >
73+
74+ <CardFooter >
75+ <Button class =" w-full" @click =" showSiliconFlowConfig = true" >
76+ {{ t('providers.configureSiliconFlow') }}
77+ </Button >
78+ </CardFooter >
79+ </Card >
4180
42- < Button variant = " link " class = " text-blue-600 dark:text-blue-400 underline hover:opacity-80 " @click = " openAddProviderDialog = true " >
43- {{ t('providers.addNewProvider') }}
44- </Button >
81+ < ManualConfigCard class = " relative gap-2 " / >
82+ </ div >
83+ </template >
4584 </div >
46- <div v-else class =" flex flex-wrap gap-2" >
47- <Badge
48- v-for =" provider in providersStore.providers"
49- :key =" provider.id"
50- :variant =" selectedProviderId === provider.id ? 'default' : 'secondary'"
51- class =" cursor-pointer transition-colors"
52- :class =" {
53- 'bg-blue-500 hover:bg-blue-600 dark:bg-blue-800 dark:hover:bg-blue-600 text-white': selectedProviderId === provider.id,
54- 'bg-muted hover:bg-muted-foreground': selectedProviderId !== provider.id,
55- }"
56- @click =" selectedProviderId = provider.id"
57- >
58- {{ provider.name }}
59- </Badge >
85+ <div v-else class =" flex gap-4" >
86+ <div :class =" compact ? 'text-sm font-medium mb-1' : 'text-base font-bold mb-1'" >
87+ {{ t('providers.selectProvider') }}
88+ </div >
89+ <div class =" w-0 flex-grow flex flex-wrap gap-2 h-fit" >
90+ <Badge
91+ v-for =" provider in providersStore.providers"
92+ :key =" provider.id"
93+ :variant =" selectedProviderId === provider.id ? 'default' : 'secondary'"
94+ class =" cursor-pointer transition-colors"
95+ :class =" {
96+ 'bg-blue-500 hover:bg-blue-600 dark:bg-blue-800 dark:hover:bg-blue-600 text-white': selectedProviderId === provider.id,
97+ 'bg-muted hover:bg-gray-300 dark:hover:bg-gray-700': selectedProviderId !== provider.id,
98+ }"
99+ @click =" selectedProviderId = provider.id"
100+ >
101+ {{ provider.name }}
102+ </Badge >
60103
61- <!-- Add new provider button -->
62- <Badge
63- variant =" secondary"
64- class =" text-xs cursor-pointer transition-colors bg-muted hover:bg-muted-foreground h-6"
65- @click =" openAddProviderDialog = true"
66- >
67- <Plus class =" inline h-4 w-4" />
68- {{ t('providers.addNewProvider') }}
69- </Badge >
104+ <!-- Add new provider button -->
105+ <Badge
106+ variant =" secondary"
107+ class =" ml-auto text-xs cursor-pointer transition-colors bg-muted hover:bg-gray-300 dark:hover:bg-gray-700 h-6"
108+ @click =" openAddProviderDialog = true"
109+ >
110+ <Plus class =" inline h-4 w-4" />
111+ {{ t('providers.addNewProvider') }}
112+ </Badge >
113+ </div >
70114 </div >
71115
116+ <SiliconFlowConfigDialog
117+ v-model:open =" showSiliconFlowConfig"
118+ @configured =" selectedProviderId = $event"
119+ />
72120 <AddProviderDialog v-model:open =" openAddProviderDialog" @configured =" selectedProviderId = $event" />
73121 </div >
74122</template >
0 commit comments