Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
bit-pm
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
燕伟桐
bit-pm
Commits
531cf236
提交
531cf236
authored
4月 21, 2025
作者:
Will Chen
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Make it clear there's other AI provider options in setup
上级
40132ec5
显示空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
37 行增加
和
9 行删除
+37
-9
SetupBanner.tsx
src/components/SetupBanner.tsx
+37
-9
没有找到文件。
src/components/SetupBanner.tsx
浏览文件 @
531cf236
...
@@ -7,8 +7,10 @@ import {
...
@@ -7,8 +7,10 @@ import {
AlertCircle
,
AlertCircle
,
XCircle
,
XCircle
,
Loader2
,
Loader2
,
Settings
,
}
from
"lucide-react"
;
}
from
"lucide-react"
;
import
{
providerSettingsRoute
}
from
"@/routes/settings/providers/$provider"
;
import
{
providerSettingsRoute
}
from
"@/routes/settings/providers/$provider"
;
import
{
settingsRoute
}
from
"@/routes/settings"
;
import
{
useSettings
}
from
"@/hooks/useSettings"
;
import
{
useSettings
}
from
"@/hooks/useSettings"
;
import
{
useState
,
useEffect
,
useCallback
}
from
"react"
;
import
{
useState
,
useEffect
,
useCallback
}
from
"react"
;
import
{
IpcClient
}
from
"@/ipc/ipc_client"
;
import
{
IpcClient
}
from
"@/ipc/ipc_client"
;
...
@@ -28,7 +30,7 @@ type NodeInstallStep =
...
@@ -28,7 +30,7 @@ type NodeInstallStep =
|
"continue-processing"
;
|
"continue-processing"
;
export
function
SetupBanner
()
{
export
function
SetupBanner
()
{
const
{
capture
}
=
usePostHog
();
const
posthog
=
usePostHog
();
const
navigate
=
useNavigate
();
const
navigate
=
useNavigate
();
const
{
isAnyProviderSetup
,
loading
}
=
useSettings
();
const
{
isAnyProviderSetup
,
loading
}
=
useSettings
();
const
[
nodeSystemInfo
,
setNodeSystemInfo
]
=
useState
<
NodeSystemInfo
|
null
>
(
const
[
nodeSystemInfo
,
setNodeSystemInfo
]
=
useState
<
NodeSystemInfo
|
null
>
(
...
@@ -54,21 +56,28 @@ export function SetupBanner() {
...
@@ -54,21 +56,28 @@ export function SetupBanner() {
},
[
checkNode
]);
},
[
checkNode
]);
const
handleAiSetupClick
=
()
=>
{
const
handleAiSetupClick
=
()
=>
{
capture
(
"setup-flow:ai-provider-setup-
click"
);
posthog
.
capture
(
"setup-flow:ai-provider-setup:google:
click"
);
navigate
({
navigate
({
to
:
providerSettingsRoute
.
id
,
to
:
providerSettingsRoute
.
id
,
params
:
{
provider
:
"google"
},
params
:
{
provider
:
"google"
},
});
});
};
};
const
handleOtherProvidersClick
=
()
=>
{
posthog
.
capture
(
"setup-flow:ai-provider-setup:other:click"
);
navigate
({
to
:
settingsRoute
.
id
,
});
};
const
handleNodeInstallClick
=
useCallback
(
async
()
=>
{
const
handleNodeInstallClick
=
useCallback
(
async
()
=>
{
capture
(
"setup-flow:start-node-install-click"
);
posthog
.
capture
(
"setup-flow:start-node-install-click"
);
setNodeInstallStep
(
"waiting-for-continue"
);
setNodeInstallStep
(
"waiting-for-continue"
);
IpcClient
.
getInstance
().
openExternalUrl
(
nodeSystemInfo
!
.
nodeDownloadUrl
);
IpcClient
.
getInstance
().
openExternalUrl
(
nodeSystemInfo
!
.
nodeDownloadUrl
);
},
[
nodeSystemInfo
,
setNodeInstallStep
]);
},
[
nodeSystemInfo
,
setNodeInstallStep
]);
const
finishNodeInstall
=
useCallback
(
async
()
=>
{
const
finishNodeInstall
=
useCallback
(
async
()
=>
{
capture
(
"setup-flow:continue-node-install-click"
);
posthog
.
capture
(
"setup-flow:continue-node-install-click"
);
setNodeInstallStep
(
"continue-processing"
);
setNodeInstallStep
(
"continue-processing"
);
await
IpcClient
.
getInstance
().
reloadEnvPath
();
await
IpcClient
.
getInstance
().
reloadEnvPath
();
await
checkNode
();
await
checkNode
();
...
@@ -228,11 +237,6 @@ export function SetupBanner() {
...
@@ -228,11 +237,6 @@ export function SetupBanner() {
onClick=
{
handleAiSetupClick
}
onClick=
{
handleAiSetupClick
}
role=
"button"
role=
"button"
tabIndex=
{
isNodeSetupComplete
?
0
:
-
1
}
tabIndex=
{
isNodeSetupComplete
?
0
:
-
1
}
onKeyDown=
{
(
e
)
=>
isNodeSetupComplete
&&
e
.
key
===
"Enter"
&&
handleAiSetupClick
()
}
>
>
<
div
className=
"flex items-center justify-between gap-3"
>
<
div
className=
"flex items-center justify-between gap-3"
>
<
div
className=
"flex items-center gap-2"
>
<
div
className=
"flex items-center gap-2"
>
...
@@ -252,6 +256,30 @@ export function SetupBanner() {
...
@@ -252,6 +256,30 @@ export function SetupBanner() {
<
ChevronRight
className=
"w-4 h-4 text-blue-600 dark:text-blue-400"
/>
<
ChevronRight
className=
"w-4 h-4 text-blue-600 dark:text-blue-400"
/>
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"mt-2 p-3 bg-gray-50 dark:bg-gray-800/50 border border-gray-200 dark:border-gray-700 rounded-lg cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800/70 transition-colors"
onClick=
{
handleOtherProvidersClick
}
role=
"button"
tabIndex=
{
isNodeSetupComplete
?
0
:
-
1
}
>
<
div
className=
"flex items-center justify-between gap-3"
>
<
div
className=
"flex items-center gap-2"
>
<
div
className=
"bg-gray-100 dark:bg-gray-700 p-1.5 rounded-full"
>
<
Settings
className=
"w-4 h-4 text-gray-600 dark:text-gray-400"
/>
</
div
>
<
div
>
<
h4
className=
"font-medium text-sm text-gray-800 dark:text-gray-300"
>
Setup other AI providers
</
h4
>
<
p
className=
"text-xs text-gray-600 dark:text-gray-400"
>
OpenAI, Anthropic, OpenRouter and more
</
p
>
</
div
>
</
div
>
<
ChevronRight
className=
"w-4 h-4 text-gray-600 dark:text-gray-400"
/>
</
div
>
</
div
>
</
AccordionContent
>
</
AccordionContent
>
</
AccordionItem
>
</
AccordionItem
>
</
Accordion
>
</
Accordion
>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论