@@ -3,16 +3,22 @@ import { Plus } from 'lucide-vue-next'
3
3
import { onMounted , ref , watchEffect } from ' vue'
4
4
import { useI18n } from ' vue-i18n'
5
5
import { Badge } from ' @/components/ui/badge'
6
+ import { Card , CardContent , CardFooter , CardHeader , CardTitle } from ' @/components/ui/card'
6
7
import { useProvidersStore } from ' @/stores'
7
8
import AddProviderDialog from ' ./AddProviderDialog.vue'
9
+ import ManualConfigCard from ' ./ManualConfigCard.vue'
10
+ import SiliconFlowConfigDialog from ' ./SiliconFlowConfigDialog.vue'
8
11
import Button from ' ./ui/button/Button.vue'
9
12
13
+ const props = defineProps <{
14
+ compact? : boolean
15
+ }>()
10
16
const selectedProviderId = defineModel <string >()
11
-
12
17
const { t } = useI18n ()
13
18
const providersStore = useProvidersStore ()
14
19
15
20
const openAddProviderDialog = ref (false )
21
+ const showSiliconFlowConfig = ref (false )
16
22
17
23
onMounted (() => providersStore .loadProviders ())
18
24
@@ -28,47 +34,89 @@ watchEffect(() => {
28
34
29
35
<template >
30
36
<div class =" space-y-2" >
31
- <div class =" text-sm font-medium" >
32
- {{ t('providers.selectProvider') }}:
33
- </div >
34
37
<div v-if =" providersStore.loading" class =" text-sm text-muted-foreground" >
35
38
{{ t('providers.loadingProviders') }}
36
39
</div >
37
40
<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 >
41
80
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 >
45
84
</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 >
60
103
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 >
70
114
</div >
71
115
116
+ <SiliconFlowConfigDialog
117
+ v-model:open =" showSiliconFlowConfig"
118
+ @configured =" selectedProviderId = $event"
119
+ />
72
120
<AddProviderDialog v-model:open =" openAddProviderDialog" @configured =" selectedProviderId = $event" />
73
121
</div >
74
122
</template >
0 commit comments