mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-10 13:10:57 +00:00
perf: frontend
This commit is contained in:
+29
-22
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|||||||
import typing
|
import typing
|
||||||
from typing import Any
|
from typing import Any
|
||||||
import base64
|
import base64
|
||||||
|
import traceback
|
||||||
|
|
||||||
import sqlalchemy
|
import sqlalchemy
|
||||||
|
|
||||||
@@ -48,33 +49,39 @@ class RuntimeConnectionHandler(handler.Handler):
|
|||||||
install_source = data['install_source']
|
install_source = data['install_source']
|
||||||
install_info = data['install_info']
|
install_info = data['install_info']
|
||||||
|
|
||||||
result = await self.ap.persistence_mgr.execute_async(
|
try:
|
||||||
sqlalchemy.select(persistence_plugin.PluginSetting)
|
result = await self.ap.persistence_mgr.execute_async(
|
||||||
.where(persistence_plugin.PluginSetting.plugin_author == plugin_author)
|
sqlalchemy.select(persistence_plugin.PluginSetting)
|
||||||
.where(persistence_plugin.PluginSetting.plugin_name == plugin_name)
|
|
||||||
)
|
|
||||||
|
|
||||||
if result.first() is not None:
|
|
||||||
# delete plugin setting
|
|
||||||
await self.ap.persistence_mgr.execute_async(
|
|
||||||
sqlalchemy.delete(persistence_plugin.PluginSetting)
|
|
||||||
.where(persistence_plugin.PluginSetting.plugin_author == plugin_author)
|
.where(persistence_plugin.PluginSetting.plugin_author == plugin_author)
|
||||||
.where(persistence_plugin.PluginSetting.plugin_name == plugin_name)
|
.where(persistence_plugin.PluginSetting.plugin_name == plugin_name)
|
||||||
)
|
)
|
||||||
|
|
||||||
# create plugin setting
|
if result.first() is not None:
|
||||||
await self.ap.persistence_mgr.execute_async(
|
# delete plugin setting
|
||||||
sqlalchemy.insert(persistence_plugin.PluginSetting).values(
|
await self.ap.persistence_mgr.execute_async(
|
||||||
plugin_author=plugin_author,
|
sqlalchemy.delete(persistence_plugin.PluginSetting)
|
||||||
plugin_name=plugin_name,
|
.where(persistence_plugin.PluginSetting.plugin_author == plugin_author)
|
||||||
install_source=install_source,
|
.where(persistence_plugin.PluginSetting.plugin_name == plugin_name)
|
||||||
install_info=install_info,
|
)
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
return handler.ActionResponse.success(
|
# create plugin setting
|
||||||
data={},
|
await self.ap.persistence_mgr.execute_async(
|
||||||
)
|
sqlalchemy.insert(persistence_plugin.PluginSetting).values(
|
||||||
|
plugin_author=plugin_author,
|
||||||
|
plugin_name=plugin_name,
|
||||||
|
install_source=install_source,
|
||||||
|
install_info=install_info,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return handler.ActionResponse.success(
|
||||||
|
data={},
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
traceback.print_exc()
|
||||||
|
return handler.ActionResponse.error(
|
||||||
|
message=f'Failed to initialize plugin settings: {e}',
|
||||||
|
)
|
||||||
|
|
||||||
@self.action(RuntimeToLangBotAction.GET_PLUGIN_SETTINGS)
|
@self.action(RuntimeToLangBotAction.GET_PLUGIN_SETTINGS)
|
||||||
async def get_plugin_settings(data: dict[str, Any]) -> handler.ActionResponse:
|
async def get_plugin_settings(data: dict[str, Any]) -> handler.ActionResponse:
|
||||||
|
|||||||
@@ -293,7 +293,12 @@ export default function PluginConfigPage() {
|
|||||||
)}
|
)}
|
||||||
{pluginInstallStatus === PluginInstallStatus.ASK_CONFIRM && (
|
{pluginInstallStatus === PluginInstallStatus.ASK_CONFIRM && (
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<p className="mb-2">{t('plugins.askConfirm')}</p>
|
<p className="mb-2">
|
||||||
|
{t('plugins.askConfirm', {
|
||||||
|
name: installInfo.plugin_name,
|
||||||
|
version: installInfo.plugin_version,
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{pluginInstallStatus === PluginInstallStatus.INSTALLING && (
|
{pluginInstallStatus === PluginInstallStatus.INSTALLING && (
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { Badge } from '@/components/ui/badge';
|
|||||||
import { Switch } from '@/components/ui/switch';
|
import { Switch } from '@/components/ui/switch';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ExternalLink } from 'lucide-react';
|
import { BugIcon, ExternalLink } from 'lucide-react';
|
||||||
import { getCloudServiceClientSync } from '@/app/infra/http';
|
import { getCloudServiceClientSync } from '@/app/infra/http';
|
||||||
|
|
||||||
export default function PluginCardComponent({
|
export default function PluginCardComponent({
|
||||||
@@ -65,48 +65,53 @@ export default function PluginCardComponent({
|
|||||||
variant="outline"
|
variant="outline"
|
||||||
className="text-[0.7rem] border-orange-400 text-orange-400"
|
className="text-[0.7rem] border-orange-400 text-orange-400"
|
||||||
>
|
>
|
||||||
|
<BugIcon className="w-4 h-4" />
|
||||||
{t('plugins.debugging')}
|
{t('plugins.debugging')}
|
||||||
</Badge>
|
</Badge>
|
||||||
)}
|
)}
|
||||||
{cardVO.install_source === 'github' && (
|
{!cardVO.debug && (
|
||||||
<Badge
|
<>
|
||||||
variant="outline"
|
{cardVO.install_source === 'github' && (
|
||||||
className="text-[0.7rem] border-blue-400 text-blue-400"
|
<Badge
|
||||||
onClick={(e) => {
|
variant="outline"
|
||||||
e.stopPropagation();
|
className="text-[0.7rem] border-blue-400 text-blue-400"
|
||||||
window.open(cardVO.install_info.github_url, '_blank');
|
onClick={(e) => {
|
||||||
}}
|
e.stopPropagation();
|
||||||
>
|
window.open(cardVO.install_info.github_url, '_blank');
|
||||||
{t('plugins.fromGithub')}
|
}}
|
||||||
<ExternalLink className="w-4 h-4" />
|
>
|
||||||
</Badge>
|
{t('plugins.fromGithub')}
|
||||||
)}
|
<ExternalLink className="w-4 h-4" />
|
||||||
{cardVO.install_source === 'local' && (
|
</Badge>
|
||||||
<Badge
|
)}
|
||||||
variant="outline"
|
{cardVO.install_source === 'local' && (
|
||||||
className="text-[0.7rem] border-green-400 text-green-400"
|
<Badge
|
||||||
>
|
variant="outline"
|
||||||
{t('plugins.fromLocal')}
|
className="text-[0.7rem] border-green-400 text-green-400"
|
||||||
</Badge>
|
>
|
||||||
)}
|
{t('plugins.fromLocal')}
|
||||||
{cardVO.install_source === 'marketplace' && (
|
</Badge>
|
||||||
<Badge
|
)}
|
||||||
variant="outline"
|
{cardVO.install_source === 'marketplace' && (
|
||||||
className="text-[0.7rem] border-purple-400 text-purple-400"
|
<Badge
|
||||||
onClick={(e) => {
|
variant="outline"
|
||||||
e.stopPropagation();
|
className="text-[0.7rem] border-purple-400 text-purple-400"
|
||||||
window.open(
|
onClick={(e) => {
|
||||||
getCloudServiceClientSync().getPluginMarketplaceURL(
|
e.stopPropagation();
|
||||||
cardVO.author,
|
window.open(
|
||||||
cardVO.name,
|
getCloudServiceClientSync().getPluginMarketplaceURL(
|
||||||
),
|
cardVO.author,
|
||||||
'_blank',
|
cardVO.name,
|
||||||
);
|
),
|
||||||
}}
|
'_blank',
|
||||||
>
|
);
|
||||||
{t('plugins.fromMarketplace')}
|
}}
|
||||||
<ExternalLink className="w-4 h-4" />
|
>
|
||||||
</Badge>
|
{t('plugins.fromMarketplace')}
|
||||||
|
<ExternalLink className="w-4 h-4" />
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
padding-right: 0.8rem;
|
padding-right: 0.8rem;
|
||||||
padding-top: 2rem;
|
padding-top: 2rem;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(24rem, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(30rem, 1fr));
|
||||||
gap: 2rem;
|
gap: 2rem;
|
||||||
justify-items: stretch;
|
justify-items: stretch;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
|
|||||||
@@ -21,7 +21,10 @@ export class CloudServiceClient extends BaseHttpClient {
|
|||||||
sort_order?: string,
|
sort_order?: string,
|
||||||
): Promise<ApiRespMarketplacePlugins> {
|
): Promise<ApiRespMarketplacePlugins> {
|
||||||
return this.get<ApiRespMarketplacePlugins>('/api/v1/marketplace/plugins', {
|
return this.get<ApiRespMarketplacePlugins>('/api/v1/marketplace/plugins', {
|
||||||
params: { page, page_size, sort_by, sort_order },
|
page,
|
||||||
|
page_size,
|
||||||
|
sort_by,
|
||||||
|
sort_order,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -189,6 +189,7 @@ const enUS = {
|
|||||||
uploadSuccess: 'Upload successful',
|
uploadSuccess: 'Upload successful',
|
||||||
uploadFailed: 'Upload failed',
|
uploadFailed: 'Upload failed',
|
||||||
selectFileToUpload: 'Select plugin file to upload',
|
selectFileToUpload: 'Select plugin file to upload',
|
||||||
|
askConfirm: 'Are you sure to install plugin "{{name}}" ({{version}})?',
|
||||||
fromGithub: 'From GitHub',
|
fromGithub: 'From GitHub',
|
||||||
fromLocal: 'From Local',
|
fromLocal: 'From Local',
|
||||||
fromMarketplace: 'From Marketplace',
|
fromMarketplace: 'From Marketplace',
|
||||||
|
|||||||
@@ -189,6 +189,7 @@ const jaJP = {
|
|||||||
uploadSuccess: 'アップロード成功',
|
uploadSuccess: 'アップロード成功',
|
||||||
uploadFailed: 'アップロード失敗',
|
uploadFailed: 'アップロード失敗',
|
||||||
selectFileToUpload: 'アップロードするプラグインファイルを選択',
|
selectFileToUpload: 'アップロードするプラグインファイルを選択',
|
||||||
|
askConfirm: 'プラグイン "{{name}}" ({{version}}) をインストールしますか?',
|
||||||
fromGithub: 'GitHubから',
|
fromGithub: 'GitHubから',
|
||||||
fromLocal: 'ローカルから',
|
fromLocal: 'ローカルから',
|
||||||
fromMarketplace: 'プラグインマーケットから',
|
fromMarketplace: 'プラグインマーケットから',
|
||||||
|
|||||||
@@ -184,6 +184,7 @@ const zhHans = {
|
|||||||
uploadSuccess: '上传成功',
|
uploadSuccess: '上传成功',
|
||||||
uploadFailed: '上传失败',
|
uploadFailed: '上传失败',
|
||||||
selectFileToUpload: '选择要上传的插件文件',
|
selectFileToUpload: '选择要上传的插件文件',
|
||||||
|
askConfirm: '确定要安装插件 "{{name}}" ({{version}}) 吗?',
|
||||||
fromGithub: '来自 GitHub',
|
fromGithub: '来自 GitHub',
|
||||||
fromLocal: '来自本地',
|
fromLocal: '来自本地',
|
||||||
fromMarketplace: '来自市场',
|
fromMarketplace: '来自市场',
|
||||||
|
|||||||
Reference in New Issue
Block a user