diff --git a/web/app/components/plugins/install-plugin/__tests__/hooks.spec.ts b/web/app/components/plugins/install-plugin/__tests__/hooks.spec.ts index 918a9b36e3..a770a6f2be 100644 --- a/web/app/components/plugins/install-plugin/__tests__/hooks.spec.ts +++ b/web/app/components/plugins/install-plugin/__tests__/hooks.spec.ts @@ -3,7 +3,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' import { useGitHubReleases, useGitHubUpload } from '../hooks' const mockNotify = vi.fn() -vi.mock('@/app/components/base/toast', () => ({ +vi.mock('@/app/components/plugins/utils/toast', () => ({ default: { notify: (...args: unknown[]) => mockNotify(...args) }, })) diff --git a/web/app/components/plugins/install-plugin/hooks.ts b/web/app/components/plugins/install-plugin/hooks.ts index 2addba4a04..cb1d77480f 100644 --- a/web/app/components/plugins/install-plugin/hooks.ts +++ b/web/app/components/plugins/install-plugin/hooks.ts @@ -1,6 +1,6 @@ import type { GitHubRepoReleaseResponse } from '../types' -import type { IToastProps } from '@/app/components/base/toast' -import Toast from '@/app/components/base/toast' +import type { LegacyToastOptions } from '@/app/components/plugins/utils/toast' +import Toast from '@/app/components/plugins/utils/toast' import { GITHUB_ACCESS_TOKEN } from '@/config' import { uploadGitHub } from '@/service/plugins' import { compareVersion, getLatestVersion } from '@/utils/semver' @@ -54,7 +54,7 @@ export const useGitHubReleases = () => { const checkForUpdates = (fetchedReleases: GitHubRepoReleaseResponse[], currentVersion: string) => { let needUpdate = false - const toastProps: IToastProps = { + const toastProps: LegacyToastOptions = { type: 'info', message: 'No new version available', } diff --git a/web/app/components/plugins/install-plugin/install-from-github/__tests__/index.spec.tsx b/web/app/components/plugins/install-plugin/install-from-github/__tests__/index.spec.tsx index 0fe6b88ed8..a076b93702 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/__tests__/index.spec.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/__tests__/index.spec.tsx @@ -57,7 +57,7 @@ const createUpdatePayload = (overrides: Partial = {}): // Mock external dependencies const mockNotify = vi.fn() -vi.mock('@/app/components/base/toast', () => ({ +vi.mock('@/app/components/plugins/utils/toast', () => ({ default: { notify: (props: { type: string, message: string }) => mockNotify(props), }, diff --git a/web/app/components/plugins/install-plugin/install-from-github/index.tsx b/web/app/components/plugins/install-plugin/install-from-github/index.tsx index 91425031cf..c5111f65c1 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/index.tsx @@ -7,8 +7,8 @@ import * as React from 'react' import { useCallback, useState } from 'react' import { useTranslation } from 'react-i18next' import Modal from '@/app/components/base/modal' -import Toast from '@/app/components/base/toast' import useGetIcon from '@/app/components/plugins/install-plugin/base/use-get-icon' +import Toast from '@/app/components/plugins/utils/toast' import { cn } from '@/utils/classnames' import { InstallStepFromGitHub } from '../../types' import Installed from '../base/installed' diff --git a/web/app/components/plugins/plugin-detail-panel/__tests__/detail-header.spec.tsx b/web/app/components/plugins/plugin-detail-panel/__tests__/detail-header.spec.tsx index f0ec5b6c83..d7284c6dbc 100644 --- a/web/app/components/plugins/plugin-detail-panel/__tests__/detail-header.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/__tests__/detail-header.spec.tsx @@ -2,7 +2,7 @@ import type { PluginDetail } from '../../types' import { fireEvent, render, screen, waitFor } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' import * as amplitude from '@/app/components/base/amplitude' -import Toast from '@/app/components/base/toast' +import Toast from '@/app/components/plugins/utils/toast' import { PluginSource } from '../../types' import DetailHeader from '../detail-header' diff --git a/web/app/components/plugins/plugin-detail-panel/__tests__/endpoint-card.spec.tsx b/web/app/components/plugins/plugin-detail-panel/__tests__/endpoint-card.spec.tsx index 480f399c91..ad03bf573b 100644 --- a/web/app/components/plugins/plugin-detail-panel/__tests__/endpoint-card.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/__tests__/endpoint-card.spec.tsx @@ -1,7 +1,7 @@ import type { EndpointListItem, PluginDetail } from '../../types' import { act, fireEvent, render, screen } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' -import Toast from '@/app/components/base/toast' +import Toast from '@/app/components/plugins/utils/toast' import EndpointCard from '../endpoint-card' const mockHandleChange = vi.fn() @@ -127,7 +127,7 @@ describe('EndpointCard', () => { failureFlags.disable = false failureFlags.delete = false failureFlags.update = false - // Mock Toast.notify to prevent toast elements from accumulating in DOM + // Mock notifyToast to prevent toast elements from accumulating in DOM vi.spyOn(Toast, 'notify').mockImplementation(() => ({ clear: vi.fn() })) // Polyfill document.execCommand for copy-to-clipboard in jsdom if (typeof document.execCommand !== 'function') { diff --git a/web/app/components/plugins/plugin-detail-panel/__tests__/endpoint-modal.spec.tsx b/web/app/components/plugins/plugin-detail-panel/__tests__/endpoint-modal.spec.tsx index 1dfe31c6b1..1cc1040bb8 100644 --- a/web/app/components/plugins/plugin-detail-panel/__tests__/endpoint-modal.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/__tests__/endpoint-modal.spec.tsx @@ -2,7 +2,7 @@ import type { FormSchema } from '../../../base/form/types' import type { PluginDetail } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' -import Toast from '@/app/components/base/toast' +import Toast from '@/app/components/plugins/utils/toast' import EndpointModal from '../endpoint-modal' vi.mock('@/hooks/use-i18n', () => ({ diff --git a/web/app/components/plugins/plugin-detail-panel/detail-header/hooks/__tests__/use-plugin-operations.spec.ts b/web/app/components/plugins/plugin-detail-panel/detail-header/hooks/__tests__/use-plugin-operations.spec.ts index 0fcec7f16b..b0182dcfbd 100644 --- a/web/app/components/plugins/plugin-detail-panel/detail-header/hooks/__tests__/use-plugin-operations.spec.ts +++ b/web/app/components/plugins/plugin-detail-panel/detail-header/hooks/__tests__/use-plugin-operations.spec.ts @@ -3,7 +3,7 @@ import type { ModalStates, VersionTarget } from '../use-detail-header-state' import { act, renderHook } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' import * as amplitude from '@/app/components/base/amplitude' -import Toast from '@/app/components/base/toast' +import Toast from '@/app/components/plugins/utils/toast' import { PluginSource } from '../../../../types' import { usePluginOperations } from '../use-plugin-operations' @@ -233,7 +233,7 @@ describe('usePluginOperations', () => { }) expect(mockCheckForUpdates).toHaveBeenCalled() - expect(Toast.notify).toHaveBeenCalled() + expect(notifyToast).toHaveBeenCalled() }) it('should show update plugin modal when update is needed', async () => { diff --git a/web/app/components/plugins/plugin-detail-panel/detail-header/hooks/use-plugin-operations.ts b/web/app/components/plugins/plugin-detail-panel/detail-header/hooks/use-plugin-operations.ts index bf6bb4aae6..1272945321 100644 --- a/web/app/components/plugins/plugin-detail-panel/detail-header/hooks/use-plugin-operations.ts +++ b/web/app/components/plugins/plugin-detail-panel/detail-header/hooks/use-plugin-operations.ts @@ -5,7 +5,8 @@ import type { ModalStates, VersionTarget } from './use-detail-header-state' import { useCallback } from 'react' import { useTranslation } from 'react-i18next' import { trackEvent } from '@/app/components/base/amplitude' -import Toast from '@/app/components/base/toast' +import { toast } from '@/app/components/base/ui/toast' +import Toast from '@/app/components/plugins/utils/toast' import { useModalContext } from '@/context/modal-context' import { useProviderContext } from '@/context/provider-context' import { uninstallPlugin } from '@/service/plugins' @@ -74,7 +75,7 @@ export const usePluginOperations = ({ return const { needUpdate, toastProps } = checkForUpdates(fetchedReleases, meta.version) - Toast.notify(toastProps) + toast(toastProps) if (needUpdate) { setShowUpdatePluginModal({ diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx index 164bab0f04..043fb0a334 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx @@ -9,9 +9,9 @@ import ActionButton from '@/app/components/base/action-button' import Confirm from '@/app/components/base/confirm' import { CopyCheck } from '@/app/components/base/icons/src/vender/line/files' import Switch from '@/app/components/base/switch' -import Toast from '@/app/components/base/toast' import Tooltip from '@/app/components/base/tooltip' import Indicator from '@/app/components/header/indicator' +import Toast from '@/app/components/plugins/utils/toast' import { addDefaultValue, toolCredentialToFormSchemas } from '@/app/components/tools/utils/to-form-schema' import { useDeleteEndpoint, diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx index 357e714ba2..1d579fa2a9 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx @@ -9,8 +9,8 @@ import * as React from 'react' import { useMemo } from 'react' import { useTranslation } from 'react-i18next' import ActionButton from '@/app/components/base/action-button' -import Toast from '@/app/components/base/toast' import Tooltip from '@/app/components/base/tooltip' +import Toast from '@/app/components/plugins/utils/toast' import { toolCredentialToFormSchemas } from '@/app/components/tools/utils/to-form-schema' import { useDocLink } from '@/context/i18n' import { diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx index 929e990f90..0442426286 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx @@ -8,8 +8,8 @@ import { useTranslation } from 'react-i18next' import ActionButton from '@/app/components/base/action-button' import Button from '@/app/components/base/button' import Drawer from '@/app/components/base/drawer' -import Toast from '@/app/components/base/toast' import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form' +import Toast from '@/app/components/plugins/utils/toast' import { useRenderI18nObject } from '@/hooks/use-i18n' import { cn } from '@/utils/classnames' import { ReadmeEntrance } from '../readme-panel/entrance' diff --git a/web/app/components/plugins/plugin-detail-panel/model-selector/__tests__/index.spec.tsx b/web/app/components/plugins/plugin-detail-panel/model-selector/__tests__/index.spec.tsx index 9b04a710e0..ec7ccccf57 100644 --- a/web/app/components/plugins/plugin-detail-panel/model-selector/__tests__/index.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/model-selector/__tests__/index.spec.tsx @@ -1,10 +1,10 @@ import type { Model, ModelItem } from '@/app/components/header/account-setting/model-provider-page/declarations' import { fireEvent, render, screen, waitFor } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' -// Import component after mocks -import Toast from '@/app/components/base/toast' - import { ConfigurationMethodEnum, ModelStatusEnum, ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' + +// Import component after mocks +import Toast from '@/app/components/plugins/utils/toast' import ModelParameterModal from '../index' // ==================== Mock Setup ==================== @@ -865,7 +865,7 @@ describe('ModelParameterModal', () => { // Assert await waitFor(() => { - expect(Toast.notify).toHaveBeenCalledWith( + expect(notifyToast).toHaveBeenCalledWith( expect.objectContaining({ type: 'warning' }), ) }) @@ -892,7 +892,7 @@ describe('ModelParameterModal', () => { // Assert await waitFor(() => { - expect(Toast.notify).toHaveBeenCalledWith( + expect(notifyToast).toHaveBeenCalledWith( expect.objectContaining({ type: 'error' }), ) }) diff --git a/web/app/components/plugins/plugin-detail-panel/model-selector/index.tsx b/web/app/components/plugins/plugin-detail-panel/model-selector/index.tsx index 04b78f98b7..cebfa1af89 100644 --- a/web/app/components/plugins/plugin-detail-panel/model-selector/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/model-selector/index.tsx @@ -10,7 +10,6 @@ import type { import type { TriggerProps } from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal/trigger' import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' -import Toast from '@/app/components/base/toast' import { Popover, PopoverContent, @@ -23,6 +22,7 @@ import { import AgentModelTrigger from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal/agent-model-trigger' import Trigger from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal/trigger' import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector' +import Toast from '@/app/components/plugins/utils/toast' import { useProviderContext } from '@/context/provider-context' import { cn } from '@/utils/classnames' import { fetchAndMergeValidCompletionParams } from '@/utils/completion-params' diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/__tests__/log-viewer.spec.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/__tests__/log-viewer.spec.tsx index c6fb42faab..0dcff61db2 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/__tests__/log-viewer.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/__tests__/log-viewer.spec.tsx @@ -1,7 +1,7 @@ import type { TriggerLogEntity } from '@/app/components/workflow/block-selector/types' import { cleanup, fireEvent, render, screen } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' -import Toast from '@/app/components/base/toast' +import Toast from '@/app/components/plugins/utils/toast' import LogViewer from '../log-viewer' const mockToastNotify = vi.fn() diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/__tests__/selector-entry.spec.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/__tests__/selector-entry.spec.tsx index d8d41ff9b2..e3f578db32 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/__tests__/selector-entry.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/__tests__/selector-entry.spec.tsx @@ -26,7 +26,7 @@ vi.mock('@/service/use-triggers', () => ({ useDeleteTriggerSubscription: () => ({ mutate: vi.fn(), isPending: false }), })) -vi.mock('@/app/components/base/toast', () => ({ +vi.mock('@/app/components/plugins/utils/toast', () => ({ default: { notify: vi.fn(), }, diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/__tests__/selector-view.spec.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/__tests__/selector-view.spec.tsx index 83d0cdd89d..9c6fe6363d 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/__tests__/selector-view.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/__tests__/selector-view.spec.tsx @@ -1,7 +1,7 @@ import type { TriggerSubscription } from '@/app/components/workflow/block-selector/types' import { fireEvent, render, screen } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' -import Toast from '@/app/components/base/toast' +import Toast from '@/app/components/plugins/utils/toast' import { TriggerCredentialTypeEnum } from '@/app/components/workflow/block-selector/types' import { SubscriptionSelectorView } from '../selector-view' diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/__tests__/subscription-card.spec.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/__tests__/subscription-card.spec.tsx index a51bc2954f..ffc198a9d8 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/__tests__/subscription-card.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/__tests__/subscription-card.spec.tsx @@ -1,7 +1,7 @@ import type { TriggerSubscription } from '@/app/components/workflow/block-selector/types' import { fireEvent, render, screen } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' -import Toast from '@/app/components/base/toast' +import Toast from '@/app/components/plugins/utils/toast' import { TriggerCredentialTypeEnum } from '@/app/components/workflow/block-selector/types' import SubscriptionCard from '../subscription-card' diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/__tests__/common-modal.spec.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/__tests__/common-modal.spec.tsx index 21a4c3defa..a58a30eca8 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/__tests__/common-modal.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/__tests__/common-modal.spec.tsx @@ -122,7 +122,7 @@ vi.mock('@/utils/urlValidation', () => ({ })) const mockToastNotify = vi.fn() -vi.mock('@/app/components/base/toast', () => ({ +vi.mock('@/app/components/plugins/utils/toast', () => ({ default: { notify: (params: unknown) => mockToastNotify(params), }, diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/__tests__/index.spec.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/__tests__/index.spec.tsx index 3fe9884b92..01f22149b9 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/__tests__/index.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/__tests__/index.spec.tsx @@ -3,6 +3,7 @@ import type { TriggerOAuthConfig, TriggerProviderApiEntity, TriggerSubscription, import { fireEvent, render, screen, waitFor } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' import { SupportedCreationMethods } from '@/app/components/plugins/types' +import Toast from '@/app/components/plugins/utils/toast' import { TriggerCredentialTypeEnum } from '@/app/components/workflow/block-selector/types' import { CreateButtonType, CreateSubscriptionButton, DEFAULT_METHOD } from '../index' @@ -33,7 +34,7 @@ vi.mock('@/app/components/base/portal-to-follow-elem', () => ({ }, })) -vi.mock('@/app/components/base/toast', () => ({ +vi.mock('@/app/components/plugins/utils/toast', () => ({ default: { notify: vi.fn(), }, @@ -908,8 +909,6 @@ describe('CreateSubscriptionButton', () => { it('should handle OAuth initiation error', async () => { // Arrange - const Toast = await import('@/app/components/base/toast') - mockInitiateOAuth.mockImplementation((_provider: string, callbacks: { onError: () => void }) => { callbacks.onError() }) @@ -932,7 +931,7 @@ describe('CreateSubscriptionButton', () => { // Assert await waitFor(() => { - expect(Toast.default.notify).toHaveBeenCalledWith( + expect(Toast.notify).toHaveBeenCalledWith( expect.objectContaining({ type: 'error' }), ) }) diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/__tests__/oauth-client.spec.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/__tests__/oauth-client.spec.tsx index 12419a9bf3..8b1ce7320b 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/__tests__/oauth-client.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/__tests__/oauth-client.spec.tsx @@ -86,7 +86,7 @@ vi.mock('@/hooks/use-oauth', () => ({ })) const mockToastNotify = vi.fn() -vi.mock('@/app/components/base/toast', () => ({ +vi.mock('@/app/components/plugins/utils/toast', () => ({ default: { notify: (params: unknown) => mockToastNotify(params), }, diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/hooks/__tests__/use-oauth-client-state.spec.ts b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/hooks/__tests__/use-oauth-client-state.spec.ts index 89566f3af7..f2b420ff06 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/hooks/__tests__/use-oauth-client-state.spec.ts +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/hooks/__tests__/use-oauth-client-state.spec.ts @@ -77,7 +77,7 @@ vi.mock('@/hooks/use-oauth', () => ({ })) const mockToastNotify = vi.fn() -vi.mock('@/app/components/base/toast', () => ({ +vi.mock('@/app/components/plugins/utils/toast', () => ({ default: { notify: (params: unknown) => mockToastNotify(params), }, diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/hooks/use-common-modal-state.ts b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/hooks/use-common-modal-state.ts index b01312d3d1..62868682db 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/hooks/use-common-modal-state.ts +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/hooks/use-common-modal-state.ts @@ -7,8 +7,8 @@ import type { BuildTriggerSubscriptionPayload } from '@/service/use-triggers' import { debounce } from 'es-toolkit/compat' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' -import Toast from '@/app/components/base/toast' import { SupportedCreationMethods } from '@/app/components/plugins/types' +import Toast from '@/app/components/plugins/utils/toast' import { TriggerCredentialTypeEnum } from '@/app/components/workflow/block-selector/types' import { useBuildTriggerSubscription, diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/hooks/use-oauth-client-state.ts b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/hooks/use-oauth-client-state.ts index 6a551051e2..66bb0cba81 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/hooks/use-oauth-client-state.ts +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/hooks/use-oauth-client-state.ts @@ -4,7 +4,7 @@ import type { TriggerOAuthClientParams, TriggerOAuthConfig, TriggerSubscriptionB import type { ConfigureTriggerOAuthPayload } from '@/service/use-triggers' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' -import Toast from '@/app/components/base/toast' +import Toast from '@/app/components/plugins/utils/toast' import { openOAuthPopup } from '@/hooks/use-oauth' import { useConfigureTriggerOAuth, diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/index.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/index.tsx index eecaf165fb..6360991766 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/index.tsx @@ -8,8 +8,8 @@ import { ActionButton, ActionButtonState } from '@/app/components/base/action-bu import Badge from '@/app/components/base/badge' import { Button } from '@/app/components/base/button' import CustomSelect from '@/app/components/base/select/custom' -import Toast from '@/app/components/base/toast' import Tooltip from '@/app/components/base/tooltip' +import Toast from '@/app/components/plugins/utils/toast' import { openOAuthPopup } from '@/hooks/use-oauth' import { useInitiateTriggerOAuth, useTriggerOAuthConfig, useTriggerProviderInfo } from '@/service/use-triggers' import { cn } from '@/utils/classnames' diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/oauth-client.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/oauth-client.tsx index b7f9b8ebec..256eda0d2f 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/oauth-client.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/oauth-client.tsx @@ -8,7 +8,7 @@ import { useTranslation } from 'react-i18next' import Button from '@/app/components/base/button' import { BaseForm } from '@/app/components/base/form/components/base' import Modal from '@/app/components/base/modal/modal' -import Toast from '@/app/components/base/toast' +import Toast from '@/app/components/plugins/utils/toast' import OptionCard from '@/app/components/workflow/nodes/_base/components/option-card' import { usePluginStore } from '../../store' import { ClientTypeEnum, useOAuthClientState } from './hooks/use-oauth-client-state' diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/__tests__/apikey-edit-modal.spec.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/__tests__/apikey-edit-modal.spec.tsx index e0fb7455ce..987ca8dda8 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/__tests__/apikey-edit-modal.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/__tests__/apikey-edit-modal.spec.tsx @@ -47,8 +47,8 @@ vi.mock('@/service/use-triggers', () => ({ useTriggerPluginDynamicOptions: () => ({ data: [], isLoading: false }), })) -vi.mock('@/app/components/base/toast', async (importOriginal) => { - const actual = await importOriginal() +vi.mock('@/app/components/plugins/utils/toast', async (importOriginal) => { + const actual = await importOriginal() return { ...actual, default: { @@ -57,7 +57,7 @@ vi.mock('@/app/components/base/toast', async (importOriginal) => { } }) -vi.mock('@/app/components/base/toast/context', () => ({ +vi.mock('@/app/components/plugins/utils/toast/context', () => ({ useToastContext: () => ({ notify: (args: { type: string, message: string }) => mockToast(args), close: vi.fn(), diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/__tests__/index.spec.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/__tests__/index.spec.tsx index 7d188a3f6d..f9e9a3625a 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/__tests__/index.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/__tests__/index.spec.tsx @@ -13,7 +13,7 @@ import { OAuthEditModal } from '../oauth-edit-modal' // ==================== Mock Setup ==================== const mockToastNotify = vi.fn() -vi.mock('@/app/components/base/toast', () => ({ +vi.mock('@/app/components/plugins/utils/toast', () => ({ default: { notify: (params: unknown) => mockToastNotify(params) }, })) diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/__tests__/manual-edit-modal.spec.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/__tests__/manual-edit-modal.spec.tsx index 60a8428287..343f3cd5cd 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/__tests__/manual-edit-modal.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/__tests__/manual-edit-modal.spec.tsx @@ -30,8 +30,8 @@ vi.mock('@/service/use-triggers', () => ({ useTriggerPluginDynamicOptions: () => ({ data: [], isLoading: false }), })) -vi.mock('@/app/components/base/toast', async (importOriginal) => { - const actual = await importOriginal() +vi.mock('@/app/components/plugins/utils/toast', async (importOriginal) => { + const actual = await importOriginal() return { ...actual, default: { @@ -40,7 +40,7 @@ vi.mock('@/app/components/base/toast', async (importOriginal) => { } }) -vi.mock('@/app/components/base/toast/context', () => ({ +vi.mock('@/app/components/plugins/utils/toast/context', () => ({ useToastContext: () => ({ notify: (args: { type: string, message: string }) => mockToast(args), close: vi.fn(), diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/__tests__/oauth-edit-modal.spec.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/__tests__/oauth-edit-modal.spec.tsx index 8835b46695..996946aa8d 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/__tests__/oauth-edit-modal.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/__tests__/oauth-edit-modal.spec.tsx @@ -30,8 +30,8 @@ vi.mock('@/service/use-triggers', () => ({ useTriggerPluginDynamicOptions: () => ({ data: [], isLoading: false }), })) -vi.mock('@/app/components/base/toast', async (importOriginal) => { - const actual = await importOriginal() +vi.mock('@/app/components/plugins/utils/toast', async (importOriginal) => { + const actual = await importOriginal() return { ...actual, default: { @@ -40,7 +40,7 @@ vi.mock('@/app/components/base/toast', async (importOriginal) => { } }) -vi.mock('@/app/components/base/toast/context', () => ({ +vi.mock('@/app/components/plugins/utils/toast/context', () => ({ useToastContext: () => ({ notify: (args: { type: string, message: string }) => mockToast(args), close: vi.fn(), diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/apikey-edit-modal.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/apikey-edit-modal.tsx index a4093ed00b..b2b150abdc 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/apikey-edit-modal.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/apikey-edit-modal.tsx @@ -9,8 +9,8 @@ import { EncryptedBottom } from '@/app/components/base/encrypted-bottom' import { BaseForm } from '@/app/components/base/form/components/base' import { FormTypeEnum } from '@/app/components/base/form/types' import Modal from '@/app/components/base/modal/modal' -import Toast from '@/app/components/base/toast' import { ReadmeEntrance } from '@/app/components/plugins/readme-panel/entrance' +import Toast from '@/app/components/plugins/utils/toast' import { useUpdateTriggerSubscription, useVerifyTriggerSubscription } from '@/service/use-triggers' import { parsePluginErrorMessage } from '@/utils/error-parser' import { ReadmeShowType } from '../../../readme-panel/store' diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/manual-edit-modal.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/manual-edit-modal.tsx index 262235e6ed..a32e34a40f 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/manual-edit-modal.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/manual-edit-modal.tsx @@ -8,8 +8,8 @@ import { useTranslation } from 'react-i18next' import { BaseForm } from '@/app/components/base/form/components/base' import { FormTypeEnum } from '@/app/components/base/form/types' import Modal from '@/app/components/base/modal/modal' -import Toast from '@/app/components/base/toast' import { ReadmeEntrance } from '@/app/components/plugins/readme-panel/entrance' +import Toast from '@/app/components/plugins/utils/toast' import { useUpdateTriggerSubscription } from '@/service/use-triggers' import { ReadmeShowType } from '../../../readme-panel/store' import { usePluginStore } from '../../store' diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/oauth-edit-modal.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/oauth-edit-modal.tsx index e57b9c0151..12be46048a 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/oauth-edit-modal.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/edit/oauth-edit-modal.tsx @@ -8,8 +8,8 @@ import { useTranslation } from 'react-i18next' import { BaseForm } from '@/app/components/base/form/components/base' import { FormTypeEnum } from '@/app/components/base/form/types' import Modal from '@/app/components/base/modal/modal' -import Toast from '@/app/components/base/toast' import { ReadmeEntrance } from '@/app/components/plugins/readme-panel/entrance' +import Toast from '@/app/components/plugins/utils/toast' import { useUpdateTriggerSubscription } from '@/service/use-triggers' import { ReadmeShowType } from '../../../readme-panel/store' import { usePluginStore } from '../../store' diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/log-viewer.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/log-viewer.tsx index 3b4edd1b85..5be2bb83fd 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/log-viewer.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/log-viewer.tsx @@ -11,7 +11,7 @@ import dayjs from 'dayjs' import * as React from 'react' import { useState } from 'react' import { useTranslation } from 'react-i18next' -import Toast from '@/app/components/base/toast' +import Toast from '@/app/components/plugins/utils/toast' import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor' import { CodeLanguage } from '@/app/components/workflow/nodes/code/types' import { cn } from '@/utils/classnames' diff --git a/web/app/components/plugins/plugin-detail-panel/tool-selector/__tests__/index.spec.tsx b/web/app/components/plugins/plugin-detail-panel/tool-selector/__tests__/index.spec.tsx index 26e4de0fd7..9d9a4bf9dc 100644 --- a/web/app/components/plugins/plugin-detail-panel/tool-selector/__tests__/index.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/tool-selector/__tests__/index.spec.tsx @@ -298,7 +298,7 @@ vi.mock('@/app/components/header/account-setting/model-provider-page/model-modal // Mock Toast - need to track notify calls for assertions const mockToastNotify = vi.fn() -vi.mock('@/app/components/base/toast', () => ({ +vi.mock('@/app/components/plugins/utils/toast', () => ({ default: { notify: (...args: unknown[]) => mockToastNotify(...args) }, })) @@ -1943,7 +1943,7 @@ describe('ToolCredentialsForm Component', () => { const saveBtn = screen.getByText(/save/i) fireEvent.click(saveBtn) - // Toast.notify should have been called with error (lines 49-50) + // notifyToast should have been called with error (lines 49-50) expect(mockToastNotify).toHaveBeenCalledWith(expect.objectContaining({ type: 'error' })) // onSaved should not be called because validation fails expect(onSaved).not.toHaveBeenCalled() diff --git a/web/app/components/plugins/plugin-detail-panel/tool-selector/components/__tests__/tool-credentials-form.spec.tsx b/web/app/components/plugins/plugin-detail-panel/tool-selector/components/__tests__/tool-credentials-form.spec.tsx index cb5b929d29..fc632795fa 100644 --- a/web/app/components/plugins/plugin-detail-panel/tool-selector/components/__tests__/tool-credentials-form.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/tool-selector/components/__tests__/tool-credentials-form.spec.tsx @@ -10,11 +10,11 @@ vi.mock('@/utils/classnames', () => ({ cn: (...args: unknown[]) => args.filter(Boolean).join(' '), })) -vi.mock('@/app/components/base/toast', () => ({ +vi.mock('@/app/components/plugins/utils/toast', () => ({ default: { notify: vi.fn() }, })) -vi.mock('@/app/components/base/toast/context', () => ({ +vi.mock('@/app/components/plugins/utils/toast/context', () => ({ useToastContext: () => ({ notify: vi.fn() }), })) diff --git a/web/app/components/plugins/plugin-detail-panel/tool-selector/components/tool-credentials-form.tsx b/web/app/components/plugins/plugin-detail-panel/tool-selector/components/tool-credentials-form.tsx index 0207f65336..2a179b2219 100644 --- a/web/app/components/plugins/plugin-detail-panel/tool-selector/components/tool-credentials-form.tsx +++ b/web/app/components/plugins/plugin-detail-panel/tool-selector/components/tool-credentials-form.tsx @@ -10,8 +10,8 @@ import { useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import Button from '@/app/components/base/button' import Loading from '@/app/components/base/loading' -import Toast from '@/app/components/base/toast' import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form' +import Toast from '@/app/components/plugins/utils/toast' import { addDefaultValue, toolCredentialToFormSchemas } from '@/app/components/tools/utils/to-form-schema' import { useRenderI18nObject } from '@/hooks/use-i18n' import { fetchBuiltInToolCredential, fetchBuiltInToolCredentialSchema } from '@/service/tools' diff --git a/web/app/components/plugins/plugin-item/__tests__/action.spec.tsx b/web/app/components/plugins/plugin-item/__tests__/action.spec.tsx index 8467c983d8..763a952edd 100644 --- a/web/app/components/plugins/plugin-item/__tests__/action.spec.tsx +++ b/web/app/components/plugins/plugin-item/__tests__/action.spec.tsx @@ -1,7 +1,7 @@ import type { MetaData, PluginCategoryEnum } from '../../types' import { fireEvent, render, screen, waitFor } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' -import Toast from '@/app/components/base/toast' +import Toast from '@/app/components/plugins/utils/toast' // ==================== Imports (after mocks) ==================== @@ -140,12 +140,12 @@ const getActionButtons = () => screen.getAllByRole('button') const queryActionButtons = () => screen.queryAllByRole('button') describe('Action Component', () => { - // Spy on Toast.notify - real component but we track calls + // Spy on notifyToast - real component but we track calls let toastNotifySpy: ReturnType beforeEach(() => { vi.clearAllMocks() - // Spy on Toast.notify and mock implementation to avoid DOM side effects + // Spy on notifyToast and mock implementation to avoid DOM side effects toastNotifySpy = vi.spyOn(Toast, 'notify').mockImplementation(() => ({ clear: vi.fn() })) mockUninstallPlugin.mockResolvedValue({ success: true }) mockFetchReleases.mockResolvedValue([]) @@ -563,7 +563,7 @@ describe('Action Component', () => { render() fireEvent.click(getActionButtons()[0]) - // Assert - Toast.notify is called with the toast props + // Assert - notifyToast is called with the toast props await waitFor(() => { expect(toastNotifySpy).toHaveBeenCalledWith({ type: 'success', message: 'Already up to date' }) }) diff --git a/web/app/components/plugins/plugin-item/action.tsx b/web/app/components/plugins/plugin-item/action.tsx index 171e54acab..effbd7a914 100644 --- a/web/app/components/plugins/plugin-item/action.tsx +++ b/web/app/components/plugins/plugin-item/action.tsx @@ -7,7 +7,7 @@ import { useBoolean } from 'ahooks' import * as React from 'react' import { useCallback } from 'react' import { useTranslation } from 'react-i18next' -import Toast from '@/app/components/base/toast' +import { toast } from '@/app/components/base/ui/toast' import { useModalContext } from '@/context/modal-context' import { uninstallPlugin } from '@/service/plugins' import { useInvalidateInstalledPluginList } from '@/service/use-plugins' @@ -65,7 +65,7 @@ const Action: FC = ({ if (fetchedReleases.length === 0) return const { needUpdate, toastProps } = checkForUpdates(fetchedReleases, meta!.version) - Toast.notify(toastProps) + toast(toastProps) if (needUpdate) { setShowUpdatePluginModal({ onSaveCallback: () => { diff --git a/web/app/components/plugins/utils/toast.ts b/web/app/components/plugins/utils/toast.ts new file mode 100644 index 0000000000..064135589f --- /dev/null +++ b/web/app/components/plugins/utils/toast.ts @@ -0,0 +1,22 @@ +import type { ReactNode } from 'react' +import { toast } from '@/app/components/base/ui/toast' + +type ToastType = 'success' | 'error' | 'warning' | 'info' + +export type LegacyToastOptions = { + type?: ToastType + message: ReactNode +} + +export const notifyToast = ({ + type = 'info', + message, +}: LegacyToastOptions) => { + toast[type](message) +} + +const Toast = { + notify: notifyToast, +} + +export default Toast