mirror of
https://github.com/langgenius/dify.git
synced 2026-03-10 03:00:20 +08:00
refactor: spilt context for better hmr (#33033)
This commit is contained in:
parent
f3c840a60e
commit
f487b680f5
@ -19,7 +19,7 @@ vi.mock('react-i18next', () => ({
|
||||
}),
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
useToastContext: () => ({ notify: mockNotify }),
|
||||
}))
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ import AppCard from '@/app/components/app/overview/app-card'
|
||||
import TriggerCard from '@/app/components/app/overview/trigger-card'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import MCPServiceCard from '@/app/components/tools/mcp/mcp-service-card'
|
||||
import { isTriggerNode } from '@/app/components/workflow/types'
|
||||
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
|
||||
|
||||
@ -9,9 +9,9 @@ import Header from '@/app/components/header'
|
||||
import HeaderWrapper from '@/app/components/header/header-wrapper'
|
||||
import ReadmePanel from '@/app/components/plugins/readme-panel'
|
||||
import { AppContextProvider } from '@/context/app-context-provider'
|
||||
import { EventEmitterContextProvider } from '@/context/event-emitter'
|
||||
import { ModalContextProvider } from '@/context/modal-context'
|
||||
import { ProviderContextProvider } from '@/context/provider-context'
|
||||
import { EventEmitterContextProvider } from '@/context/event-emitter-provider'
|
||||
import { ModalContextProvider } from '@/context/modal-context-provider'
|
||||
import { ProviderContextProvider } from '@/context/provider-context-provider'
|
||||
import PartnerStack from '../components/billing/partner-stack'
|
||||
import Splash from '../components/splash'
|
||||
import RoleRouteGuard from './role-route-guard'
|
||||
|
||||
@ -16,7 +16,7 @@ import Button from '@/app/components/base/button'
|
||||
import Divider from '@/app/components/base/divider'
|
||||
import { useLocalFileUploader } from '@/app/components/base/image-uploader/hooks'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import { DISABLE_UPLOAD_IMAGE_AS_ICON } from '@/config'
|
||||
import { updateUserProfile } from '@/service/common'
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import { useContext } from 'use-context-selector'
|
||||
import Button from '@/app/components/base/button'
|
||||
import Input from '@/app/components/base/input'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import {
|
||||
checkEmailExisted,
|
||||
resetEmail,
|
||||
|
||||
@ -12,7 +12,7 @@ import Button from '@/app/components/base/button'
|
||||
import Input from '@/app/components/base/input'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
import PremiumBadge from '@/app/components/base/premium-badge'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import Collapse from '@/app/components/header/account-setting/collapse'
|
||||
import { IS_CE_EDITION, validPassword } from '@/config'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
|
||||
@ -5,9 +5,9 @@ import AmplitudeProvider from '@/app/components/base/amplitude'
|
||||
import GA, { GaType } from '@/app/components/base/ga'
|
||||
import HeaderWrapper from '@/app/components/header/header-wrapper'
|
||||
import { AppContextProvider } from '@/context/app-context-provider'
|
||||
import { EventEmitterContextProvider } from '@/context/event-emitter'
|
||||
import { ModalContextProvider } from '@/context/modal-context'
|
||||
import { ProviderContextProvider } from '@/context/provider-context'
|
||||
import { EventEmitterContextProvider } from '@/context/event-emitter-provider'
|
||||
import { ModalContextProvider } from '@/context/modal-context-provider'
|
||||
import { ProviderContextProvider } from '@/context/provider-context-provider'
|
||||
import Header from './header'
|
||||
|
||||
const Layout = ({ children }: { children: ReactNode }) => {
|
||||
|
||||
@ -42,7 +42,7 @@ vi.mock('@/app/components/app/store', () => ({
|
||||
}),
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
ToastContext: {},
|
||||
}))
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ import { useCallback, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import { copyApp, deleteApp, exportAppConfig, updateAppInfo } from '@/service/apps'
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type { Props } from './csv-uploader'
|
||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import * as React from 'react'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import CSVUploader from './csv-uploader'
|
||||
|
||||
describe('CSVUploader', () => {
|
||||
|
||||
@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import Button from '@/app/components/base/button'
|
||||
import { Csv as CSVIcon } from '@/app/components/base/icons/src/public/files'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
||||
export type Props = {
|
||||
|
||||
@ -20,7 +20,7 @@ import {
|
||||
} from '@/app/components/base/icons/src/vender/line/files'
|
||||
import PromptEditor from '@/app/components/base/prompt-editor'
|
||||
import { INSERT_VARIABLE_VALUE_BLOCK_COMMAND } from '@/app/components/base/prompt-editor/plugins/variable-block'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import ConfigContext from '@/context/debug-configuration'
|
||||
import { useEventEmitterContextContext } from '@/context/event-emitter'
|
||||
|
||||
@ -17,7 +17,7 @@ import { useFeaturesStore } from '@/app/components/base/features/hooks'
|
||||
import PromptEditor from '@/app/components/base/prompt-editor'
|
||||
import { PROMPT_EDITOR_UPDATE_VALUE_BY_EVENT_EMITTER } from '@/app/components/base/prompt-editor/plugins/update-block'
|
||||
import { INSERT_VARIABLE_VALUE_BLOCK_COMMAND } from '@/app/components/base/prompt-editor/plugins/variable-block'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import ConfigContext from '@/context/debug-configuration'
|
||||
import { useEventEmitterContextContext } from '@/context/event-emitter'
|
||||
|
||||
@ -12,7 +12,7 @@ import {
|
||||
CopyCheck,
|
||||
} from '@/app/components/base/icons/src/vender/line/files'
|
||||
import PromptEditor from '@/app/components/base/prompt-editor'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import ConfigContext from '@/context/debug-configuration'
|
||||
import { useModalContext } from '@/context/modal-context'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
||||
@ -3,7 +3,7 @@ import type { DataSet } from '@/models/datasets'
|
||||
import type { RetrievalConfig } from '@/types/app'
|
||||
import { render, screen, waitFor } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import { IndexingType } from '@/app/components/datasets/create/step-two'
|
||||
import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants'
|
||||
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
|
||||
@ -9,7 +9,7 @@ import { useTranslation } from 'react-i18next'
|
||||
import Button from '@/app/components/base/button'
|
||||
import Input from '@/app/components/base/input'
|
||||
import Textarea from '@/app/components/base/textarea'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import { isReRankModelSelected } from '@/app/components/datasets/common/check-rerank-model'
|
||||
import { IndexingType } from '@/app/components/datasets/create/step-two'
|
||||
import IndexMethod from '@/app/components/datasets/settings/index-method'
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
'use client'
|
||||
|
||||
import type { ReactNode } from 'react'
|
||||
import type { DebugWithMultipleModelContextType } from './context'
|
||||
import { DebugWithMultipleModelContext } from './context'
|
||||
|
||||
type DebugWithMultipleModelContextProviderProps = {
|
||||
children: ReactNode
|
||||
} & DebugWithMultipleModelContextType
|
||||
export const DebugWithMultipleModelContextProvider = ({
|
||||
children,
|
||||
onMultipleModelConfigsChange,
|
||||
multipleModelConfigs,
|
||||
onDebugWithMultipleModelChange,
|
||||
checkCanSend,
|
||||
}: DebugWithMultipleModelContextProviderProps) => {
|
||||
return (
|
||||
<DebugWithMultipleModelContext.Provider value={{
|
||||
onMultipleModelConfigsChange,
|
||||
multipleModelConfigs,
|
||||
onDebugWithMultipleModelChange,
|
||||
checkCanSend,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</DebugWithMultipleModelContext.Provider>
|
||||
)
|
||||
}
|
||||
@ -1,10 +1,8 @@
|
||||
import type { ModelAndParameter } from '../types'
|
||||
import type { DebugWithMultipleModelContextType } from './context'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import {
|
||||
DebugWithMultipleModelContextProvider,
|
||||
useDebugWithMultipleModelContext,
|
||||
} from './context'
|
||||
import { useDebugWithMultipleModelContext } from './context'
|
||||
import { DebugWithMultipleModelContextProvider } from './context-provider'
|
||||
|
||||
const createModelAndParameter = (overrides: Partial<ModelAndParameter> = {}): ModelAndParameter => ({
|
||||
id: 'model-1',
|
||||
|
||||
@ -10,7 +10,8 @@ export type DebugWithMultipleModelContextType = {
|
||||
onDebugWithMultipleModelChange: (singleModelConfig: ModelAndParameter) => void
|
||||
checkCanSend?: () => boolean
|
||||
}
|
||||
const DebugWithMultipleModelContext = createContext<DebugWithMultipleModelContextType>({
|
||||
|
||||
export const DebugWithMultipleModelContext = createContext<DebugWithMultipleModelContextType>({
|
||||
multipleModelConfigs: [],
|
||||
onMultipleModelConfigsChange: noop,
|
||||
onDebugWithMultipleModelChange: noop,
|
||||
@ -18,27 +19,4 @@ const DebugWithMultipleModelContext = createContext<DebugWithMultipleModelContex
|
||||
|
||||
export const useDebugWithMultipleModelContext = () => useContext(DebugWithMultipleModelContext)
|
||||
|
||||
type DebugWithMultipleModelContextProviderProps = {
|
||||
children: React.ReactNode
|
||||
} & DebugWithMultipleModelContextType
|
||||
export const DebugWithMultipleModelContextProvider = ({
|
||||
children,
|
||||
onMultipleModelConfigsChange,
|
||||
multipleModelConfigs,
|
||||
onDebugWithMultipleModelChange,
|
||||
checkCanSend,
|
||||
}: DebugWithMultipleModelContextProviderProps) => {
|
||||
return (
|
||||
<DebugWithMultipleModelContext.Provider value={{
|
||||
onMultipleModelConfigsChange,
|
||||
multipleModelConfigs,
|
||||
onDebugWithMultipleModelChange,
|
||||
checkCanSend,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</DebugWithMultipleModelContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export default DebugWithMultipleModelContext
|
||||
@ -14,10 +14,8 @@ import { useDebugConfigurationContext } from '@/context/debug-configuration'
|
||||
import { useEventEmitterContextContext } from '@/context/event-emitter'
|
||||
import { AppModeEnum } from '@/types/app'
|
||||
import { APP_CHAT_WITH_MULTIPLE_MODEL } from '../types'
|
||||
import {
|
||||
DebugWithMultipleModelContextProvider,
|
||||
useDebugWithMultipleModelContext,
|
||||
} from './context'
|
||||
import { useDebugWithMultipleModelContext } from './context'
|
||||
import { DebugWithMultipleModelContextProvider } from './context-provider'
|
||||
import DebugItem from './debug-item'
|
||||
|
||||
const DebugWithMultipleModel = () => {
|
||||
|
||||
@ -387,7 +387,7 @@ vi.mock('@/context/event-emitter', () => ({
|
||||
}))
|
||||
|
||||
// Mock toast context
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
useToastContext: vi.fn(() => ({
|
||||
notify: vi.fn(),
|
||||
})),
|
||||
|
||||
@ -29,7 +29,7 @@ import Button from '@/app/components/base/button'
|
||||
import { useFeatures, useFeaturesStore } from '@/app/components/base/features/hooks'
|
||||
import { RefreshCcw01 } from '@/app/components/base/icons/src/vender/line/arrows'
|
||||
import PromptLogModal from '@/app/components/base/prompt-log-modal'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import TooltipPlus from '@/app/components/base/tooltip'
|
||||
import { ModelFeatureEnum, ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { useDefaultModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
|
||||
@ -49,7 +49,8 @@ import { FeaturesProvider } from '@/app/components/base/features'
|
||||
import NewFeaturePanel from '@/app/components/base/features/new-feature-panel'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
import { FILE_EXTS } from '@/app/components/base/prompt-editor/constants'
|
||||
import Toast, { ToastContext } from '@/app/components/base/toast'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants'
|
||||
import { ModelFeatureEnum, ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import {
|
||||
@ -66,7 +67,7 @@ import { SupportUploadFileTypes } from '@/app/components/workflow/types'
|
||||
import { ANNOTATION_DEFAULT, DATASET_DEFAULT, DEFAULT_AGENT_SETTING, DEFAULT_CHAT_PROMPT_CONFIG, DEFAULT_COMPLETION_PROMPT_CONFIG } from '@/config'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import ConfigContext from '@/context/debug-configuration'
|
||||
import { MittProvider } from '@/context/mitt-context'
|
||||
import { MittProvider } from '@/context/mitt-context-provider'
|
||||
import { useModalContext } from '@/context/modal-context'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
|
||||
|
||||
@ -13,7 +13,7 @@ import FormGeneration from '@/app/components/base/features/new-feature-panel/mod
|
||||
import { BookOpen01 } from '@/app/components/base/icons/src/vender/line/education'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
import { SimpleSelect } from '@/app/components/base/select'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import ApiBasedExtensionSelector from '@/app/components/header/account-setting/api-based-extension-page/selector'
|
||||
import { useDocLink, useLocale } from '@/context/i18n'
|
||||
import { LanguagesSupported } from '@/i18n-config/language'
|
||||
|
||||
@ -15,7 +15,7 @@ import {
|
||||
} from '@/app/components/base/icons/src/vender/line/general'
|
||||
import { Tool03 } from '@/app/components/base/icons/src/vender/solid/general'
|
||||
import Switch from '@/app/components/base/switch'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import ConfigContext from '@/context/debug-configuration'
|
||||
import { useModalContext } from '@/context/modal-context'
|
||||
|
||||
@ -4,7 +4,7 @@ import { useRouter } from 'next/navigation'
|
||||
import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { trackEvent } from '@/app/components/base/amplitude'
|
||||
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
|
||||
@ -17,7 +17,7 @@ import FullScreenModal from '@/app/components/base/fullscreen-modal'
|
||||
import { BubbleTextMod, ChatBot, ListSparkle, Logic } from '@/app/components/base/icons/src/vender/solid/communication'
|
||||
import Input from '@/app/components/base/input'
|
||||
import Textarea from '@/app/components/base/textarea'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import AppsFull from '@/app/components/billing/apps-full-in-dialog'
|
||||
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
|
||||
@ -12,7 +12,7 @@ import { trackEvent } from '@/app/components/base/amplitude'
|
||||
import Button from '@/app/components/base/button'
|
||||
import Input from '@/app/components/base/input'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import AppsFull from '@/app/components/billing/apps-full-in-dialog'
|
||||
import { usePluginDependencies } from '@/app/components/workflow/plugin-dependency/hooks'
|
||||
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
|
||||
|
||||
@ -10,7 +10,7 @@ import { useTranslation } from 'react-i18next'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import ActionButton from '@/app/components/base/action-button'
|
||||
import { Yaml as YamlIcon } from '@/app/components/base/icons/src/public/files'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import { formatFileSize } from '@/utils/format'
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@ import Drawer from '@/app/components/base/drawer'
|
||||
import { getProcessedFilesFromResponse } from '@/app/components/base/file-uploader/utils'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
import MessageLogModal from '@/app/components/base/message-log-modal'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import { addFileInfos, sortAgentSorts } from '@/app/components/tools/utils'
|
||||
import { WorkflowContextProvider } from '@/app/components/workflow/context'
|
||||
|
||||
@ -59,16 +59,12 @@ vi.mock('@/context/modal-context', () => ({
|
||||
useModalContext: () => buildModalContext(),
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/base/toast', async () => {
|
||||
const actual = await vi.importActual<typeof import('@/app/components/base/toast')>('@/app/components/base/toast')
|
||||
return {
|
||||
...actual,
|
||||
useToastContext: () => ({
|
||||
notify: mockNotify,
|
||||
close: vi.fn(),
|
||||
}),
|
||||
}
|
||||
})
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
useToastContext: () => ({
|
||||
notify: mockNotify,
|
||||
close: vi.fn(),
|
||||
}),
|
||||
}))
|
||||
|
||||
vi.mock('@/context/i18n', async () => {
|
||||
const actual = await vi.importActual<typeof import('@/context/i18n')>('@/context/i18n')
|
||||
|
||||
@ -20,7 +20,7 @@ import PremiumBadge from '@/app/components/base/premium-badge'
|
||||
import { SimpleSelect } from '@/app/components/base/select'
|
||||
import Switch from '@/app/components/base/switch'
|
||||
import Textarea from '@/app/components/base/textarea'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants'
|
||||
import { useModalContext } from '@/context/modal-context'
|
||||
|
||||
@ -3,7 +3,7 @@ import { render, screen, waitFor } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import * as React from 'react'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import { Plan } from '@/app/components/billing/type'
|
||||
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
|
||||
import { AppModeEnum } from '@/types/app'
|
||||
|
||||
@ -15,7 +15,7 @@ import Confirm from '@/app/components/base/confirm'
|
||||
import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
|
||||
import Input from '@/app/components/base/input'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import AppsFull from '@/app/components/billing/apps-full-in-dialog'
|
||||
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
|
||||
@ -18,7 +18,8 @@ import AppIcon from '@/app/components/base/app-icon'
|
||||
import Divider from '@/app/components/base/divider'
|
||||
import CustomPopover from '@/app/components/base/popover'
|
||||
import TagSelector from '@/app/components/base/tag-management/selector'
|
||||
import Toast, { ToastContext } from '@/app/components/base/toast'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import {
|
||||
AlertDialog,
|
||||
|
||||
@ -2,7 +2,7 @@ import type { ComponentProps } from 'react'
|
||||
import type { IChatItem } from '@/app/components/base/chat/chat/type'
|
||||
import type { AgentLogDetailResponse } from '@/models/log'
|
||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import { fetchAgentLogDetail } from '@/service/log'
|
||||
import AgentLogDetail from '../detail'
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type { IChatItem } from '@/app/components/base/chat/chat/type'
|
||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { useClickAway } from 'ahooks'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import { fetchAgentLogDetail } from '@/service/log'
|
||||
import AgentLogModal from '../index'
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ import { useTranslation } from 'react-i18next'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import { fetchAgentLogDetail } from '@/service/log'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import ResultPanel from './result'
|
||||
|
||||
@ -23,7 +23,7 @@ import {
|
||||
} from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { getProcessedFilesFromResponse } from '@/app/components/base/file-uploader/utils'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import { InputVarType } from '@/app/components/workflow/types'
|
||||
import { useWebAppStore } from '@/context/web-app-context'
|
||||
import { useAppFavicon } from '@/hooks/use-app-favicon'
|
||||
|
||||
@ -3,7 +3,8 @@ import type { ChatContextValue } from '../context'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { vi } from 'vitest'
|
||||
import { ChatContextProvider, useChatContext } from '../context'
|
||||
import { useChatContext } from '../context'
|
||||
import { ChatContextProvider } from '../context-provider'
|
||||
|
||||
const TestConsumer = () => {
|
||||
const context = useChatContext()
|
||||
|
||||
@ -9,7 +9,7 @@ import { vi } from 'vitest'
|
||||
|
||||
import Toast from '../../../toast'
|
||||
import { ThemeBuilder } from '../../embedded-chatbot/theme/theme-context'
|
||||
import { ChatContextProvider } from '../context'
|
||||
import { ChatContextProvider } from '../context-provider'
|
||||
import Question from '../question'
|
||||
|
||||
// Global Mocks
|
||||
|
||||
@ -91,15 +91,9 @@ vi.mock('@/app/components/base/features/hooks', () => ({
|
||||
// ---------------------------------------------------------------------------
|
||||
// Toast context
|
||||
// ---------------------------------------------------------------------------
|
||||
vi.mock('@/app/components/base/toast', async () => {
|
||||
const actual = await vi.importActual<typeof import('@/app/components/base/toast')>(
|
||||
'@/app/components/base/toast',
|
||||
)
|
||||
return {
|
||||
...actual,
|
||||
useToastContext: () => ({ notify: mockNotify }),
|
||||
}
|
||||
})
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
useToastContext: () => ({ notify: mockNotify, close: vi.fn() }),
|
||||
}))
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal layout hook – controls single/multi-line textarea mode
|
||||
|
||||
@ -22,7 +22,7 @@ import {
|
||||
FileContextProvider,
|
||||
useFileStore,
|
||||
} from '@/app/components/base/file-uploader/store'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import VoiceInput from '@/app/components/base/voice-input'
|
||||
import { TransferMethod } from '@/types/app'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type { InputForm } from './type'
|
||||
import { useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import { InputVarType } from '@/app/components/workflow/types'
|
||||
import { TransferMethod } from '@/types/app'
|
||||
|
||||
|
||||
@ -1,30 +1,8 @@
|
||||
'use client'
|
||||
|
||||
import type { ReactNode } from 'react'
|
||||
import type { ChatProps } from './index'
|
||||
import { createContext, useContext } from 'use-context-selector'
|
||||
|
||||
export type ChatContextValue = Pick<ChatProps, 'config'
|
||||
| 'isResponding'
|
||||
| 'chatList'
|
||||
| 'showPromptLog'
|
||||
| 'questionIcon'
|
||||
| 'answerIcon'
|
||||
| 'onSend'
|
||||
| 'onRegenerate'
|
||||
| 'onAnnotationEdited'
|
||||
| 'onAnnotationAdded'
|
||||
| 'onAnnotationRemoved'
|
||||
| 'disableFeedback'
|
||||
| 'onFeedback'
|
||||
| 'getHumanInputNodeData'> & {
|
||||
readonly?: boolean
|
||||
}
|
||||
|
||||
const ChatContext = createContext<ChatContextValue>({
|
||||
chatList: [],
|
||||
readonly: false,
|
||||
})
|
||||
import type { ChatContextValue } from './context'
|
||||
import { ChatContext } from './context'
|
||||
|
||||
type ChatContextProviderProps = {
|
||||
children: ReactNode
|
||||
@ -71,7 +49,3 @@ export const ChatContextProvider = ({
|
||||
</ChatContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const useChatContext = () => useContext(ChatContext)
|
||||
|
||||
export default ChatContext
|
||||
30
web/app/components/base/chat/chat/context.ts
Normal file
30
web/app/components/base/chat/chat/context.ts
Normal file
@ -0,0 +1,30 @@
|
||||
'use client'
|
||||
|
||||
import type { ChatProps } from './index'
|
||||
import { createContext, useContext } from 'use-context-selector'
|
||||
|
||||
export type ChatContextValue = Pick<ChatProps, 'config'
|
||||
| 'isResponding'
|
||||
| 'chatList'
|
||||
| 'showPromptLog'
|
||||
| 'questionIcon'
|
||||
| 'answerIcon'
|
||||
| 'onSend'
|
||||
| 'onRegenerate'
|
||||
| 'onAnnotationEdited'
|
||||
| 'onAnnotationAdded'
|
||||
| 'onAnnotationRemoved'
|
||||
| 'disableFeedback'
|
||||
| 'onFeedback'
|
||||
| 'getHumanInputNodeData'> & {
|
||||
readonly?: boolean
|
||||
}
|
||||
|
||||
export const ChatContext = createContext<ChatContextValue>({
|
||||
chatList: [],
|
||||
readonly: false,
|
||||
})
|
||||
|
||||
export const useChatContext = () => useContext(ChatContext)
|
||||
|
||||
export default ChatContext
|
||||
@ -30,7 +30,7 @@ import {
|
||||
getProcessedFiles,
|
||||
getProcessedFilesFromResponse,
|
||||
} from '@/app/components/base/file-uploader/utils'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import { NodeRunningStatus, WorkflowRunningStatus } from '@/app/components/workflow/types'
|
||||
import useTimestamp from '@/hooks/use-timestamp'
|
||||
import {
|
||||
|
||||
@ -30,7 +30,7 @@ import PromptLogModal from '@/app/components/base/prompt-log-modal'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import Answer from './answer'
|
||||
import ChatInputArea from './chat-input-area'
|
||||
import { ChatContextProvider } from './context'
|
||||
import { ChatContextProvider } from './context-provider'
|
||||
import Question from './question'
|
||||
import TryToAsk from './try-to-ask'
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ import {
|
||||
useState,
|
||||
} from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import { addFileInfos, sortAgentSorts } from '@/app/components/tools/utils'
|
||||
import { InputVarType } from '@/app/components/workflow/types'
|
||||
import { useWebAppStore } from '@/context/web-app-context'
|
||||
|
||||
@ -16,7 +16,7 @@ vi.mock('next/navigation', () => ({
|
||||
useSearchParams: () => new URLSearchParams(),
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
useToastContext: () => ({ notify: vi.fn() }),
|
||||
}))
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import ModerationSettingModal from '../moderation-setting-modal'
|
||||
|
||||
const mockNotify = vi.fn()
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
useToastContext: () => ({ notify: mockNotify }),
|
||||
}))
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next'
|
||||
import Button from '@/app/components/base/button'
|
||||
import Divider from '@/app/components/base/divider'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import ApiBasedExtensionSelector from '@/app/components/header/account-setting/api-based-extension-page/selector'
|
||||
import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants'
|
||||
import { CustomConfigurationStatusEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
|
||||
@ -11,7 +11,7 @@ vi.mock('next/navigation', () => ({
|
||||
}))
|
||||
|
||||
// Exception: hook requires toast context that isn't available without a provider wrapper
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
useToastContext: () => ({
|
||||
notify: mockNotify,
|
||||
}),
|
||||
|
||||
@ -18,7 +18,7 @@ import {
|
||||
MAX_FILE_UPLOAD_LIMIT,
|
||||
VIDEO_SIZE_LIMIT,
|
||||
} from '@/app/components/base/file-uploader/constants'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import { SupportUploadFileTypes } from '@/app/components/workflow/types'
|
||||
import { uploadRemoteFileInfo } from '@/service/common'
|
||||
import { TransferMethod } from '@/types/app'
|
||||
|
||||
@ -5,7 +5,7 @@ import { useCheckValidated } from '../use-check-validated'
|
||||
|
||||
const mockNotify = vi.fn()
|
||||
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
useToastContext: () => ({
|
||||
notify: mockNotify,
|
||||
}),
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type { AnyFormApi } from '@tanstack/react-form'
|
||||
import type { FormSchema } from '@/app/components/base/form/types'
|
||||
import { useCallback } from 'react'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
|
||||
export const useCheckValidated = (form: AnyFormApi, FormSchemas: FormSchema[]) => {
|
||||
const { notify } = useToastContext()
|
||||
|
||||
@ -5,7 +5,7 @@ import { Resolution, TransferMethod } from '@/types/app'
|
||||
import { useClipboardUploader, useDraggableUploader, useImageFiles, useLocalFileUploader } from '../hooks'
|
||||
|
||||
const mockNotify = vi.fn()
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
useToastContext: () => ({ notify: mockNotify }),
|
||||
}))
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import type { ImageFile, VisionSettings } from '@/types/app'
|
||||
import { useParams } from 'next/navigation'
|
||||
import { useCallback, useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import { ALLOW_FILE_EXTENSIONS, TransferMethod } from '@/types/app'
|
||||
import { getImageUploadErrorMessage, imageUpload } from './utils'
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import userEvent from '@testing-library/user-event'
|
||||
// markdown-button.spec.tsx
|
||||
import * as React from 'react'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { ChatContextProvider } from '@/app/components/base/chat/chat/context'
|
||||
import { ChatContextProvider } from '@/app/components/base/chat/chat/context-provider'
|
||||
|
||||
import MarkdownButton from '../button'
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { act, render, screen } from '@testing-library/react'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { ChatContextProvider } from '@/app/components/base/chat/chat/context'
|
||||
import { ChatContextProvider } from '@/app/components/base/chat/chat/context-provider'
|
||||
import ThinkBlock from '../think-block'
|
||||
|
||||
// Mock react-i18next
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import { useState } from 'react'
|
||||
import { ChatContextProvider } from '@/app/components/base/chat/chat/context'
|
||||
import { ChatContextProvider } from '@/app/components/base/chat/chat/context-provider'
|
||||
import ThinkBlock from './think-block'
|
||||
|
||||
const THOUGHT_TEXT = `
|
||||
|
||||
@ -28,7 +28,8 @@ import {
|
||||
import * as React from 'react'
|
||||
import { GeneratorType } from '@/app/components/app/configuration/config/automatic/types'
|
||||
import { VarType } from '@/app/components/workflow/types'
|
||||
import { EventEmitterContextProvider, useEventEmitterContextContext } from '@/context/event-emitter'
|
||||
import { useEventEmitterContextContext } from '@/context/event-emitter'
|
||||
import { EventEmitterContextProvider } from '@/context/event-emitter-provider'
|
||||
import { INSERT_CONTEXT_BLOCK_COMMAND } from '../../context-block'
|
||||
import { INSERT_CURRENT_BLOCK_COMMAND } from '../../current-block'
|
||||
import { INSERT_ERROR_MESSAGE_BLOCK_COMMAND } from '../../error-message-block'
|
||||
|
||||
@ -5,7 +5,7 @@ import TagInput from '../index'
|
||||
|
||||
const mockNotify = vi.fn()
|
||||
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
useToastContext: () => ({
|
||||
notify: mockNotify,
|
||||
}),
|
||||
|
||||
@ -2,7 +2,7 @@ import type { ChangeEvent, FC, KeyboardEvent } from 'react'
|
||||
import { useCallback, useState } from 'react'
|
||||
import AutosizeInput from 'react-18-input-autosize'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
||||
type TagInputProps = {
|
||||
|
||||
@ -3,7 +3,7 @@ import { render, screen, waitFor, within } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import * as React from 'react'
|
||||
import { act } from 'react'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import Panel from '../panel'
|
||||
import { useStore as useTagStore } from '../store'
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import { render, screen, waitFor, within } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import * as React from 'react'
|
||||
import { act } from 'react'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import TagSelector from '../selector'
|
||||
import { useStore as useTagStore } from '../store'
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ import { useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import {
|
||||
createTag,
|
||||
fetchTagList,
|
||||
|
||||
@ -10,7 +10,7 @@ import { useContext } from 'use-context-selector'
|
||||
import Checkbox from '@/app/components/base/checkbox'
|
||||
import Divider from '@/app/components/base/divider'
|
||||
import Input from '@/app/components/base/input'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import { bindTag, createTag, unBindTag } from '@/service/tag'
|
||||
import { useStore as useTagStore } from './store'
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import Confirm from '@/app/components/base/confirm'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import {
|
||||
deleteTag,
|
||||
|
||||
@ -5,7 +5,7 @@ import { useTextGeneration } from '../hooks'
|
||||
const mockNotify = vi.fn()
|
||||
const mockSsePost = vi.fn<(url: string, fetchOptions: { body: Record<string, unknown> }, otherOptions: IOtherOptions) => void>()
|
||||
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
useToastContext: () => ({
|
||||
notify: mockNotify,
|
||||
}),
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import { ssePost } from '@/service/base'
|
||||
|
||||
export const useTextGeneration = () => {
|
||||
|
||||
@ -2,7 +2,8 @@ import type { ReactNode } from 'react'
|
||||
import { act, render, screen, waitFor } from '@testing-library/react'
|
||||
import { noop } from 'es-toolkit/function'
|
||||
import * as React from 'react'
|
||||
import Toast, { ToastProvider, useToastContext } from '..'
|
||||
import Toast, { ToastProvider } from '..'
|
||||
import { useToastContext } from '../context'
|
||||
|
||||
const TestComponent = () => {
|
||||
const { notify, close } = useToastContext()
|
||||
|
||||
23
web/app/components/base/toast/context.ts
Normal file
23
web/app/components/base/toast/context.ts
Normal file
@ -0,0 +1,23 @@
|
||||
'use client'
|
||||
|
||||
import type { ReactNode } from 'react'
|
||||
import { createContext, useContext } from 'use-context-selector'
|
||||
|
||||
export type IToastProps = {
|
||||
type?: 'success' | 'error' | 'warning' | 'info'
|
||||
size?: 'md' | 'sm'
|
||||
duration?: number
|
||||
message: string
|
||||
children?: ReactNode
|
||||
onClose?: () => void
|
||||
className?: string
|
||||
customComponent?: ReactNode
|
||||
}
|
||||
|
||||
type IToastContext = {
|
||||
notify: (props: IToastProps) => void
|
||||
close: () => void
|
||||
}
|
||||
|
||||
export const ToastContext = createContext<IToastContext>({} as IToastContext)
|
||||
export const useToastContext = () => useContext(ToastContext)
|
||||
@ -1,6 +1,7 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import { useCallback } from 'react'
|
||||
import Toast, { ToastProvider, useToastContext } from '.'
|
||||
import Toast, { ToastProvider } from '.'
|
||||
import { useToastContext } from './context'
|
||||
|
||||
const ToastControls = () => {
|
||||
const { notify } = useToastContext()
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
'use client'
|
||||
import type { ReactNode } from 'react'
|
||||
import type { IToastProps } from './context'
|
||||
import {
|
||||
RiAlertFill,
|
||||
RiCheckboxCircleFill,
|
||||
@ -11,31 +12,13 @@ import { noop } from 'es-toolkit/function'
|
||||
import * as React from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import { createContext, useContext } from 'use-context-selector'
|
||||
import ActionButton from '@/app/components/base/action-button'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
||||
export type IToastProps = {
|
||||
type?: 'success' | 'error' | 'warning' | 'info'
|
||||
size?: 'md' | 'sm'
|
||||
duration?: number
|
||||
message: string
|
||||
children?: ReactNode
|
||||
onClose?: () => void
|
||||
className?: string
|
||||
customComponent?: ReactNode
|
||||
}
|
||||
type IToastContext = {
|
||||
notify: (props: IToastProps) => void
|
||||
close: () => void
|
||||
}
|
||||
import { ToastContext, useToastContext } from './context'
|
||||
|
||||
export type ToastHandle = {
|
||||
clear?: VoidFunction
|
||||
}
|
||||
|
||||
export const ToastContext = createContext<IToastContext>({} as IToastContext)
|
||||
export const useToastContext = () => useContext(ToastContext)
|
||||
const Toast = ({
|
||||
type = 'info',
|
||||
size = 'md',
|
||||
@ -77,11 +60,11 @@ const Toast = ({
|
||||
</div>
|
||||
<div className={cn('flex grow flex-col items-start gap-1 py-1', size === 'md' ? 'px-1' : 'px-0.5')}>
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="system-sm-semibold text-text-primary [word-break:break-word]">{message}</div>
|
||||
<div className="text-text-primary system-sm-semibold [word-break:break-word]">{message}</div>
|
||||
{customComponent}
|
||||
</div>
|
||||
{!!children && (
|
||||
<div className="system-xs-regular text-text-secondary">
|
||||
<div className="text-text-secondary system-xs-regular">
|
||||
{children}
|
||||
</div>
|
||||
)}
|
||||
@ -183,3 +166,5 @@ Toast.notify = ({
|
||||
}
|
||||
|
||||
export default Toast
|
||||
|
||||
export type { IToastProps } from './context'
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { getImageUploadErrorMessage, imageUpload } from '@/app/components/base/image-uploader/utils'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import { Plan } from '@/app/components/billing/type'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
@ -9,7 +9,7 @@ import { useProviderContext } from '@/context/provider-context'
|
||||
import { updateCurrentWorkspace } from '@/service/common'
|
||||
import CustomWebAppBrand from '../index'
|
||||
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
useToastContext: vi.fn(),
|
||||
}))
|
||||
vi.mock('@/service/common', () => ({
|
||||
|
||||
@ -16,7 +16,7 @@ import { BubbleTextMod } from '@/app/components/base/icons/src/vender/solid/comm
|
||||
import { getImageUploadErrorMessage, imageUpload } from '@/app/components/base/image-uploader/utils'
|
||||
import DifyLogo from '@/app/components/base/logo/dify-logo'
|
||||
import Switch from '@/app/components/base/switch'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import { Plan } from '@/app/components/billing/type'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
|
||||
@ -4,7 +4,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import Uploader from '../uploader'
|
||||
|
||||
const mockNotify = vi.fn()
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
ToastContext: {
|
||||
Provider: ({ children }: { children: React.ReactNode }) => children,
|
||||
Consumer: ({ children }: { children: (value: { notify: typeof mockNotify }) => React.ReactNode }) => children({ notify: mockNotify }),
|
||||
|
||||
@ -4,7 +4,7 @@ import { useRouter } from 'next/navigation'
|
||||
import { useCallback, useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import { usePluginDependencies } from '@/app/components/workflow/plugin-dependency/hooks'
|
||||
import {
|
||||
DSLImportMode,
|
||||
|
||||
@ -10,7 +10,7 @@ import { useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import ActionButton from '@/app/components/base/action-button'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import { formatFileSize } from '@/utils/format'
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ import { trackEvent } from '@/app/components/base/amplitude'
|
||||
import Button from '@/app/components/base/button'
|
||||
import Input from '@/app/components/base/input'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
|
||||
import { createEmptyDataset } from '@/service/datasets'
|
||||
import { useInvalidDatasetList } from '@/service/knowledge/use-dataset'
|
||||
|
||||
@ -2,7 +2,7 @@ import type { ReactNode } from 'react'
|
||||
import type { CustomFile, FileItem } from '@/models/datasets'
|
||||
import { act, render, renderHook, waitFor } from '@testing-library/react'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
|
||||
import { PROGRESS_COMPLETE, PROGRESS_ERROR, PROGRESS_NOT_STARTED } from '../../constants'
|
||||
// Import after mocks
|
||||
|
||||
@ -5,7 +5,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import { getFileUploadErrorMessage } from '@/app/components/base/file-uploader/utils'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import { IS_CE_EDITION } from '@/config'
|
||||
import { useLocale } from '@/context/i18n'
|
||||
import { LanguagesSupported } from '@/i18n-config/language'
|
||||
|
||||
@ -10,7 +10,7 @@ vi.mock('next/navigation', () => ({
|
||||
}))
|
||||
|
||||
const mockNotify = vi.fn()
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
ToastContext: {
|
||||
Provider: ({ children }: { children: React.ReactNode }) => children,
|
||||
},
|
||||
|
||||
@ -24,7 +24,7 @@ import Divider from '@/app/components/base/divider'
|
||||
import { SearchLinesSparkle } from '@/app/components/base/icons/src/vender/knowledge'
|
||||
import CustomPopover from '@/app/components/base/popover'
|
||||
import Switch from '@/app/components/base/switch'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import { IS_CE_EDITION } from '@/config'
|
||||
import { DataSourceType, DocumentActionType } from '@/models/datasets'
|
||||
|
||||
@ -9,7 +9,7 @@ const mockNotify = vi.fn()
|
||||
const mockClose = vi.fn()
|
||||
|
||||
// Mock ToastContext with factory function
|
||||
vi.mock('@/app/components/base/toast', async () => {
|
||||
vi.mock('@/app/components/base/toast/context', async () => {
|
||||
const { createContext, useContext } = await import('use-context-selector')
|
||||
const context = createContext({ notify: mockNotify, close: mockClose })
|
||||
return {
|
||||
@ -87,7 +87,7 @@ vi.mock('@/service/base', () => ({
|
||||
|
||||
// Import after all mocks are set up
|
||||
const { useLocalFileUpload } = await import('../use-local-file-upload')
|
||||
const { ToastContext } = await import('@/app/components/base/toast')
|
||||
const { ToastContext } = await import('@/app/components/base/toast/context')
|
||||
|
||||
const createWrapper = () => {
|
||||
return ({ children }: { children: ReactNode }) => (
|
||||
|
||||
@ -25,7 +25,7 @@ vi.mock('@/hooks/use-theme', () => ({
|
||||
}))
|
||||
|
||||
const mockNotify = vi.fn()
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
ToastContext: {
|
||||
Provider: ({ children }: { children: ReactNode }) => children,
|
||||
Consumer: ({ children }: { children: (ctx: { notify: typeof mockNotify }) => ReactNode }) => children({ notify: mockNotify }),
|
||||
|
||||
@ -12,7 +12,7 @@ import Button from '@/app/components/base/button'
|
||||
import { getFileUploadErrorMessage } from '@/app/components/base/file-uploader/utils'
|
||||
import { Csv as CSVIcon } from '@/app/components/base/icons/src/public/files'
|
||||
import SimplePieChart from '@/app/components/base/simple-pie-chart'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import useTheme from '@/hooks/use-theme'
|
||||
import { upload } from '@/service/base'
|
||||
import { useFileUploadConfig } from '@/service/use-common'
|
||||
|
||||
@ -65,7 +65,7 @@ vi.mock('../../context', () => ({
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
ToastContext: { Provider: ({ children }: { children: React.ReactNode }) => children, Consumer: () => null },
|
||||
useToastContext: () => ({ notify: mockNotify }),
|
||||
}))
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import type { ReactNode } from 'react'
|
||||
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { EventEmitterContextProvider, useEventEmitterContextContext } from '@/context/event-emitter'
|
||||
import { useEventEmitterContextContext } from '@/context/event-emitter'
|
||||
import { EventEmitterContextProvider } from '@/context/event-emitter-provider'
|
||||
import RegenerationModal from '../regeneration-modal'
|
||||
|
||||
// Store emit function for triggering events in tests
|
||||
|
||||
@ -59,7 +59,7 @@ vi.mock('../../../context', () => ({
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
useToastContext: () => ({ notify: mockNotify }),
|
||||
}))
|
||||
|
||||
|
||||
@ -92,7 +92,7 @@ vi.mock('../../../context', () => ({
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/app/components/base/toast/context', () => ({
|
||||
useToastContext: () => ({ notify: mockNotify }),
|
||||
}))
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ import type { ChildChunkDetail, ChildSegmentsResponse, SegmentDetailModel, Segme
|
||||
import { useQueryClient } from '@tanstack/react-query'
|
||||
import { useCallback, useEffect, useMemo, useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import { useEventEmitterContextContext } from '@/context/event-emitter'
|
||||
import {
|
||||
useChildSegmentList,
|
||||
|
||||
@ -4,7 +4,7 @@ import { useQueryClient } from '@tanstack/react-query'
|
||||
import { usePathname } from 'next/navigation'
|
||||
import { useCallback, useEffect, useMemo, useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useToastContext } from '@/app/components/base/toast/context'
|
||||
import { useEventEmitterContextContext } from '@/context/event-emitter'
|
||||
import { ChunkingMode } from '@/models/datasets'
|
||||
import {
|
||||
|
||||
@ -8,7 +8,7 @@ import { useContext } from 'use-context-selector'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import Divider from '@/app/components/base/divider'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import { ChunkingMode } from '@/models/datasets'
|
||||
import { useAddChildSegment } from '@/service/knowledge/use-segment'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
||||
@ -5,7 +5,7 @@ import * as React from 'react'
|
||||
import { useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import { useProcessRule } from '@/service/knowledge/use-dataset'
|
||||
import { useDocumentContext } from '../context'
|
||||
import { ProgressBar, RuleDetail, SegmentProgress, StatusHeader } from './components'
|
||||
|
||||
@ -3,7 +3,7 @@ import type { FullDocumentDetail } from '@/models/datasets'
|
||||
import { act, renderHook } from '@testing-library/react'
|
||||
import * as React from 'react'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { ToastContext } from '@/app/components/base/toast/context'
|
||||
|
||||
import { useMetadataState } from '../use-metadata-state'
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user