From 95166806ae751c3cc09c9f259d73e728e13fb942 Mon Sep 17 00:00:00 2001 From: yyh <92089059+lyzno1@users.noreply.github.com> Date: Thu, 30 Jul 2026 15:07:43 +0800 Subject: [PATCH] refactor(web): remove configuration mitt context (#39796) --- oxlint-suppressions.json | 2 +- .../__tests__/configuration-view.spec.tsx | 106 +++++++++++++++++- .../agent-tools/__tests__/index.spec.tsx | 37 +----- .../config/agent/agent-tools/index.tsx | 16 --- .../app/configuration/configuration-view.tsx | 26 ++++- .../install-bundle/__tests__/index.spec.tsx | 5 - .../__tests__/ready-to-install.spec.tsx | 7 ++ .../install-plugin/install-bundle/index.tsx | 11 +- .../install-bundle/ready-to-install.tsx | 6 +- .../steps/__tests__/install.spec.tsx | 25 ----- .../install-bundle/steps/install.tsx | 33 +----- .../workflow/plugin-dependency/index.tsx | 15 ++- web/context/mitt-context-provider.tsx | 15 --- web/context/mitt-context.ts | 15 --- 14 files changed, 167 insertions(+), 152 deletions(-) delete mode 100644 web/context/mitt-context-provider.tsx delete mode 100644 web/context/mitt-context.ts diff --git a/oxlint-suppressions.json b/oxlint-suppressions.json index aa6b95541ae..643f838f8de 100644 --- a/oxlint-suppressions.json +++ b/oxlint-suppressions.json @@ -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": { diff --git a/web/app/components/app/configuration/__tests__/configuration-view.spec.tsx b/web/app/components/app/configuration/__tests__/configuration-view.spec.tsx index bae633b0c27..0a8e09172d8 100644 --- a/web/app/components/app/configuration/__tests__/configuration-view.spec.tsx +++ b/web/app/components/app/configuration/__tests__/configuration-view.spec.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: () =>
, })) +let pluginDependencyOnInstallComplete: InstallBundleCompleteCallback | undefined vi.mock('@/app/components/workflow/plugin-dependency', () => ({ - default: () =>
, + default: ({ onInstallComplete }: { onInstallComplete?: InstallBundleCompleteCallback }) => { + pluginDependencyOnInstallComplete = onInstallComplete + return
+ }, })) +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['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() + 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() + 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() + + expect(pluginDependencyOnInstallComplete).toBeUndefined() + }) }) diff --git a/web/app/components/app/configuration/config/agent/agent-tools/__tests__/index.spec.tsx b/web/app/components/app/configuration/config/agent/agent-tools/__tests__/index.spec.tsx index f47e3d94b40..757800df08f 100644 --- a/web/app/components/app/configuration/config/agent/agent-tools/__tests__/index.spec.tsx +++ b/web/app/components/app/configuration/config/agent/agent-tools/__tests__/index.spec.tsx @@ -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, - ) - }) - }) }) diff --git a/web/app/components/app/configuration/config/agent/agent-tools/index.tsx b/web/app/components/app/configuration/config/agent/agent-tools/index.tsx index 9a4ea6422d6..add510e6274 100644 --- a/web/app/components/app/configuration/config/agent/agent-tools/index.tsx +++ b/web/app/components/app/configuration/config/agent/agent-tools/index.tsx @@ -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) => { const newModelConfig = produce(modelConfig, (draft) => { const tool = draft.agentConfig.tools.find( diff --git a/web/app/components/app/configuration/configuration-view.tsx b/web/app/components/app/configuration/configuration-view.tsx index aa0425b5cb3..52333f830f9 100644 --- a/web/app/components/app/configuration/configuration-view.tsx +++ b/web/app/components/app/configuration/configuration-view.tsx @@ -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 = ({ 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 = ({ return ( - + <>
@@ -312,8 +330,8 @@ const ConfigurationView: FC = ({ onAutoAddPromptVariable={onAutoAddPromptVariable} /> )} - - + + ) diff --git a/web/app/components/plugins/install-plugin/install-bundle/__tests__/index.spec.tsx b/web/app/components/plugins/install-plugin/install-bundle/__tests__/index.spec.tsx index f53b12ed78e..55eb99c4e4f 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/__tests__/index.spec.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/__tests__/index.spec.tsx @@ -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 }), diff --git a/web/app/components/plugins/install-plugin/install-bundle/__tests__/ready-to-install.spec.tsx b/web/app/components/plugins/install-plugin/install-bundle/__tests__/ready-to-install.spec.tsx index bd0a8a49f33..4735718e8c7 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/__tests__/ready-to-install.spec.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/__tests__/ready-to-install.spec.tsx @@ -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', () => { diff --git a/web/app/components/plugins/install-plugin/install-bundle/index.tsx b/web/app/components/plugins/install-plugin/install-bundle/index.tsx index 6f6587e37e6..b30538f80e2 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/index.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/index.tsx @@ -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 = ({ installType = InstallType.fromMarketplace, fromDSLPayload, onClose, + onInstallComplete, }) => { const { t } = useTranslation() const [step, setStep] = useState( @@ -78,6 +86,7 @@ const InstallBundle: FC = ({ setIsInstalling={setIsInstalling} allPlugins={fromDSLPayload} onClose={onClose} + onInstallComplete={onInstallComplete} /> diff --git a/web/app/components/plugins/install-plugin/install-bundle/ready-to-install.tsx b/web/app/components/plugins/install-plugin/install-bundle/ready-to-install.tsx index 99e7a1f1c12..816da2390e7 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/ready-to-install.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/ready-to-install.tsx @@ -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 = ({ setIsInstalling, allPlugins, onClose, + onInstallComplete, isFromMarketPlace, }) => { const [installedPlugins, setInstalledPlugins] = useState([]) @@ -36,8 +39,9 @@ const ReadyToInstall: FC = ({ setInstalledVersionInfo(versionInfo) onStepChange(InstallStep.installed) setIsInstalling(false) + onInstallComplete?.(plugins, installStatus, versionInfo) }, - [onStepChange, setIsInstalling], + [onInstallComplete, onStepChange, setIsInstalling], ) return ( <> diff --git a/web/app/components/plugins/install-plugin/install-bundle/steps/__tests__/install.spec.tsx b/web/app/components/plugins/install-plugin/install-bundle/steps/__tests__/install.spec.tsx index dbcbf9c1533..b65acff3079 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/steps/__tests__/install.spec.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/steps/__tests__/install.spec.tsx @@ -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() - - // 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() diff --git a/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx b/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx index 39ebc7bbe43..419b07a6b6d 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx @@ -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 = ({ isHideButton, }) => { const { t } = useTranslation() - const emit = useMittContextSelector((s) => s.emit) const [selectedPlugins, setSelectedPlugins] = React.useState([]) const [selectedIndexes, setSelectedIndexes] = React.useState([]) const selectedPluginsNum = selectedPlugins.length @@ -113,12 +101,6 @@ const Install: FC = ({ 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 = ({ }), ) 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 = () => { diff --git a/web/app/components/workflow/plugin-dependency/index.tsx b/web/app/components/workflow/plugin-dependency/index.tsx index 6fe95e0a321..21f3f648330 100644 --- a/web/app/components/workflow/plugin-dependency/index.tsx +++ b/web/app/components/workflow/plugin-dependency/index.tsx @@ -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 + return ( + + ) } export default PluginDependency diff --git a/web/context/mitt-context-provider.tsx b/web/context/mitt-context-provider.tsx deleted file mode 100644 index 7fee75eb5b6..00000000000 --- a/web/context/mitt-context-provider.tsx +++ /dev/null @@ -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 {children} -} diff --git a/web/context/mitt-context.ts b/web/context/mitt-context.ts deleted file mode 100644 index 66616d70913..00000000000 --- a/web/context/mitt-context.ts +++ /dev/null @@ -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 -export const MittContext = createContext({ - emit: noop, - useSubscribe: noop, -}) - -export function useMittContextSelector(selector: (value: ContextValueType) => T): T { - return useContextSelector(MittContext, selector) -}