Merge branch 'feat/model-plugins-implementing' into deploy/dev

This commit is contained in:
yyh
2026-03-11 22:23:12 +08:00
17 changed files with 220 additions and 175 deletions

View File

@ -1,6 +1,7 @@
import type { ChecklistItem } from '../../hooks/use-checklist'
import { fireEvent, render, screen } from '@testing-library/react'
import { beforeEach, describe, expect, it } from 'vitest'
import { Popover, PopoverContent } from '@/app/components/base/ui/popover'
import { useStore as usePluginDependencyStore } from '../../plugin-dependency/store'
import { BlockEnum } from '../../types'
import { ChecklistPluginGroup } from './plugin-group'
@ -17,6 +18,20 @@ const createChecklistItem = (overrides: Partial<ChecklistItem> = {}): ChecklistI
})
describe('ChecklistPluginGroup', () => {
const getInstallButton = () => {
return screen.getByText('workflow.nodes.agent.pluginInstaller.install').closest('button') as HTMLButtonElement
}
const renderInPopover = (items: ChecklistItem[]) => {
return render(
<Popover open>
<PopoverContent>
<ChecklistPluginGroup items={items} />
</PopoverContent>
</Popover>,
)
}
beforeEach(() => {
usePluginDependencyStore.setState({ dependencies: [] })
})
@ -28,9 +43,9 @@ describe('ChecklistPluginGroup', () => {
createChecklistItem({ id: 'node-3', pluginUniqueIdentifier: 'langgenius/another-plugin:2.0.0@sha256' }),
]
render(<ChecklistPluginGroup items={items} />)
renderInPopover(items)
fireEvent.click(screen.getByRole('button'))
fireEvent.click(getInstallButton())
expect(usePluginDependencyStore.getState().dependencies).toEqual([
{
@ -53,9 +68,9 @@ describe('ChecklistPluginGroup', () => {
})
it('should keep install button disabled when no identifier is available', () => {
render(<ChecklistPluginGroup items={[createChecklistItem({ pluginUniqueIdentifier: undefined })]} />)
renderInPopover([createChecklistItem({ pluginUniqueIdentifier: undefined })])
const installButton = screen.getByRole('button')
const installButton = getInstallButton()
expect(installButton).toBeDisabled()
fireEvent.click(installButton)

View File

@ -1,10 +1,10 @@
import type { MouseEventHandler } from 'react'
import type { ChecklistItem } from '../../hooks/use-checklist'
import type { BlockEnum } from '../../types'
import type { Dependency } from '@/app/components/plugins/types'
import { memo, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { PopoverClose } from '@/app/components/base/ui/popover'
import BlockIcon from '../../block-icon'
import { useStore as usePluginDependencyStore } from '../../plugin-dependency/store'
import { ItemIndicator } from './item-indicator'
@ -46,8 +46,7 @@ export const ChecklistPluginGroup = memo(({
})
}, [identifiers])
const handleInstallAll: MouseEventHandler = (e) => {
e.stopPropagation()
const handleInstallAll = () => {
if (dependencies.length === 0)
return
const { setDependencies } = usePluginDependencyStore.getState()
@ -63,14 +62,18 @@ export const ChecklistPluginGroup = memo(({
<span className="min-w-0 grow truncate text-sm font-medium leading-5 text-text-primary">
{t('nodes.common.pluginsNotInstalled', { ns: 'workflow', count: items.length })}
</span>
<Button
variant="secondary"
size="small"
onClick={handleInstallAll}
disabled={dependencies.length === 0}
<PopoverClose
render={(
<Button
variant="secondary"
size="small"
onClick={handleInstallAll}
disabled={dependencies.length === 0}
/>
)}
>
{t('nodes.agent.pluginInstaller.install', { ns: 'workflow' })}
</Button>
</PopoverClose>
</div>
<div className="p-1">
{items.map(item => (