feat: can select plugins

This commit is contained in:
Joel
2025-06-26 15:31:50 +08:00
parent 52b845a5bb
commit 4c583f3d9a
6 changed files with 80 additions and 19 deletions

View File

@@ -4,6 +4,6 @@ export const defaultValue: AutoUpdateConfig = {
strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly, // For test
upgrade_time_of_day: 0,
upgrade_mode: AUTO_UPDATE_MODE.exclude, // For test
exclude_plugins: ['a', 'c'],
include_plugins: ['b'],
exclude_plugins: ['langgenius/openai_api_compatible', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai', 'langgenius/openai'],
include_plugins: ['langgenius/openai'],
}

View File

@@ -53,7 +53,7 @@ const PluginsPicker: FC<Props> = ({
<ToolPicker
trigger={
<Button className='mt-2 w-[350px]' size='small' variant='secondary-accent'>
<Button className='mt-2 w-[412px]' size='small' variant='secondary-accent'>
<RiAddLine className='size-3.5' />
{t(`${i18nPrefix}.operation.select`)}
</Button>

View File

@@ -2,6 +2,8 @@
import type { FC } from 'react'
import React from 'react'
import cn from '@/utils/classnames'
import { MARKETPLACE_API_PREFIX } from '@/config'
import Icon from '@/app/components/plugins/card/base/card-icon'
const MAX_DISPLAY_COUNT = 14
type Props = {
@@ -14,17 +16,13 @@ const PluginsSelected: FC<Props> = ({
plugins,
}) => {
const isShowAll = plugins.length < MAX_DISPLAY_COUNT
const displayPlugins = isShowAll ? plugins.slice(0, MAX_DISPLAY_COUNT) : plugins
const displayPlugins = plugins.slice(0, MAX_DISPLAY_COUNT)
return (
<div className={cn('flex space-x-1', className)}>
{displayPlugins.map((plugin, index) => (
<div
key={index}
className='size-6 rounded-lg border-[0.5px] border-[components-panel-border-subtle] bg-background-default-dodge text-center text-xs leading-6 text-text-secondary'
>
</div>
<div className={cn('flex items-center space-x-1', className)}>
{displayPlugins.map(plugin => (
<Icon key={plugin} size='tiny' src={`${MARKETPLACE_API_PREFIX}/plugins/${plugin}/icon`} />
))}
{!isShowAll && <div>+{plugins.length - MAX_DISPLAY_COUNT}</div>}
{!isShowAll && <div className='system-xs-medium text-text-tertiary'>+{plugins.length - MAX_DISPLAY_COUNT}</div>}
</div>
)
}

View File

@@ -0,0 +1,44 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import type { Plugin } from '@/app/components/plugins/types'
import Icon from '@/app/components/plugins/card/base/card-icon'
import { renderI18nObject } from '@/i18n'
import { useGetLanguage } from '@/context/i18n'
import { MARKETPLACE_API_PREFIX } from '@/config'
import Checkbox from '@/app/components/base/checkbox'
type Props = {
payload: Plugin
isChecked?: boolean
onCheckChange: () => void
}
const ToolItem: FC<Props> = ({
payload,
isChecked,
onCheckChange,
}) => {
const language = useGetLanguage()
const { plugin_id, label, org } = payload
return (
<div className='p-1'>
<div
className='flex w-full select-none items-center rounded-lg pr-2 hover:bg-state-base-hover'
>
<div className='flex h-8 grow items-center space-x-2 pl-3 pr-2'>
<Icon size='tiny' src={`${MARKETPLACE_API_PREFIX}/plugins/${plugin_id}/icon`} />
<div className='system-sm-medium max-w-[150px] shrink-0 truncate text-text-primary'>{renderI18nObject(label, language)}</div>
<div className='system-xs-regular max-w-[150px] shrink-0 truncate text-text-quaternary'>{org}</div>
</div>
<Checkbox
checked={isChecked}
onCheck={onCheckChange}
className='shrink-0'
/>
</div>
</div>
)
}
export default React.memo(ToolItem)

View File

@@ -11,6 +11,7 @@ import { PLUGIN_TYPE_SEARCH_MAP } from '../../marketplace/plugin-type-switch'
import SearchBox from '@/app/components/plugins/marketplace/search-box'
import { useTranslation } from 'react-i18next'
import cn from '@/utils/classnames'
import ToolItem from './tool-item'
type Props = {
trigger: React.ReactNode
@@ -70,13 +71,19 @@ const ToolPicker: FC<Props> = ({
})
const isBundle = pluginType === PLUGIN_TYPE_SEARCH_MAP.bundle
const list = (isBundle ? data?.data?.bundles : data?.data?.plugins) || []
console.log(list)
const handleCheckChange = useCallback((pluginId: string) => {
return () => {
const newValue = value.includes(pluginId)
? value.filter(id => id !== pluginId)
: [...value, pluginId]
onChange(newValue)
}
}, [onChange, value])
return (
<PortalToFollowElem
placement='top-start'
placement='top'
offset={0}
open={true}
open={isShow}
onOpenChange={onShowChange}
>
<PortalToFollowElemTrigger
@@ -85,7 +92,7 @@ const ToolPicker: FC<Props> = ({
{trigger}
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className='z-[1000]'>
<div className={cn('relative min-h-20 w-[356px] rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur pb-2 shadow-lg backdrop-blur-sm')}>
<div className={cn('relative min-h-20 w-[436px] rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur pb-2 shadow-lg backdrop-blur-sm')}>
<div className='p-2 pb-1'>
<SearchBox
search={query}
@@ -116,6 +123,18 @@ const ToolPicker: FC<Props> = ({
}
</div>
</div>
{list.length > 0 && (
<div className='max-h-[396px] overflow-y-auto'>
{list.map(item => (
<ToolItem
key={item.plugin_id}
payload={item}
isChecked={value.includes(item.plugin_id)}
onCheckChange={handleCheckChange(item.plugin_id)}
/>
))}
</div>
)}
</div>
</PortalToFollowElemContent>
</PortalToFollowElem>

View File

@@ -51,9 +51,9 @@ const PluginSettingModal: FC<Props> = ({
isShow
onClose={onHide}
closable
className='w-[420px] !p-0'
className='w-[480px] !p-0'
>
<div className='shadows-shadow-xl flex w-[420px] flex-col items-start rounded-2xl border border-components-panel-border bg-components-panel-bg'>
<div className='shadows-shadow-xl flex w-[480px] flex-col items-start rounded-2xl border border-components-panel-border bg-components-panel-bg'>
<div className='flex items-start gap-2 self-stretch pb-3 pl-6 pr-14 pt-6'>
<span className='title-2xl-semi-bold self-stretch text-text-primary'>{t(`${i18nPrefix}.title`)}</span>
</div>