mirror of
https://github.com/langgenius/dify.git
synced 2026-07-31 17:29:37 +08:00
refactor(web): remove configuration mitt context (#39796)
This commit is contained in:
parent
e4947811a5
commit
95166806ae
@ -458,7 +458,7 @@
|
||||
"count": 2
|
||||
},
|
||||
"typescript/no-explicit-any": {
|
||||
"count": 9
|
||||
"count": 7
|
||||
}
|
||||
},
|
||||
"web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx": {
|
||||
|
||||
@ -1,9 +1,14 @@
|
||||
import type { ComponentProps } from 'react'
|
||||
import type { ConfigurationViewModel } from '../hooks/use-configuration'
|
||||
import type AppPublisher from '@/app/components/app/app-publisher/features-wrapper'
|
||||
import type { InstallBundleCompleteCallback } from '@/app/components/plugins/install-plugin/install-bundle'
|
||||
import type { Plugin } from '@/app/components/plugins/types'
|
||||
import type ConfigContext from '@/context/debug-configuration'
|
||||
import type { AgentTool } from '@/types/app'
|
||||
import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import * as React from 'react'
|
||||
import { PluginCategoryEnum } from '@/app/components/plugins/types'
|
||||
import { CollectionType } from '@/app/components/tools/types'
|
||||
import { AppModeEnum, ModelModeType } from '@/types/app'
|
||||
import ConfigurationView from '../configuration-view'
|
||||
|
||||
@ -48,10 +53,49 @@ vi.mock('@/app/components/base/features/new-feature-panel', () => ({
|
||||
default: () => <div data-testid="feature-panel" />,
|
||||
}))
|
||||
|
||||
let pluginDependencyOnInstallComplete: InstallBundleCompleteCallback | undefined
|
||||
vi.mock('@/app/components/workflow/plugin-dependency', () => ({
|
||||
default: () => <div data-testid="plugin-dependency" />,
|
||||
default: ({ onInstallComplete }: { onInstallComplete?: InstallBundleCompleteCallback }) => {
|
||||
pluginDependencyOnInstallComplete = onInstallComplete
|
||||
return <div data-testid="plugin-dependency" />
|
||||
},
|
||||
}))
|
||||
|
||||
const createPlugin = (name: string): Plugin => ({
|
||||
type: 'plugin',
|
||||
org: 'vendor',
|
||||
name,
|
||||
plugin_id: 'vendor',
|
||||
version: '1.0.0',
|
||||
latest_version: '1.0.0',
|
||||
latest_package_identifier: `vendor/${name}:1.0.0`,
|
||||
icon: 'icon.svg',
|
||||
verified: true,
|
||||
label: { 'en-US': name },
|
||||
brief: { 'en-US': name },
|
||||
description: { 'en-US': name },
|
||||
introduction: '',
|
||||
repository: `https://example.com/vendor/${name}`,
|
||||
category: PluginCategoryEnum.tool,
|
||||
install_count: 0,
|
||||
endpoint: { settings: [] },
|
||||
tags: [],
|
||||
badges: [],
|
||||
verification: { authorized_category: 'community' },
|
||||
from: 'marketplace',
|
||||
})
|
||||
|
||||
const createDeletedAgentTool = (providerId: string): AgentTool => ({
|
||||
provider_id: providerId,
|
||||
provider_type: CollectionType.builtIn,
|
||||
provider_name: providerId,
|
||||
tool_name: 'search',
|
||||
tool_label: 'Search',
|
||||
tool_parameters: {},
|
||||
enabled: true,
|
||||
isDeleted: true,
|
||||
})
|
||||
|
||||
const createContextValue = (): ComponentProps<typeof ConfigContext.Provider>['value'] => ({
|
||||
appId: 'app-1',
|
||||
isAPIKeySet: true,
|
||||
@ -269,6 +313,7 @@ describe('ConfigurationView', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
mockIsAgentV2Enabled.mockReturnValue(false)
|
||||
pluginDependencyOnInstallComplete = undefined
|
||||
})
|
||||
|
||||
it('should render a loading state before configuration data is ready', () => {
|
||||
@ -332,4 +377,63 @@ describe('ConfigurationView', () => {
|
||||
|
||||
expect(screen.queryByText('appDebug.legacyAgentBadge.label')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should reinstate selected plugin tools when at least one installation succeeds', () => {
|
||||
const contextValue = createContextValue()
|
||||
contextValue.isAgent = true
|
||||
const tools = [
|
||||
createDeletedAgentTool('vendor/successful-plugin'),
|
||||
createDeletedAgentTool('vendor/failed-plugin'),
|
||||
createDeletedAgentTool('vendor/unselected-plugin'),
|
||||
]
|
||||
contextValue.modelConfig.agentConfig.tools = tools
|
||||
|
||||
render(<ConfigurationView {...createViewModel({ contextValue, isAgent: true })} />)
|
||||
if (!pluginDependencyOnInstallComplete)
|
||||
throw new Error('Plugin completion callback not registered')
|
||||
|
||||
pluginDependencyOnInstallComplete(
|
||||
[createPlugin('successful-plugin'), createPlugin('failed-plugin')],
|
||||
[
|
||||
{ success: true, isFromMarketPlace: true },
|
||||
{ success: false, isFromMarketPlace: true },
|
||||
],
|
||||
[
|
||||
{ hasInstalled: false, toInstallVersion: '1.0.0' },
|
||||
{ hasInstalled: false, toInstallVersion: '1.0.0' },
|
||||
],
|
||||
)
|
||||
|
||||
expect(contextValue.setModelConfig).toHaveBeenCalledOnce()
|
||||
const nextModelConfig = vi.mocked(contextValue.setModelConfig).mock.calls[0]![0]
|
||||
expect(nextModelConfig.agentConfig.tools).toEqual([
|
||||
expect.objectContaining({ provider_id: 'vendor/successful-plugin', isDeleted: false }),
|
||||
expect.objectContaining({ provider_id: 'vendor/failed-plugin', isDeleted: false }),
|
||||
expect.objectContaining({ provider_id: 'vendor/unselected-plugin', isDeleted: true }),
|
||||
])
|
||||
})
|
||||
|
||||
it('should keep deleted tools unchanged when every installation fails', () => {
|
||||
const contextValue = createContextValue()
|
||||
contextValue.isAgent = true
|
||||
contextValue.modelConfig.agentConfig.tools = [createDeletedAgentTool('vendor/failed-plugin')]
|
||||
|
||||
render(<ConfigurationView {...createViewModel({ contextValue, isAgent: true })} />)
|
||||
if (!pluginDependencyOnInstallComplete)
|
||||
throw new Error('Plugin completion callback not registered')
|
||||
|
||||
pluginDependencyOnInstallComplete(
|
||||
[createPlugin('failed-plugin')],
|
||||
[{ success: false, isFromMarketPlace: true }],
|
||||
[{ hasInstalled: false, toInstallVersion: '1.0.0' }],
|
||||
)
|
||||
|
||||
expect(contextValue.setModelConfig).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not attach the agent tool completion handler to non-agent configurations', () => {
|
||||
render(<ConfigurationView {...createViewModel()} />)
|
||||
|
||||
expect(pluginDependencyOnInstallComplete).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
@ -8,7 +8,7 @@ import type { ToolDefaultValue } from '@/app/components/workflow/block-selector/
|
||||
import type { ToolWithProvider } from '@/app/components/workflow/types'
|
||||
import type { ModelConfig } from '@/models/debug'
|
||||
import type { AgentTool } from '@/types/app'
|
||||
import { act, render, screen, waitFor } from '@testing-library/react'
|
||||
import { render, screen, waitFor } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import * as React from 'react'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
@ -28,17 +28,6 @@ vi.mock('@/app/components/app/configuration/debug/hooks', () => ({
|
||||
useFormattingChangedDispatcher: () => formattingDispatcherMock,
|
||||
}))
|
||||
|
||||
let pluginInstallHandler: ((names: string[]) => void) | null = null
|
||||
const subscribeMock = vi.fn((event: string, handler: any) => {
|
||||
if (event === 'plugin:install:success') pluginInstallHandler = handler
|
||||
})
|
||||
vi.mock('@/context/mitt-context', () => ({
|
||||
useMittContextSelector: (selector: any) =>
|
||||
selector({
|
||||
useSubscribe: subscribeMock,
|
||||
}),
|
||||
}))
|
||||
|
||||
let builtInTools: ToolWithProvider[] = []
|
||||
let customTools: ToolWithProvider[] = []
|
||||
let workflowTools: ToolWithProvider[] = []
|
||||
@ -326,7 +315,6 @@ describe('AgentTools', () => {
|
||||
latestSettingPanelProps = null
|
||||
settingPanelSavePayload = {}
|
||||
settingPanelCredentialId = 'credential-from-panel'
|
||||
pluginInstallHandler = null
|
||||
})
|
||||
|
||||
it('should show enabled count and provider information', () => {
|
||||
@ -493,27 +481,4 @@ describe('AgentTools', () => {
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
it('should reinstate deleted tools after plugin install success event', async () => {
|
||||
const { getModelConfig } = renderAgentTools([
|
||||
createAgentTool({
|
||||
provider_id: 'provider-1',
|
||||
provider_name: 'vendor/provider-1',
|
||||
tool_name: 'search',
|
||||
tool_label: 'Search Tool',
|
||||
isDeleted: true,
|
||||
}),
|
||||
])
|
||||
if (!pluginInstallHandler) throw new Error('Plugin handler not registered')
|
||||
|
||||
await act(async () => {
|
||||
pluginInstallHandler?.(['provider-1'])
|
||||
})
|
||||
|
||||
await waitFor(() => {
|
||||
expect((getModelConfig().agentConfig.tools[0] as { isDeleted: boolean }).isDeleted).toBe(
|
||||
false,
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -31,7 +31,6 @@ import {
|
||||
import ToolPicker from '@/app/components/workflow/block-selector/tool-picker'
|
||||
import { MAX_TOOLS_NUM } from '@/config'
|
||||
import ConfigContext from '@/context/debug-configuration'
|
||||
import { useMittContextSelector } from '@/context/mitt-context'
|
||||
import {
|
||||
useAllBuiltInTools,
|
||||
useAllCustomTools,
|
||||
@ -77,21 +76,6 @@ const AgentTools: FC = () => {
|
||||
collection,
|
||||
}
|
||||
})
|
||||
const useSubscribe = useMittContextSelector((s) => s.useSubscribe)
|
||||
const handleUpdateToolsWhenInstallToolSuccess = useCallback(
|
||||
(installedPluginNames: string[]) => {
|
||||
const newModelConfig = produce(modelConfig, (draft) => {
|
||||
draft.agentConfig.tools.forEach((item: any) => {
|
||||
if (item.isDeleted && installedPluginNames.includes(item.provider_id))
|
||||
item.isDeleted = false
|
||||
})
|
||||
})
|
||||
setModelConfig(newModelConfig)
|
||||
},
|
||||
[modelConfig, setModelConfig],
|
||||
)
|
||||
useSubscribe('plugin:install:success', handleUpdateToolsWhenInstallToolSuccess as any)
|
||||
|
||||
const handleToolSettingChange = (value: Record<string, any>) => {
|
||||
const newModelConfig = produce(modelConfig, (draft) => {
|
||||
const tool = draft.agentConfig.tools.find(
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import type { ConfigurationViewModel } from './hooks/use-configuration'
|
||||
import type { InstallBundleCompleteCallback } from '@/app/components/plugins/install-plugin/install-bundle'
|
||||
import { CodeBracketIcon } from '@heroicons/react/20/solid'
|
||||
import {
|
||||
AlertDialog,
|
||||
@ -22,6 +23,7 @@ import {
|
||||
DrawerViewport,
|
||||
} from '@langgenius/dify-ui/drawer'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover'
|
||||
import { produce } from 'immer'
|
||||
import * as React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import AppPublisher from '@/app/components/app/app-publisher/features-wrapper'
|
||||
@ -37,7 +39,6 @@ import Loading from '@/app/components/base/loading'
|
||||
import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal'
|
||||
import PluginDependency from '@/app/components/workflow/plugin-dependency'
|
||||
import ConfigContext from '@/context/debug-configuration'
|
||||
import { MittProvider } from '@/context/mitt-context-provider'
|
||||
import { isAgentV2Enabled } from '@/features/agent-v2/feature-flag'
|
||||
import Link from '@/next/link'
|
||||
import { AppModeEnum, ModelModeType } from '@/types/app'
|
||||
@ -117,6 +118,23 @@ const ConfigurationView: FC<ConfigurationViewModel> = ({
|
||||
const { t } = useTranslation()
|
||||
const debugWithMultipleModel = appPublisherProps.debugWithMultipleModel
|
||||
const showLegacyAgentBadge = isAgentV2Enabled() && contextValue.mode === AppModeEnum.AGENT_CHAT
|
||||
const handlePluginInstallComplete: InstallBundleCompleteCallback = (plugins, installStatus) => {
|
||||
if (!installStatus.some((status) => status.success)) return
|
||||
|
||||
const installedPluginNames = plugins.map((plugin) => `${plugin.plugin_id}/${plugin.name}`)
|
||||
const nextModelConfig = produce(contextValue.modelConfig, (draft) => {
|
||||
draft.agentConfig.tools.forEach((tool) => {
|
||||
if (
|
||||
'provider_id' in tool &&
|
||||
tool.isDeleted &&
|
||||
installedPluginNames.includes(tool.provider_id)
|
||||
) {
|
||||
tool.isDeleted = false
|
||||
}
|
||||
})
|
||||
})
|
||||
contextValue.setModelConfig(nextModelConfig)
|
||||
}
|
||||
|
||||
if (showLoading) {
|
||||
return (
|
||||
@ -129,7 +147,7 @@ const ConfigurationView: FC<ConfigurationViewModel> = ({
|
||||
return (
|
||||
<ConfigContext.Provider value={contextValue}>
|
||||
<FeaturesProvider features={featuresData}>
|
||||
<MittProvider>
|
||||
<>
|
||||
<div className="flex h-full flex-col">
|
||||
<div className="relative flex h-50 grow pt-14">
|
||||
<div className="bg-default-subtle absolute top-0 left-0 h-14 w-full">
|
||||
@ -312,8 +330,8 @@ const ConfigurationView: FC<ConfigurationViewModel> = ({
|
||||
onAutoAddPromptVariable={onAutoAddPromptVariable}
|
||||
/>
|
||||
)}
|
||||
<PluginDependency />
|
||||
</MittProvider>
|
||||
<PluginDependency onInstallComplete={isAgent ? handlePluginInstallComplete : undefined} />
|
||||
</>
|
||||
</FeaturesProvider>
|
||||
</ConfigContext.Provider>
|
||||
)
|
||||
|
||||
@ -188,11 +188,6 @@ vi.mock('@/config', async () => {
|
||||
}
|
||||
})
|
||||
|
||||
// Mock mitt context
|
||||
vi.mock('@/context/mitt-context', () => ({
|
||||
useMittContextSelector: () => vi.fn(),
|
||||
}))
|
||||
|
||||
// Mock useCanInstallPluginFromMarketplace
|
||||
vi.mock('@/app/components/plugins/plugin-page/use-reference-setting', () => ({
|
||||
useCanInstallPluginFromMarketplace: () => ({ canInstallPluginFromMarketplace: true }),
|
||||
|
||||
@ -100,6 +100,7 @@ describe('ReadyToInstall', () => {
|
||||
const mockOnStartToInstall = vi.fn()
|
||||
const mockSetIsInstalling = vi.fn()
|
||||
const mockOnClose = vi.fn()
|
||||
const mockOnInstallComplete = vi.fn()
|
||||
|
||||
const defaultProps = {
|
||||
step: InstallStep.readyToInstall,
|
||||
@ -108,6 +109,7 @@ describe('ReadyToInstall', () => {
|
||||
setIsInstalling: mockSetIsInstalling,
|
||||
allPlugins: createMockDependencies(),
|
||||
onClose: mockOnClose,
|
||||
onInstallComplete: mockOnInstallComplete,
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
@ -177,6 +179,11 @@ describe('ReadyToInstall', () => {
|
||||
expect(screen.getByTestId('installed-step')).toBeInTheDocument()
|
||||
expect(screen.getByTestId('installed-count')).toHaveTextContent('1')
|
||||
expect(screen.getByTestId('installed-status-count')).toHaveTextContent('1')
|
||||
expect(mockOnInstallComplete).toHaveBeenCalledWith(
|
||||
[expect.objectContaining({ plugin_id: 'p1' })],
|
||||
[expect.objectContaining({ success: true })],
|
||||
[expect.objectContaining({ toInstallVersion: '1.0.0' })],
|
||||
)
|
||||
})
|
||||
|
||||
it('should pass custom plugins and status via capturedOnInstalled', () => {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import type { Dependency } from '../../types'
|
||||
import type { Dependency, InstallStatus, Plugin, VersionProps } from '../../types'
|
||||
import { cn } from '@langgenius/dify-ui/cn'
|
||||
import { Dialog, DialogCloseButton, DialogContent } from '@langgenius/dify-ui/dialog'
|
||||
import * as React from 'react'
|
||||
@ -12,6 +12,12 @@ import ReadyToInstall from './ready-to-install'
|
||||
|
||||
const i18nPrefix = 'installModal'
|
||||
|
||||
export type InstallBundleCompleteCallback = (
|
||||
plugins: Plugin[],
|
||||
installStatus: InstallStatus[],
|
||||
versionInfo: VersionProps[],
|
||||
) => void
|
||||
|
||||
export enum InstallType {
|
||||
fromLocal = 'fromLocal',
|
||||
fromMarketplace = 'fromMarketplace',
|
||||
@ -23,12 +29,14 @@ type Props = Readonly<{
|
||||
fromDSLPayload: Dependency[]
|
||||
// plugins?: PluginDeclaration[]
|
||||
onClose: () => void
|
||||
onInstallComplete?: InstallBundleCompleteCallback
|
||||
}>
|
||||
|
||||
const InstallBundle: FC<Props> = ({
|
||||
installType = InstallType.fromMarketplace,
|
||||
fromDSLPayload,
|
||||
onClose,
|
||||
onInstallComplete,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const [step, setStep] = useState<InstallStep>(
|
||||
@ -78,6 +86,7 @@ const InstallBundle: FC<Props> = ({
|
||||
setIsInstalling={setIsInstalling}
|
||||
allPlugins={fromDSLPayload}
|
||||
onClose={onClose}
|
||||
onInstallComplete={onInstallComplete}
|
||||
/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import type { Dependency, InstallStatus, Plugin, VersionProps } from '../../types'
|
||||
import type { InstallBundleCompleteCallback } from './index'
|
||||
import * as React from 'react'
|
||||
import { useCallback, useState } from 'react'
|
||||
import { InstallStep } from '../../types'
|
||||
@ -14,6 +15,7 @@ type Props = Readonly<{
|
||||
setIsInstalling: (isInstalling: boolean) => void
|
||||
allPlugins: Dependency[]
|
||||
onClose: () => void
|
||||
onInstallComplete?: InstallBundleCompleteCallback
|
||||
isFromMarketPlace?: boolean
|
||||
}>
|
||||
|
||||
@ -24,6 +26,7 @@ const ReadyToInstall: FC<Props> = ({
|
||||
setIsInstalling,
|
||||
allPlugins,
|
||||
onClose,
|
||||
onInstallComplete,
|
||||
isFromMarketPlace,
|
||||
}) => {
|
||||
const [installedPlugins, setInstalledPlugins] = useState<Plugin[]>([])
|
||||
@ -36,8 +39,9 @@ const ReadyToInstall: FC<Props> = ({
|
||||
setInstalledVersionInfo(versionInfo)
|
||||
onStepChange(InstallStep.installed)
|
||||
setIsInstalling(false)
|
||||
onInstallComplete?.(plugins, installStatus, versionInfo)
|
||||
},
|
||||
[onStepChange, setIsInstalling],
|
||||
[onInstallComplete, onStepChange, setIsInstalling],
|
||||
)
|
||||
return (
|
||||
<>
|
||||
|
||||
@ -55,12 +55,6 @@ vi.mock('../../../hooks/use-refresh-plugin-list', () => ({
|
||||
}),
|
||||
}))
|
||||
|
||||
// Mock mitt context
|
||||
const mockEmit = vi.fn()
|
||||
vi.mock('@/context/mitt-context', () => ({
|
||||
useMittContextSelector: () => mockEmit,
|
||||
}))
|
||||
|
||||
// Mock useCanInstallPluginFromMarketplace
|
||||
vi.mock('@/app/components/plugins/plugin-page/use-reference-setting', () => ({
|
||||
useCanInstallPluginFromMarketplace: () => ({ canInstallPluginFromMarketplace: true }),
|
||||
@ -530,25 +524,6 @@ describe('Install Component', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('should emit plugin:install:success event on successful installation', async () => {
|
||||
render(<Install {...defaultProps} />)
|
||||
|
||||
// Select all plugins
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByTestId('select-all-plugins'))
|
||||
})
|
||||
|
||||
// Click install
|
||||
const installButton = screen.getByText(/plugin\.installModal\.install/i)
|
||||
await act(async () => {
|
||||
fireEvent.click(installButton)
|
||||
})
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockEmit).toHaveBeenCalledWith('plugin:install:success', expect.any(Array))
|
||||
})
|
||||
})
|
||||
|
||||
it('should disable install button when no plugins are selected', async () => {
|
||||
render(<Install {...defaultProps} />)
|
||||
|
||||
|
||||
@ -1,13 +1,7 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import type {
|
||||
Dependency,
|
||||
InstallStatus,
|
||||
InstallStatusResponse,
|
||||
Plugin,
|
||||
VersionInfo,
|
||||
VersionProps,
|
||||
} from '../../../types'
|
||||
import type { Dependency, InstallStatusResponse, Plugin, VersionInfo } from '../../../types'
|
||||
import type { InstallBundleCompleteCallback } from '../index'
|
||||
import type { ExposeRefs } from './install-multi'
|
||||
import { Button } from '@langgenius/dify-ui/button'
|
||||
import { Checkbox } from '@langgenius/dify-ui/checkbox'
|
||||
@ -16,7 +10,6 @@ import * as React from 'react'
|
||||
import { useCallback, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useCanInstallPluginFromMarketplace } from '@/app/components/plugins/plugin-page/use-reference-setting'
|
||||
import { useMittContextSelector } from '@/context/mitt-context'
|
||||
import { useInstallOrUpdate, usePluginTaskList } from '@/service/use-plugins'
|
||||
import { TaskStatus } from '../../../types'
|
||||
import checkTaskStatus from '../../base/check-task-status'
|
||||
@ -29,11 +22,7 @@ const i18nPrefix = 'installModal'
|
||||
type Props = Readonly<{
|
||||
allPlugins: Dependency[]
|
||||
onStartToInstall?: () => void
|
||||
onInstalled: (
|
||||
plugins: Plugin[],
|
||||
installStatus: InstallStatus[],
|
||||
versionInfo: VersionProps[],
|
||||
) => void
|
||||
onInstalled: InstallBundleCompleteCallback
|
||||
onCancel: () => void
|
||||
isFromMarketPlace?: boolean
|
||||
isHideButton?: boolean
|
||||
@ -48,7 +37,6 @@ const Install: FC<Props> = ({
|
||||
isHideButton,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const emit = useMittContextSelector((s) => s.emit)
|
||||
const [selectedPlugins, setSelectedPlugins] = React.useState<Plugin[]>([])
|
||||
const [selectedIndexes, setSelectedIndexes] = React.useState<number[]>([])
|
||||
const selectedPluginsNum = selectedPlugins.length
|
||||
@ -113,12 +101,6 @@ const Install: FC<Props> = ({
|
||||
const hasInstallSuccess = res.some((r) => r.status === TaskStatus.success)
|
||||
if (hasInstallSuccess) {
|
||||
refreshPluginList(undefined, true)
|
||||
emit(
|
||||
'plugin:install:success',
|
||||
selectedPlugins.map((p) => {
|
||||
return `${p.plugin_id}/${p.name}`
|
||||
}),
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -143,15 +125,6 @@ const Install: FC<Props> = ({
|
||||
}),
|
||||
)
|
||||
onInstalled(selectedPlugins, installStatus, getSelectedVersionInfo())
|
||||
const hasInstallSuccess = installStatus.some((r) => r.success)
|
||||
if (hasInstallSuccess) {
|
||||
emit(
|
||||
'plugin:install:success',
|
||||
selectedPlugins.map((p) => {
|
||||
return `${p.plugin_id}/${p.name}`
|
||||
}),
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
const handleInstall = () => {
|
||||
|
||||
@ -1,10 +1,15 @@
|
||||
'use client'
|
||||
|
||||
import type { InstallBundleCompleteCallback } from '@/app/components/plugins/install-plugin/install-bundle'
|
||||
import { useCallback } from 'react'
|
||||
import InstallBundle from '@/app/components/plugins/install-plugin/install-bundle'
|
||||
import { useStore } from './store'
|
||||
|
||||
const PluginDependency = () => {
|
||||
type Props = {
|
||||
onInstallComplete?: InstallBundleCompleteCallback
|
||||
}
|
||||
|
||||
const PluginDependency = ({ onInstallComplete }: Props) => {
|
||||
const dependencies = useStore((s) => s.dependencies)
|
||||
|
||||
const handleCancelInstallBundle = useCallback(() => {
|
||||
@ -14,7 +19,13 @@ const PluginDependency = () => {
|
||||
|
||||
if (!dependencies.length) return null
|
||||
|
||||
return <InstallBundle fromDSLPayload={dependencies} onClose={handleCancelInstallBundle} />
|
||||
return (
|
||||
<InstallBundle
|
||||
fromDSLPayload={dependencies}
|
||||
onClose={handleCancelInstallBundle}
|
||||
onInstallComplete={onInstallComplete}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default PluginDependency
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import type { ReactNode } from 'react'
|
||||
import { useMitt } from '@/hooks/use-mitt'
|
||||
import { MittContext } from './mitt-context'
|
||||
|
||||
type MittProviderProps = {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export const MittProvider = ({ children }: MittProviderProps) => {
|
||||
const mitt = useMitt()
|
||||
|
||||
return <MittContext.Provider value={mitt}>{children}</MittContext.Provider>
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import type { useMitt } from '@/hooks/use-mitt'
|
||||
import { noop } from 'es-toolkit/function'
|
||||
import { createContext, useContextSelector } from 'use-context-selector'
|
||||
|
||||
type ContextValueType = ReturnType<typeof useMitt>
|
||||
export const MittContext = createContext<ContextValueType>({
|
||||
emit: noop,
|
||||
useSubscribe: noop,
|
||||
})
|
||||
|
||||
export function useMittContextSelector<T>(selector: (value: ContextValueType) => T): T {
|
||||
return useContextSelector(MittContext, selector)
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user