瀏覽代碼

refactor & perf: `import { noop } from 'lodash-es'` across `web` (#17439)

tags/1.2.0
yusheng chen 6 月之前
父節點
當前提交
c05e03fc09
沒有連結到貢獻者的電子郵件帳戶。
共有 87 個檔案被更改,包括 271 行新增184 行删除
  1. 2
    1
      web/app/components/app/annotation/batch-add-annotation-modal/index.tsx
  2. 2
    1
      web/app/components/app/configuration/base/operation-btn/index.tsx
  3. 2
    1
      web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx
  4. 4
    3
      web/app/components/app/configuration/config/agent/prompt-editor.tsx
  5. 2
    1
      web/app/components/app/configuration/dataset-config/params-config/weighted-score.tsx
  6. 3
    2
      web/app/components/app/configuration/debug/debug-with-multiple-model/context.tsx
  7. 2
    1
      web/app/components/app/configuration/debug/debug-with-multiple-model/text-generation-item.tsx
  8. 2
    1
      web/app/components/app/configuration/debug/index.tsx
  9. 2
    1
      web/app/components/app/configuration/tools/external-data-tool-modal.tsx
  10. 2
    1
      web/app/components/app/create-from-dsl-modal/index.tsx
  11. 2
    1
      web/app/components/app/duplicate-modal/index.tsx
  12. 2
    1
      web/app/components/app/log/list.tsx
  13. 2
    1
      web/app/components/app/switch-app-modal/index.tsx
  14. 2
    1
      web/app/components/base/app-icon-picker/index.tsx
  15. 16
    15
      web/app/components/base/chat/chat-with-history/context.tsx
  16. 2
    1
      web/app/components/base/chat/chat-with-history/hooks.tsx
  17. 11
    10
      web/app/components/base/chat/embedded-chatbot/context.tsx
  18. 2
    1
      web/app/components/base/chat/embedded-chatbot/hooks.tsx
  19. 2
    1
      web/app/components/base/emoji-picker/index.tsx
  20. 2
    1
      web/app/components/base/features/new-feature-panel/conversation-opener/modal.tsx
  21. 2
    1
      web/app/components/base/features/new-feature-panel/moderation/moderation-setting-modal.tsx
  22. 3
    2
      web/app/components/base/file-uploader/hooks.ts
  23. 3
    2
      web/app/components/base/file-uploader/pdf-preview.tsx
  24. 2
    1
      web/app/components/base/fullscreen-modal/index.tsx
  25. 3
    2
      web/app/components/base/image-uploader/image-preview.tsx
  26. 2
    1
      web/app/components/base/input/index.tsx
  27. 2
    1
      web/app/components/base/modal/index.tsx
  28. 2
    1
      web/app/components/base/notion-page-selector/notion-page-selector-modal/index.tsx
  29. 2
    1
      web/app/components/base/prompt-editor/plugins/context-block/context-block-replacement-block.tsx
  30. 2
    1
      web/app/components/base/prompt-editor/plugins/context-block/index.tsx
  31. 2
    1
      web/app/components/base/prompt-editor/plugins/history-block/history-block-replacement-block.tsx
  32. 2
    1
      web/app/components/base/prompt-editor/plugins/history-block/index.tsx
  33. 2
    1
      web/app/components/base/radio-card/index.tsx
  34. 3
    2
      web/app/components/base/tag-management/selector.tsx
  35. 2
    1
      web/app/components/base/tag-management/tag-remove-modal.tsx
  36. 3
    2
      web/app/components/base/toast/index.spec.tsx
  37. 2
    1
      web/app/components/base/toast/index.tsx
  38. 2
    1
      web/app/components/base/with-input-validation/index.spec.tsx
  39. 2
    1
      web/app/components/datasets/common/document-status-with-action/index-failed.tsx
  40. 2
    1
      web/app/components/datasets/documents/detail/batch-modal/index.tsx
  41. 2
    1
      web/app/components/datasets/documents/detail/completed/common/full-screen-drawer.tsx
  42. 2
    1
      web/app/components/datasets/documents/detail/completed/common/regeneration-modal.tsx
  43. 2
    1
      web/app/components/datasets/documents/detail/completed/index.tsx
  44. 2
    1
      web/app/components/datasets/metadata/metadata-dataset/create-content.tsx
  45. 2
    1
      web/app/components/datasets/rename-modal/index.tsx
  46. 2
    1
      web/app/components/header/account-about/index.tsx
  47. 2
    1
      web/app/components/header/account-setting/api-based-extension-page/modal.tsx
  48. 2
    1
      web/app/components/header/account-setting/data-source-page/data-source-notion/index.tsx
  49. 3
    1
      web/app/components/header/account-setting/members-page/edit-workspace-modal/index.tsx
  50. 3
    2
      web/app/components/header/account-setting/members-page/invite-modal/index.tsx
  51. 2
    1
      web/app/components/header/account-setting/members-page/invited-modal/index.tsx
  52. 2
    1
      web/app/components/header/account-setting/menu-dialog.tsx
  53. 2
    1
      web/app/components/header/app-selector/index.tsx
  54. 12
    11
      web/app/components/plugins/marketplace/context.tsx
  55. 4
    3
      web/app/components/plugins/plugin-page/context.tsx
  56. 3
    2
      web/app/components/plugins/plugin-page/empty/index.tsx
  57. 4
    3
      web/app/components/plugins/plugin-page/index.tsx
  58. 3
    2
      web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx
  59. 2
    1
      web/app/components/tools/labels/selector.tsx
  60. 2
    1
      web/app/components/tools/setting/build-in/config-credentials.tsx
  61. 2
    1
      web/app/components/tools/workflow-tool/confirm-modal/index.tsx
  62. 2
    1
      web/app/components/workflow/dsl-export-confirm-modal.tsx
  63. 2
    2
      web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx
  64. 2
    1
      web/app/components/workflow/nodes/_base/components/file-type-item.tsx
  65. 3
    2
      web/app/components/workflow/nodes/_base/components/input-support-select-var.tsx
  66. 3
    2
      web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx
  67. 2
    1
      web/app/components/workflow/nodes/assigner/components/var-list/index.tsx
  68. 2
    1
      web/app/components/workflow/nodes/if-else/components/condition-wrap.tsx
  69. 3
    2
      web/app/components/workflow/nodes/knowledge-retrieval/components/metadata/metadata-filter/index.tsx
  70. 3
    2
      web/app/components/workflow/nodes/start/components/var-item.tsx
  71. 2
    1
      web/app/components/workflow/nodes/tool/components/input-var-list.tsx
  72. 2
    1
      web/app/components/workflow/nodes/variable-assigner/components/var-list/index.tsx
  73. 2
    1
      web/app/components/workflow/panel/debug-and-preview/conversation-variable-modal.tsx
  74. 2
    1
      web/app/components/workflow/panel/debug-and-preview/index.tsx
  75. 2
    1
      web/app/components/workflow/run/utils/format-log/iteration/index.spec.ts
  76. 2
    1
      web/app/components/workflow/run/utils/format-log/loop/index.spec.ts
  77. 2
    1
      web/app/components/workflow/workflow-history-store.tsx
  78. 4
    3
      web/app/education-apply/education-apply-page.tsx
  79. 2
    1
      web/app/reset-password/page.tsx
  80. 2
    1
      web/app/signin/components/mail-and-code-auth.tsx
  81. 2
    1
      web/app/signin/components/mail-and-password-auth.tsx
  82. 4
    3
      web/context/app-context.tsx
  83. 2
    1
      web/context/datasets-context.tsx
  84. 29
    28
      web/context/debug-configuration.ts
  85. 3
    2
      web/context/explore-context.ts
  86. 13
    12
      web/context/modal-context.tsx
  87. 3
    2
      web/context/provider-context.tsx

+ 2
- 1
web/app/components/app/annotation/batch-add-annotation-modal/index.tsx 查看文件

import { annotationBatchImport, checkAnnotationBatchImportProgress } from '@/service/annotation' import { annotationBatchImport, checkAnnotationBatchImportProgress } from '@/service/annotation'
import { useProviderContext } from '@/context/provider-context' import { useProviderContext } from '@/context/provider-context'
import AnnotationFull from '@/app/components/billing/annotation-full' import AnnotationFull from '@/app/components/billing/annotation-full'
import { noop } from 'lodash-es'


export enum ProcessStatus { export enum ProcessStatus {
WAITING = 'waiting', WAITING = 'waiting',
} }


return ( return (
<Modal isShow={isShow} onClose={() => { }} className='!max-w-[520px] !rounded-xl px-8 py-6'>
<Modal isShow={isShow} onClose={noop} className='!max-w-[520px] !rounded-xl px-8 py-6'>
<div className='system-xl-medium relative pb-1 text-text-primary'>{t('appAnnotation.batchModal.title')}</div> <div className='system-xl-medium relative pb-1 text-text-primary'>{t('appAnnotation.batchModal.title')}</div>
<div className='absolute right-4 top-4 cursor-pointer p-2' onClick={onCancel}> <div className='absolute right-4 top-4 cursor-pointer p-2' onClick={onCancel}>
<RiCloseLine className='h-4 w-4 text-text-tertiary' /> <RiCloseLine className='h-4 w-4 text-text-tertiary' />

+ 2
- 1
web/app/components/app/configuration/base/operation-btn/index.tsx 查看文件

RiEditLine, RiEditLine,
} from '@remixicon/react' } from '@remixicon/react'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import { noop } from 'lodash-es'


export type IOperationBtnProps = { export type IOperationBtnProps = {
className?: string className?: string
className, className,
type, type,
actionName, actionName,
onClick = () => { },
onClick = noop,
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
return ( return (

+ 2
- 1
web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx 查看文件

import { PROMPT_EDITOR_UPDATE_VALUE_BY_EVENT_EMITTER } from '@/app/components/base/prompt-editor/plugins/update-block' import { PROMPT_EDITOR_UPDATE_VALUE_BY_EVENT_EMITTER } from '@/app/components/base/prompt-editor/plugins/update-block'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import { useFeaturesStore } from '@/app/components/base/features/hooks' import { useFeaturesStore } from '@/app/components/base/features/hooks'
import { noop } from 'lodash-es'


export type ISimplePromptInput = { export type ISimplePromptInput = {
mode: AppType mode: AppType
user: '', user: '',
assistant: '', assistant: '',
}, },
onEditRole: () => { },
onEditRole: noop,
}} }}
queryBlock={{ queryBlock={{
show: false, show: false,

+ 4
- 3
web/app/components/app/configuration/config/agent/prompt-editor.tsx 查看文件

import ConfigContext from '@/context/debug-configuration' import ConfigContext from '@/context/debug-configuration'
import { useModalContext } from '@/context/modal-context' import { useModalContext } from '@/context/modal-context'
import { useToastContext } from '@/app/components/base/toast' import { useToastContext } from '@/app/components/base/toast'

import s from '@/app/components/app/configuration/config-prompt/style.module.css' import s from '@/app/components/app/configuration/config-prompt/style.module.css'
import { noop } from 'lodash-es'

type Props = { type Props = {
className?: string className?: string
type: 'first-prompt' | 'next-iteration' type: 'first-prompt' | 'next-iteration'
user: '', user: '',
assistant: '', assistant: '',
}, },
onEditRole: () => { },
onEditRole: noop,
}} }}
queryBlock={{ queryBlock={{
show: false, show: false,
selectable: false, selectable: false,
}} }}
onChange={onChange} onChange={onChange}
onBlur={() => { }}
onBlur={noop}
/> />
</div> </div>
<div className='flex pb-2 pl-4'> <div className='flex pb-2 pl-4'>

+ 2
- 1
web/app/components/app/configuration/dataset-config/params-config/weighted-score.tsx 查看文件

import './weighted-score.css' import './weighted-score.css'
import Slider from '@/app/components/base/slider' import Slider from '@/app/components/base/slider'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import { noop } from 'lodash-es'


const formatNumber = (value: number) => { const formatNumber = (value: number) => {
if (value > 0 && value < 1) if (value > 0 && value < 1)
} }
const WeightedScore = ({ const WeightedScore = ({
value, value,
onChange = () => {},
onChange = noop,
}: WeightedScoreProps) => { }: WeightedScoreProps) => {
const { t } = useTranslation() const { t } = useTranslation()



+ 3
- 2
web/app/components/app/configuration/debug/debug-with-multiple-model/context.tsx 查看文件



import { createContext, useContext } from 'use-context-selector' import { createContext, useContext } from 'use-context-selector'
import type { ModelAndParameter } from '../types' import type { ModelAndParameter } from '../types'
import { noop } from 'lodash-es'


export type DebugWithMultipleModelContextType = { export type DebugWithMultipleModelContextType = {
multipleModelConfigs: ModelAndParameter[] multipleModelConfigs: ModelAndParameter[]
} }
const DebugWithMultipleModelContext = createContext<DebugWithMultipleModelContextType>({ const DebugWithMultipleModelContext = createContext<DebugWithMultipleModelContextType>({
multipleModelConfigs: [], multipleModelConfigs: [],
onMultipleModelConfigsChange: () => {},
onDebugWithMultipleModelChange: () => {},
onMultipleModelConfigsChange: noop,
onDebugWithMultipleModelChange: noop,
}) })


export const useDebugWithMultipleModelContext = () => useContext(DebugWithMultipleModelContext) export const useDebugWithMultipleModelContext = () => useContext(DebugWithMultipleModelContext)

+ 2
- 1
web/app/components/app/configuration/debug/debug-with-multiple-model/text-generation-item.tsx 查看文件

import { useEventEmitterContextContext } from '@/context/event-emitter' import { useEventEmitterContextContext } from '@/context/event-emitter'
import { useProviderContext } from '@/context/provider-context' import { useProviderContext } from '@/context/provider-context'
import { useFeatures } from '@/app/components/base/features/hooks' import { useFeatures } from '@/app/components/base/features/hooks'
import { noop } from 'lodash-es'


type TextGenerationItemProps = { type TextGenerationItemProps = {
modelAndParameter: ModelAndParameter modelAndParameter: ModelAndParameter
siteInfo={null} siteInfo={null}
messageId={messageId} messageId={messageId}
isError={false} isError={false}
onRetry={() => { }}
onRetry={noop}
inSidePanel inSidePanel
/> />
) )

+ 2
- 1
web/app/components/app/configuration/debug/index.tsx 查看文件

import PromptLogModal from '@/app/components/base/prompt-log-modal' import PromptLogModal from '@/app/components/base/prompt-log-modal'
import { useStore as useAppStore } from '@/app/components/app/store' import { useStore as useAppStore } from '@/app/components/app/store'
import { useFeatures, useFeaturesStore } from '@/app/components/base/features/hooks' import { useFeatures, useFeaturesStore } from '@/app/components/base/features/hooks'
import { noop } from 'lodash-es'


type IDebug = { type IDebug = {
isAPIKeySet: boolean isAPIKeySet: boolean
isInstalledApp={false} isInstalledApp={false}
messageId={messageId} messageId={messageId}
isError={false} isError={false}
onRetry={() => { }}
onRetry={noop}
siteInfo={null} siteInfo={null}
/> />
</div> </div>

+ 2
- 1
web/app/components/app/configuration/tools/external-data-tool-modal.tsx 查看文件

} from '@/models/common' } from '@/models/common'
import { useToastContext } from '@/app/components/base/toast' import { useToastContext } from '@/app/components/base/toast'
import AppIcon from '@/app/components/base/app-icon' import AppIcon from '@/app/components/base/app-icon'
import { noop } from 'lodash-es'


const systemTypes = ['api'] const systemTypes = ['api']
type ExternalDataToolModalProps = { type ExternalDataToolModalProps = {
return ( return (
<Modal <Modal
isShow isShow
onClose={() => { }}
onClose={noop}
className='!w-[640px] !max-w-none !p-8 !pb-6' className='!w-[640px] !max-w-none !p-8 !pb-6'
> >
<div className='mb-2 text-xl font-semibold text-gray-900'> <div className='mb-2 text-xl font-semibold text-gray-900'>

+ 2
- 1
web/app/components/app/create-from-dsl-modal/index.tsx 查看文件

import { getRedirection } from '@/utils/app-redirection' import { getRedirection } from '@/utils/app-redirection'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import { usePluginDependencies } from '@/app/components/workflow/plugin-dependency/hooks' import { usePluginDependencies } from '@/app/components/workflow/plugin-dependency/hooks'
import { noop } from 'lodash-es'


type CreateFromDSLModalProps = { type CreateFromDSLModalProps = {
show: boolean show: boolean
<Modal <Modal
className='w-[520px] rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg p-0 shadow-xl' className='w-[520px] rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg p-0 shadow-xl'
isShow={show} isShow={show}
onClose={() => { }}
onClose={noop}
> >
<div className='title-2xl-semi-bold flex items-center justify-between pb-3 pl-6 pr-5 pt-6 text-text-primary'> <div className='title-2xl-semi-bold flex items-center justify-between pb-3 pl-6 pr-5 pt-6 text-text-primary'>
{t('app.importFromDSL')} {t('app.importFromDSL')}

+ 2
- 1
web/app/components/app/duplicate-modal/index.tsx 查看文件

import { useProviderContext } from '@/context/provider-context' import { useProviderContext } from '@/context/provider-context'
import AppsFull from '@/app/components/billing/apps-full-in-dialog' import AppsFull from '@/app/components/billing/apps-full-in-dialog'
import type { AppIconType } from '@/types/app' import type { AppIconType } from '@/types/app'
import { noop } from 'lodash-es'


export type DuplicateAppModalProps = { export type DuplicateAppModalProps = {
appName: string appName: string
<> <>
<Modal <Modal
isShow={show} isShow={show}
onClose={() => { }}
onClose={noop}
className={cn('relative !max-w-[480px]', 'px-8')} className={cn('relative !max-w-[480px]', 'px-8')}
> >
<div className='absolute right-4 top-4 cursor-pointer p-2' onClick={onHide}> <div className='absolute right-4 top-4 cursor-pointer p-2' onClick={onHide}>

+ 2
- 1
web/app/components/app/log/list.tsx 查看文件

import { buildChatItemTree, getThreadMessages } from '@/app/components/base/chat/utils' import { buildChatItemTree, getThreadMessages } from '@/app/components/base/chat/utils'
import { getProcessedFilesFromResponse } from '@/app/components/base/file-uploader/utils' import { getProcessedFilesFromResponse } from '@/app/components/base/file-uploader/utils'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import { noop } from 'lodash-es'


dayjs.extend(utc) dayjs.extend(utc)
dayjs.extend(timezone) dayjs.extend(timezone)
content={detail.message.answer} content={detail.message.answer}
messageId={detail.message.id} messageId={detail.message.id}
isError={false} isError={false}
onRetry={() => { }}
onRetry={noop}
isInstalledApp={false} isInstalledApp={false}
supportFeedback supportFeedback
feedback={detail.message.feedbacks.find((item: any) => item.from_source === 'admin')} feedback={detail.message.feedbacks.find((item: any) => item.from_source === 'admin')}

+ 2
- 1
web/app/components/app/switch-app-modal/index.tsx 查看文件

import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback' import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
import AppIcon from '@/app/components/base/app-icon' import AppIcon from '@/app/components/base/app-icon'
import { useStore as useAppStore } from '@/app/components/app/store' import { useStore as useAppStore } from '@/app/components/app/store'
import { noop } from 'lodash-es'


type SwitchAppModalProps = { type SwitchAppModalProps = {
show: boolean show: boolean
<Modal <Modal
className={cn('w-[600px] max-w-[600px] p-8')} className={cn('w-[600px] max-w-[600px] p-8')}
isShow={show} isShow={show}
onClose={() => { }}
onClose={noop}
> >
<div className='absolute right-4 top-4 cursor-pointer p-2' onClick={onClose}> <div className='absolute right-4 top-4 cursor-pointer p-2' onClick={onClose}>
<RiCloseLine className='h-4 w-4 text-text-tertiary' /> <RiCloseLine className='h-4 w-4 text-text-tertiary' />

+ 2
- 1
web/app/components/base/app-icon-picker/index.tsx 查看文件

import type { AppIconType, ImageFile } from '@/types/app' import type { AppIconType, ImageFile } from '@/types/app'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import { DISABLE_UPLOAD_IMAGE_AS_ICON } from '@/config' import { DISABLE_UPLOAD_IMAGE_AS_ICON } from '@/config'
import { noop } from 'lodash-es'


export type AppIconEmojiSelection = { export type AppIconEmojiSelection = {
type: 'emoji' type: 'emoji'
} }


return <Modal return <Modal
onClose={() => { }}
onClose={noop}
isShow isShow
closable={false} closable={false}
wrapperClassName={className} wrapperClassName={className}

+ 16
- 15
web/app/components/base/chat/chat-with-history/context.tsx 查看文件

AppMeta, AppMeta,
ConversationItem, ConversationItem,
} from '@/models/share' } from '@/models/share'
import { noop } from 'lodash-es'


export type ChatWithHistoryContextValue = { export type ChatWithHistoryContextValue = {
appInfoError?: any appInfoError?: any
conversationList: [], conversationList: [],
newConversationInputs: {}, newConversationInputs: {},
newConversationInputsRef: { current: {} }, newConversationInputsRef: { current: {} },
handleNewConversationInputsChange: () => {},
handleNewConversationInputsChange: noop,
inputsForms: [], inputsForms: [],
handleNewConversation: () => {},
handleStartChat: () => {},
handleChangeConversation: () => {},
handlePinConversation: () => {},
handleUnpinConversation: () => {},
handleDeleteConversation: () => {},
handleNewConversation: noop,
handleStartChat: noop,
handleChangeConversation: noop,
handlePinConversation: noop,
handleUnpinConversation: noop,
handleDeleteConversation: noop,
conversationRenaming: false, conversationRenaming: false,
handleRenameConversation: () => {},
handleNewConversationCompleted: () => {},
handleRenameConversation: noop,
handleNewConversationCompleted: noop,
chatShouldReloadKey: '', chatShouldReloadKey: '',
isMobile: false, isMobile: false,
isInstalledApp: false, isInstalledApp: false,
handleFeedback: () => {},
currentChatInstanceRef: { current: { handleStop: () => {} } },
handleFeedback: noop,
currentChatInstanceRef: { current: { handleStop: noop } },
sidebarCollapseState: false, sidebarCollapseState: false,
handleSidebarCollapse: () => {},
handleSidebarCollapse: noop,
clearChatList: false, clearChatList: false,
setClearChatList: () => {},
setClearChatList: noop,
isResponding: false, isResponding: false,
setIsResponding: () => {},
setIsResponding: noop,
currentConversationInputs: {}, currentConversationInputs: {},
setCurrentConversationInputs: () => {},
setCurrentConversationInputs: noop,
}) })
export const useChatWithHistoryContext = () => useContext(ChatWithHistoryContext) export const useChatWithHistoryContext = () => useContext(ChatWithHistoryContext)

+ 2
- 1
web/app/components/base/chat/chat-with-history/hooks.tsx 查看文件

import { useAppFavicon } from '@/hooks/use-app-favicon' import { useAppFavicon } from '@/hooks/use-app-favicon'
import { InputVarType } from '@/app/components/workflow/types' import { InputVarType } from '@/app/components/workflow/types'
import { TransferMethod } from '@/types/app' import { TransferMethod } from '@/types/app'
import { noop } from 'lodash-es'


function getFormattedChatList(messages: any[]) { function getFormattedChatList(messages: any[]) {
const newChatList: ChatItem[] = [] const newChatList: ChatItem[] = []
callback?.() callback?.()
} }
}, [setShowNewConversationItemInList, checkInputsRequired]) }, [setShowNewConversationItemInList, checkInputsRequired])
const currentChatInstanceRef = useRef<{ handleStop: () => void }>({ handleStop: () => { } })
const currentChatInstanceRef = useRef<{ handleStop: () => void }>({ handleStop: noop })
const handleChangeConversation = useCallback((conversationId: string) => { const handleChangeConversation = useCallback((conversationId: string) => {
currentChatInstanceRef.current.handleStop() currentChatInstanceRef.current.handleStop()
setNewConversationId('') setNewConversationId('')

+ 11
- 10
web/app/components/base/chat/embedded-chatbot/context.tsx 查看文件

AppMeta, AppMeta,
ConversationItem, ConversationItem,
} from '@/models/share' } from '@/models/share'
import { noop } from 'lodash-es'


export type EmbeddedChatbotContextValue = { export type EmbeddedChatbotContextValue = {
appInfoError?: any appInfoError?: any
conversationList: [], conversationList: [],
newConversationInputs: {}, newConversationInputs: {},
newConversationInputsRef: { current: {} }, newConversationInputsRef: { current: {} },
handleNewConversationInputsChange: () => {},
handleNewConversationInputsChange: noop,
inputsForms: [], inputsForms: [],
handleNewConversation: () => {},
handleStartChat: () => {},
handleChangeConversation: () => {},
handleNewConversationCompleted: () => {},
handleNewConversation: noop,
handleStartChat: noop,
handleChangeConversation: noop,
handleNewConversationCompleted: noop,
chatShouldReloadKey: '', chatShouldReloadKey: '',
isMobile: false, isMobile: false,
isInstalledApp: false, isInstalledApp: false,
handleFeedback: () => {},
currentChatInstanceRef: { current: { handleStop: () => {} } },
handleFeedback: noop,
currentChatInstanceRef: { current: { handleStop: noop } },
clearChatList: false, clearChatList: false,
setClearChatList: () => {},
setClearChatList: noop,
isResponding: false, isResponding: false,
setIsResponding: () => {},
setIsResponding: noop,
currentConversationInputs: {}, currentConversationInputs: {},
setCurrentConversationInputs: () => {},
setCurrentConversationInputs: noop,
}) })
export const useEmbeddedChatbotContext = () => useContext(EmbeddedChatbotContext) export const useEmbeddedChatbotContext = () => useContext(EmbeddedChatbotContext)

+ 2
- 1
web/app/components/base/chat/embedded-chatbot/hooks.tsx 查看文件

import { InputVarType } from '@/app/components/workflow/types' import { InputVarType } from '@/app/components/workflow/types'
import { TransferMethod } from '@/types/app' import { TransferMethod } from '@/types/app'
import { addFileInfos, sortAgentSorts } from '@/app/components/tools/utils' import { addFileInfos, sortAgentSorts } from '@/app/components/tools/utils'
import { noop } from 'lodash-es'


function getFormattedChatList(messages: any[]) { function getFormattedChatList(messages: any[]) {
const newChatList: ChatItem[] = [] const newChatList: ChatItem[] = []
callback?.() callback?.()
} }
}, [setShowNewConversationItemInList, checkInputsRequired]) }, [setShowNewConversationItemInList, checkInputsRequired])
const currentChatInstanceRef = useRef<{ handleStop: () => void }>({ handleStop: () => { } })
const currentChatInstanceRef = useRef<{ handleStop: () => void }>({ handleStop: noop })
const handleChangeConversation = useCallback((conversationId: string) => { const handleChangeConversation = useCallback((conversationId: string) => {
currentChatInstanceRef.current.handleStop() currentChatInstanceRef.current.handleStop()
setNewConversationId('') setNewConversationId('')

+ 2
- 1
web/app/components/base/emoji-picker/index.tsx 查看文件

import Divider from '@/app/components/base/divider' import Divider from '@/app/components/base/divider'
import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
import Modal from '@/app/components/base/modal' import Modal from '@/app/components/base/modal'
import { noop } from 'lodash-es'


type IEmojiPickerProps = { type IEmojiPickerProps = {
isModal?: boolean isModal?: boolean


return isModal return isModal
? <Modal ? <Modal
onClose={() => { }}
onClose={noop}
isShow isShow
closable={false} closable={false}
wrapperClassName={className} wrapperClassName={className}

+ 2
- 1
web/app/components/base/features/new-feature-panel/conversation-opener/modal.tsx 查看文件

import type { InputVar } from '@/app/components/workflow/types' import type { InputVar } from '@/app/components/workflow/types'
import { getNewVar } from '@/utils/var' import { getNewVar } from '@/utils/var'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import { noop } from 'lodash-es'


type OpeningSettingModalProps = { type OpeningSettingModalProps = {
data: OpeningStatement data: OpeningStatement
return ( return (
<Modal <Modal
isShow isShow
onClose={() => { }}
onClose={noop}
className='!mt-14 !w-[640px] !max-w-none !bg-components-panel-bg-blur !p-6' className='!mt-14 !w-[640px] !max-w-none !bg-components-panel-bg-blur !p-6'
> >
<div className='mb-6 flex items-center justify-between'> <div className='mb-6 flex items-center justify-between'>

+ 2
- 1
web/app/components/base/features/new-feature-panel/moderation/moderation-setting-modal.tsx 查看文件

import { useModalContext } from '@/context/modal-context' import { useModalContext } from '@/context/modal-context'
import { CustomConfigurationStatusEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' import { CustomConfigurationStatusEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import { noop } from 'lodash-es'


const systemTypes = ['openai_moderation', 'keywords', 'api'] const systemTypes = ['openai_moderation', 'keywords', 'api']


return ( return (
<Modal <Modal
isShow isShow
onClose={() => { }}
onClose={noop}
className='!mt-14 !w-[600px] !max-w-none !p-6' className='!mt-14 !w-[600px] !max-w-none !p-6'
> >
<div className='flex items-center justify-between'> <div className='flex items-center justify-between'>

+ 3
- 2
web/app/components/base/file-uploader/hooks.ts 查看文件

import { formatFileSize } from '@/utils/format' import { formatFileSize } from '@/utils/format'
import { uploadRemoteFileInfo } from '@/service/common' import { uploadRemoteFileInfo } from '@/service/common'
import type { FileUploadConfigResponse } from '@/models/common' import type { FileUploadConfigResponse } from '@/models/common'
import { noop } from 'lodash-es'


export const useFileSizeLimit = (fileUploadConfig?: FileUploadConfigResponse) => { export const useFileSizeLimit = (fileUploadConfig?: FileUploadConfigResponse) => {
const imgSizeLimit = Number(fileUploadConfig?.image_file_size_limit) * 1024 * 1024 || IMG_SIZE_LIMIT const imgSizeLimit = Number(fileUploadConfig?.image_file_size_limit) * 1024 * 1024 || IMG_SIZE_LIMIT
}) })
}, [checkSizeLimit, handleAddFile, handleUpdateFile, notify, t, handleRemoveFile, fileConfig?.allowed_file_types, fileConfig.allowed_file_extensions, startProgressTimer, params.token]) }, [checkSizeLimit, handleAddFile, handleUpdateFile, notify, t, handleRemoveFile, fileConfig?.allowed_file_types, fileConfig.allowed_file_extensions, startProgressTimer, params.token])


const handleLoadFileFromLinkSuccess = useCallback(() => { }, [])
const handleLoadFileFromLinkSuccess = useCallback(noop, [])


const handleLoadFileFromLinkError = useCallback(() => { }, [])
const handleLoadFileFromLinkError = useCallback(noop, [])


const handleClearFiles = useCallback(() => { const handleClearFiles = useCallback(() => {
const { const {

+ 3
- 2
web/app/components/base/file-uploader/pdf-preview.tsx 查看文件

import Loading from '@/app/components/base/loading' import Loading from '@/app/components/base/loading'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import Tooltip from '@/app/components/base/tooltip' import Tooltip from '@/app/components/base/tooltip'
import { noop } from 'lodash-es'


type PdfPreviewProps = { type PdfPreviewProps = {
url: string url: string
<PdfHighlighter <PdfHighlighter
pdfDocument={pdfDocument} pdfDocument={pdfDocument}
enableAreaSelection={event => event.altKey} enableAreaSelection={event => event.altKey}
scrollRef={() => { }}
onScrollChange={() => { }}
scrollRef={noop}
onScrollChange={noop}
onSelectionFinished={() => null} onSelectionFinished={() => null}
highlightTransform={() => { return <div/> }} highlightTransform={() => { return <div/> }}
highlights={[]} highlights={[]}

+ 2
- 1
web/app/components/base/fullscreen-modal/index.tsx 查看文件

import { Dialog, DialogPanel, Transition, TransitionChild } from '@headlessui/react' import { Dialog, DialogPanel, Transition, TransitionChild } from '@headlessui/react'
import { RiCloseLargeLine } from '@remixicon/react' import { RiCloseLargeLine } from '@remixicon/react'
import classNames from '@/utils/classnames' import classNames from '@/utils/classnames'
import { noop } from 'lodash-es'


type IModal = { type IModal = {
className?: string className?: string
className, className,
wrapperClassName, wrapperClassName,
open, open,
onClose = () => { },
onClose = noop,
children, children,
closable = false, closable = false,
overflowVisible = false, overflowVisible = false,

+ 3
- 2
web/app/components/base/image-uploader/image-preview.tsx 查看文件

import { useHotkeys } from 'react-hotkeys-hook' import { useHotkeys } from 'react-hotkeys-hook'
import Tooltip from '@/app/components/base/tooltip' import Tooltip from '@/app/components/base/tooltip'
import Toast from '@/app/components/base/toast' import Toast from '@/app/components/base/toast'
import { noop } from 'lodash-es'


type ImagePreviewProps = { type ImagePreviewProps = {
url: string url: string
useHotkeys('esc', onCancel) useHotkeys('esc', onCancel)
useHotkeys('up', zoomIn) useHotkeys('up', zoomIn)
useHotkeys('down', zoomOut) useHotkeys('down', zoomOut)
useHotkeys('left', onPrev || (() => { }))
useHotkeys('right', onNext || (() => { }))
useHotkeys('left', onPrev || noop)
useHotkeys('right', onNext || noop)


return createPortal( return createPortal(
<div className='image-preview-container fixed inset-0 z-[1000] flex items-center justify-center bg-black/80 p-8' <div className='image-preview-container fixed inset-0 z-[1000] flex items-center justify-center bg-black/80 p-8'

+ 2
- 1
web/app/components/base/input/index.tsx 查看文件

import { RiCloseCircleFill, RiErrorWarningLine, RiSearchLine } from '@remixicon/react' import { RiCloseCircleFill, RiErrorWarningLine, RiSearchLine } from '@remixicon/react'
import { type VariantProps, cva } from 'class-variance-authority' import { type VariantProps, cva } from 'class-variance-authority'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import { noop } from 'lodash-es'


export const inputVariants = cva( export const inputVariants = cva(
'', '',
styleCss, styleCss,
value, value,
placeholder, placeholder,
onChange = () => { },
onChange = noop,
unit, unit,
...props ...props
}: InputProps) => { }: InputProps) => {

+ 2
- 1
web/app/components/base/modal/index.tsx 查看文件

import { Fragment } from 'react' import { Fragment } from 'react'
import { RiCloseLine } from '@remixicon/react' import { RiCloseLine } from '@remixicon/react'
import classNames from '@/utils/classnames' import classNames from '@/utils/classnames'
import { noop } from 'lodash-es'
// https://headlessui.com/react/dialog // https://headlessui.com/react/dialog


type IModal = { type IModal = {
className, className,
wrapperClassName, wrapperClassName,
isShow, isShow,
onClose = () => { },
onClose = noop,
title, title,
description, description,
children, children,

+ 2
- 1
web/app/components/base/notion-page-selector/notion-page-selector-modal/index.tsx 查看文件

import type { NotionPage } from '@/models/common' import type { NotionPage } from '@/models/common'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import Modal from '@/app/components/base/modal' import Modal from '@/app/components/base/modal'
import { noop } from 'lodash-es'


type NotionPageSelectorModalProps = { type NotionPageSelectorModalProps = {
isShow: boolean isShow: boolean
<Modal <Modal
className={s.modal} className={s.modal}
isShow={isShow} isShow={isShow}
onClose={() => { }}
onClose={noop}
> >
<div className='mb-6 flex h-8 items-center justify-between'> <div className='mb-6 flex h-8 items-center justify-between'>
<div className='text-xl font-semibold text-gray-900'>{t('common.dataSource.notion.selector.addPages')}</div> <div className='text-xl font-semibold text-gray-900'>{t('common.dataSource.notion.selector.addPages')}</div>

+ 2
- 1
web/app/components/base/prompt-editor/plugins/context-block/context-block-replacement-block.tsx 查看文件

ContextBlockNode, ContextBlockNode,
} from '../context-block/node' } from '../context-block/node'
import { CustomTextNode } from '../custom-text/node' import { CustomTextNode } from '../custom-text/node'
import { noop } from 'lodash-es'


const REGEX = new RegExp(CONTEXT_PLACEHOLDER_TEXT) const REGEX = new RegExp(CONTEXT_PLACEHOLDER_TEXT)


const ContextBlockReplacementBlock = ({ const ContextBlockReplacementBlock = ({
datasets = [], datasets = [],
onAddContext = () => {},
onAddContext = noop,
onInsert, onInsert,
canNotAddContext, canNotAddContext,
}: ContextBlockType) => { }: ContextBlockType) => {

+ 2
- 1
web/app/components/base/prompt-editor/plugins/context-block/index.tsx 查看文件

$createContextBlockNode, $createContextBlockNode,
ContextBlockNode, ContextBlockNode,
} from './node' } from './node'
import { noop } from 'lodash-es'


export const INSERT_CONTEXT_BLOCK_COMMAND = createCommand('INSERT_CONTEXT_BLOCK_COMMAND') export const INSERT_CONTEXT_BLOCK_COMMAND = createCommand('INSERT_CONTEXT_BLOCK_COMMAND')
export const DELETE_CONTEXT_BLOCK_COMMAND = createCommand('DELETE_CONTEXT_BLOCK_COMMAND') export const DELETE_CONTEXT_BLOCK_COMMAND = createCommand('DELETE_CONTEXT_BLOCK_COMMAND')


const ContextBlock = memo(({ const ContextBlock = memo(({
datasets = [], datasets = [],
onAddContext = () => {},
onAddContext = noop,
onInsert, onInsert,
onDelete, onDelete,
canNotAddContext, canNotAddContext,

+ 2
- 1
web/app/components/base/prompt-editor/plugins/history-block/history-block-replacement-block.tsx 查看文件

HistoryBlockNode, HistoryBlockNode,
} from '../history-block/node' } from '../history-block/node'
import { CustomTextNode } from '../custom-text/node' import { CustomTextNode } from '../custom-text/node'
import { noop } from 'lodash-es'


const REGEX = new RegExp(HISTORY_PLACEHOLDER_TEXT) const REGEX = new RegExp(HISTORY_PLACEHOLDER_TEXT)


const HistoryBlockReplacementBlock = ({ const HistoryBlockReplacementBlock = ({
history = { user: '', assistant: '' }, history = { user: '', assistant: '' },
onEditRole = () => {},
onEditRole = noop,
onInsert, onInsert,
}: HistoryBlockType) => { }: HistoryBlockType) => {
const [editor] = useLexicalComposerContext() const [editor] = useLexicalComposerContext()

+ 2
- 1
web/app/components/base/prompt-editor/plugins/history-block/index.tsx 查看文件

$createHistoryBlockNode, $createHistoryBlockNode,
HistoryBlockNode, HistoryBlockNode,
} from './node' } from './node'
import { noop } from 'lodash-es'


export const INSERT_HISTORY_BLOCK_COMMAND = createCommand('INSERT_HISTORY_BLOCK_COMMAND') export const INSERT_HISTORY_BLOCK_COMMAND = createCommand('INSERT_HISTORY_BLOCK_COMMAND')
export const DELETE_HISTORY_BLOCK_COMMAND = createCommand('DELETE_HISTORY_BLOCK_COMMAND') export const DELETE_HISTORY_BLOCK_COMMAND = createCommand('DELETE_HISTORY_BLOCK_COMMAND')


const HistoryBlock = memo(({ const HistoryBlock = memo(({
history = { user: '', assistant: '' }, history = { user: '', assistant: '' },
onEditRole = () => {},
onEditRole = noop,
onInsert, onInsert,
onDelete, onDelete,
}: HistoryBlockType) => { }: HistoryBlockType) => {

+ 2
- 1
web/app/components/base/radio-card/index.tsx 查看文件

import type { FC } from 'react' import type { FC } from 'react'
import React from 'react' import React from 'react'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import { noop } from 'lodash-es'


type Props = { type Props = {
className?: string className?: string
description, description,
noRadio, noRadio,
isChosen, isChosen,
onChosen = () => { },
onChosen = noop,
chosenConfig, chosenConfig,
chosenConfigWrapClassName, chosenConfigWrapClassName,
className, className,

+ 3
- 2
web/app/components/base/tag-management/selector.tsx 查看文件

import Checkbox from '@/app/components/base/checkbox' import Checkbox from '@/app/components/base/checkbox'
import { bindTag, createTag, fetchTagList, unBindTag } from '@/service/tag' import { bindTag, createTag, fetchTagList, unBindTag } from '@/service/tag'
import { ToastContext } from '@/app/components/base/toast' import { ToastContext } from '@/app/components/base/toast'
import { noop } from 'lodash-es'


type TagSelectorProps = { type TagSelectorProps = {
targetID: string targetID: string
<Checkbox <Checkbox
className='shrink-0' className='shrink-0'
checked={selectedTagIDs.includes(tag.id)} checked={selectedTagIDs.includes(tag.id)}
onCheck={() => { }}
onCheck={noop}
/> />
<div title={tag.name} className='grow truncate text-sm leading-5 text-text-secondary'>{tag.name}</div> <div title={tag.name} className='grow truncate text-sm leading-5 text-text-secondary'>{tag.name}</div>
</div> </div>
<Checkbox <Checkbox
className='shrink-0' className='shrink-0'
checked={selectedTagIDs.includes(tag.id)} checked={selectedTagIDs.includes(tag.id)}
onCheck={() => { }}
onCheck={noop}
/> />
<div title={tag.name} className='grow truncate text-sm leading-5 text-text-secondary'>{tag.name}</div> <div title={tag.name} className='grow truncate text-sm leading-5 text-text-secondary'>{tag.name}</div>
</div> </div>

+ 2
- 1
web/app/components/base/tag-management/tag-remove-modal.tsx 查看文件

import Modal from '@/app/components/base/modal' import Modal from '@/app/components/base/modal'
import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback' import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
import type { Tag } from '@/app/components/base/tag-management/constant' import type { Tag } from '@/app/components/base/tag-management/constant'
import { noop } from 'lodash-es'


type TagRemoveModalProps = { type TagRemoveModalProps = {
show: boolean show: boolean
<Modal <Modal
className={cn('w-[480px] max-w-[480px] p-8')} className={cn('w-[480px] max-w-[480px] p-8')}
isShow={show} isShow={show}
onClose={() => { }}
onClose={noop}
> >
<div className='absolute right-4 top-4 cursor-pointer p-2' onClick={onClose}> <div className='absolute right-4 top-4 cursor-pointer p-2' onClick={onClose}>
<RiCloseLine className='h-4 w-4 text-text-tertiary' /> <RiCloseLine className='h-4 w-4 text-text-tertiary' />

+ 3
- 2
web/app/components/base/toast/index.spec.tsx 查看文件

import { act, render, screen, waitFor } from '@testing-library/react' import { act, render, screen, waitFor } from '@testing-library/react'
import Toast, { ToastProvider, useToastContext } from '.' import Toast, { ToastProvider, useToastContext } from '.'
import '@testing-library/jest-dom' import '@testing-library/jest-dom'
import { noop } from 'lodash-es'


// Mock timers for testing timeouts // Mock timers for testing timeouts
jest.useFakeTimers() jest.useFakeTimers()


test('does not render close button when close is undefined', () => { test('does not render close button when close is undefined', () => {
// Create a modified context where close is undefined // Create a modified context where close is undefined
const CustomToastContext = React.createContext({ notify: () => { }, close: undefined })
const CustomToastContext = React.createContext({ notify: noop, close: undefined })


// Create a wrapper component using the custom context // Create a wrapper component using the custom context
const Wrapper = ({ children }: any) => ( const Wrapper = ({ children }: any) => (
<CustomToastContext.Provider value={{ notify: () => { }, close: undefined }}>
<CustomToastContext.Provider value={{ notify: noop, close: undefined }}>
{children} {children}
</CustomToastContext.Provider> </CustomToastContext.Provider>
) )

+ 2
- 1
web/app/components/base/toast/index.tsx 查看文件

import { createContext, useContext } from 'use-context-selector' import { createContext, useContext } from 'use-context-selector'
import ActionButton from '@/app/components/base/action-button' import ActionButton from '@/app/components/base/action-button'
import classNames from '@/utils/classnames' import classNames from '@/utils/classnames'
import { noop } from 'lodash-es'


export type IToastProps = { export type IToastProps = {
type?: 'success' | 'error' | 'warning' | 'info' type?: 'success' | 'error' | 'warning' | 'info'


root.render( root.render(
<ToastContext.Provider value={{ <ToastContext.Provider value={{
notify: () => { },
notify: noop,
close: () => { close: () => {
if (holder) { if (holder) {
root.unmount() root.unmount()

+ 2
- 1
web/app/components/base/with-input-validation/index.spec.tsx 查看文件

import '@testing-library/jest-dom' import '@testing-library/jest-dom'
import { z } from 'zod' import { z } from 'zod'
import withValidation from '.' import withValidation from '.'
import { noop } from 'lodash-es'


describe('withValidation HOC', () => { describe('withValidation HOC', () => {
// schema for validation // schema for validation
const WrappedComponent = withValidation(TestComponent, schema) const WrappedComponent = withValidation(TestComponent, schema)


beforeAll(() => { beforeAll(() => {
jest.spyOn(console, 'error').mockImplementation(() => { })
jest.spyOn(console, 'error').mockImplementation(noop)
}) })


afterAll(() => { afterAll(() => {

+ 2
- 1
web/app/components/datasets/common/document-status-with-action/index-failed.tsx 查看文件

import StatusWithAction from './status-with-action' import StatusWithAction from './status-with-action'
import { getErrorDocs, retryErrorDocs } from '@/service/datasets' import { getErrorDocs, retryErrorDocs } from '@/service/datasets'
import type { IndexingStatusResponse } from '@/models/datasets' import type { IndexingStatusResponse } from '@/models/datasets'
import { noop } from 'lodash-es'


type Props = { type Props = {
datasetId: string datasetId: string
description={`${errorDocs?.total} ${t('dataset.docsFailedNotice')}`} description={`${errorDocs?.total} ${t('dataset.docsFailedNotice')}`}
actionText={t('dataset.retry')} actionText={t('dataset.retry')}
disabled={indexState.value === 'retry'} disabled={indexState.value === 'retry'}
onAction={indexState.value === 'error' ? onRetryErrorDocs : () => { }}
onAction={indexState.value === 'error' ? onRetryErrorDocs : noop}
/> />
) )
} }

+ 2
- 1
web/app/components/datasets/documents/detail/batch-modal/index.tsx 查看文件

import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
import Modal from '@/app/components/base/modal' import Modal from '@/app/components/base/modal'
import type { ChunkingMode } from '@/models/datasets' import type { ChunkingMode } from '@/models/datasets'
import { noop } from 'lodash-es'


export type IBatchModalProps = { export type IBatchModalProps = {
isShow: boolean isShow: boolean
}, [isShow]) }, [isShow])


return ( return (
<Modal isShow={isShow} onClose={() => { }} className='!max-w-[520px] !rounded-xl px-8 py-6'>
<Modal isShow={isShow} onClose={noop} className='!max-w-[520px] !rounded-xl px-8 py-6'>
<div className='relative pb-1 text-xl font-medium leading-[30px] text-gray-900'>{t('datasetDocuments.list.batchModal.title')}</div> <div className='relative pb-1 text-xl font-medium leading-[30px] text-gray-900'>{t('datasetDocuments.list.batchModal.title')}</div>
<div className='absolute right-4 top-4 cursor-pointer p-2' onClick={onCancel}> <div className='absolute right-4 top-4 cursor-pointer p-2' onClick={onCancel}>
<RiCloseLine className='h-4 w-4 text-gray-500' /> <RiCloseLine className='h-4 w-4 text-gray-500' />

+ 2
- 1
web/app/components/datasets/documents/detail/completed/common/full-screen-drawer.tsx 查看文件

import React, { type FC } from 'react' import React, { type FC } from 'react'
import Drawer from '@/app/components/base/drawer' import Drawer from '@/app/components/base/drawer'
import classNames from '@/utils/classnames' import classNames from '@/utils/classnames'
import { noop } from 'lodash-es'


type IFullScreenDrawerProps = { type IFullScreenDrawerProps = {
isOpen: boolean isOpen: boolean


const FullScreenDrawer: FC<IFullScreenDrawerProps> = ({ const FullScreenDrawer: FC<IFullScreenDrawerProps> = ({
isOpen, isOpen,
onClose = () => {},
onClose = noop,
fullScreen, fullScreen,
children, children,
}) => { }) => {

+ 2
- 1
web/app/components/datasets/documents/detail/completed/common/regeneration-modal.tsx 查看文件

import Modal from '@/app/components/base/modal' import Modal from '@/app/components/base/modal'
import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
import { useEventEmitterContextContext } from '@/context/event-emitter' import { useEventEmitterContextContext } from '@/context/event-emitter'
import { noop } from 'lodash-es'


type IDefaultContentProps = { type IDefaultContentProps = {
onCancel: () => void onCancel: () => void
}) })


return ( return (
<Modal isShow={isShow} onClose={() => {}} className='!max-w-[480px] !rounded-2xl'>
<Modal isShow={isShow} onClose={noop} className='!max-w-[480px] !rounded-2xl'>
{!loading && !updateSucceeded && <DefaultContent onCancel={onCancel} onConfirm={onConfirm} />} {!loading && !updateSucceeded && <DefaultContent onCancel={onCancel} onConfirm={onConfirm} />}
{loading && !updateSucceeded && <RegeneratingContent />} {loading && !updateSucceeded && <RegeneratingContent />}
{!loading && updateSucceeded && <RegenerationCompletedContent onClose={onClose} />} {!loading && updateSucceeded && <RegenerationCompletedContent onClose={onClose} />}

+ 2
- 1
web/app/components/datasets/documents/detail/completed/index.tsx 查看文件

useUpdateSegment, useUpdateSegment,
} from '@/service/knowledge/use-segment' } from '@/service/knowledge/use-segment'
import { useInvalid } from '@/service/use-base' import { useInvalid } from '@/service/use-base'
import { noop } from 'lodash-es'


const DEFAULT_LIMIT = 10 const DEFAULT_LIMIT = 10


const SegmentListContext = createContext<SegmentListContextValue>({ const SegmentListContext = createContext<SegmentListContextValue>({
isCollapsed: true, isCollapsed: true,
fullScreen: false, fullScreen: false,
toggleFullScreen: () => {},
toggleFullScreen: noop,
currSegment: { showModal: false }, currSegment: { showModal: false },
currChildChunk: { showModal: false }, currChildChunk: { showModal: false },
}) })

+ 2
- 1
web/app/components/datasets/metadata/metadata-dataset/create-content.tsx 查看文件

import Input from '@/app/components/base/input' import Input from '@/app/components/base/input'
import { RiArrowLeftLine } from '@remixicon/react' import { RiArrowLeftLine } from '@remixicon/react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { noop } from 'lodash-es'


const i18nPrefix = 'dataset.metadata.createMetadata' const i18nPrefix = 'dataset.metadata.createMetadata'


} }


const CreateContent: FC<Props> = ({ const CreateContent: FC<Props> = ({
onClose = () => { },
onClose = noop,
hasBack, hasBack,
onBack, onBack,
onSave, onSave,

+ 2
- 1
web/app/components/datasets/rename-modal/index.tsx 查看文件

import { ToastContext } from '@/app/components/base/toast' import { ToastContext } from '@/app/components/base/toast'
import type { DataSet } from '@/models/datasets' import type { DataSet } from '@/models/datasets'
import { updateDatasetSetting } from '@/service/datasets' import { updateDatasetSetting } from '@/service/datasets'
import { noop } from 'lodash-es'


type RenameDatasetModalProps = { type RenameDatasetModalProps = {
show: boolean show: boolean
<Modal <Modal
className='w-[520px] max-w-[520px] rounded-xl px-8 py-6' className='w-[520px] max-w-[520px] rounded-xl px-8 py-6'
isShow={show} isShow={show}
onClose={() => { }}
onClose={noop}
> >
<div className='relative pb-2 text-xl font-medium leading-[30px] text-text-primary'>{t('datasetSettings.title')}</div> <div className='relative pb-2 text-xl font-medium leading-[30px] text-text-primary'>{t('datasetSettings.title')}</div>
<div className='absolute right-4 top-4 cursor-pointer p-2' onClick={onClose}> <div className='absolute right-4 top-4 cursor-pointer p-2' onClick={onClose}>

+ 2
- 1
web/app/components/header/account-about/index.tsx 查看文件

import type { LangGeniusVersionResponse } from '@/models/common' import type { LangGeniusVersionResponse } from '@/models/common'
import { IS_CE_EDITION } from '@/config' import { IS_CE_EDITION } from '@/config'
import LogoSite from '@/app/components/base/logo/logo-site' import LogoSite from '@/app/components/base/logo/logo-site'
import { noop } from 'lodash-es'


type IAccountSettingProps = { type IAccountSettingProps = {
langeniusVersionInfo: LangGeniusVersionResponse langeniusVersionInfo: LangGeniusVersionResponse
return ( return (
<Modal <Modal
isShow isShow
onClose={() => { }}
onClose={noop}
className='!w-[480px] !max-w-[480px] !px-6 !py-4' className='!w-[480px] !max-w-[480px] !px-6 !py-4'
> >
<div className='relative pt-4'> <div className='relative pt-4'>

+ 2
- 1
web/app/components/header/account-setting/api-based-extension-page/modal.tsx 查看文件

updateApiBasedExtension, updateApiBasedExtension,
} from '@/service/common' } from '@/service/common'
import { useToastContext } from '@/app/components/base/toast' import { useToastContext } from '@/app/components/base/toast'
import { noop } from 'lodash-es'


export type ApiBasedExtensionData = { export type ApiBasedExtensionData = {
name?: string name?: string
return ( return (
<Modal <Modal
isShow isShow
onClose={() => { }}
onClose={noop}
className='!w-[640px] !max-w-none !p-8 !pb-6' className='!w-[640px] !max-w-none !p-8 !pb-6'
> >
<div className='mb-2 text-xl font-semibold text-text-primary'> <div className='mb-2 text-xl font-semibold text-text-primary'>

+ 2
- 1
web/app/components/header/account-setting/data-source-page/data-source-notion/index.tsx 查看文件

import { useAppContext } from '@/context/app-context' import { useAppContext } from '@/context/app-context'
import { fetchNotionConnection } from '@/service/common' import { fetchNotionConnection } from '@/service/common'
import NotionIcon from '@/app/components/base/notion-icon' import NotionIcon from '@/app/components/base/notion-icon'
import { noop } from 'lodash-es'


const Icon: FC<{ const Icon: FC<{
src: string src: string
total: workspace.source_info.total || 0, total: workspace.source_info.total || 0,
}, },
}))} }))}
onRemove={() => { }} // handled in operation/index.tsx
onRemove={noop} // handled in operation/index.tsx
notionActions={{ notionActions={{
onChangeAuthorizedPage: handleAuthAgain, onChangeAuthorizedPage: handleAuthAgain,
}} }}

+ 3
- 1
web/app/components/header/account-setting/members-page/edit-workspace-modal/index.tsx 查看文件

import { useAppContext } from '@/context/app-context' import { useAppContext } from '@/context/app-context'
import { updateWorkspaceInfo } from '@/service/common' import { updateWorkspaceInfo } from '@/service/common'
import { ToastContext } from '@/app/components/base/toast' import { ToastContext } from '@/app/components/base/toast'
import { noop } from 'lodash-es'

type IEditWorkspaceModalProps = { type IEditWorkspaceModalProps = {
onCancel: () => void onCancel: () => void
} }


return ( return (
<div className={cn(s.wrap)}> <div className={cn(s.wrap)}>
<Modal overflowVisible isShow onClose={() => {}} className={cn(s.modal)}>
<Modal overflowVisible isShow onClose={noop} className={cn(s.modal)}>
<div className='mb-2 flex justify-between'> <div className='mb-2 flex justify-between'>
<div className='text-xl font-semibold text-text-primary'>{t('common.account.editWorkspaceInfo')}</div> <div className='text-xl font-semibold text-text-primary'>{t('common.account.editWorkspaceInfo')}</div>
<RiCloseLine className='h-4 w-4 cursor-pointer text-text-tertiary' onClick={onCancel} /> <RiCloseLine className='h-4 w-4 cursor-pointer text-text-tertiary' onClick={onCancel} />

+ 3
- 2
web/app/components/header/account-setting/members-page/invite-modal/index.tsx 查看文件

import { ToastContext } from '@/app/components/base/toast' import { ToastContext } from '@/app/components/base/toast'
import type { InvitationResult } from '@/models/common' import type { InvitationResult } from '@/models/common'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'

import 'react-multi-email/dist/style.css' import 'react-multi-email/dist/style.css'
import { noop } from 'lodash-es'

type IInviteModalProps = { type IInviteModalProps = {
isEmailSetup: boolean isEmailSetup: boolean
onCancel: () => void onCancel: () => void


return ( return (
<div className={cn(s.wrap)}> <div className={cn(s.wrap)}>
<Modal overflowVisible isShow onClose={() => { }} className={cn(s.modal)}>
<Modal overflowVisible isShow onClose={noop} className={cn(s.modal)}>
<div className='mb-2 flex justify-between'> <div className='mb-2 flex justify-between'>
<div className='text-xl font-semibold text-text-primary'>{t('common.members.inviteTeamMember')}</div> <div className='text-xl font-semibold text-text-primary'>{t('common.members.inviteTeamMember')}</div>
<RiCloseLine className='h-4 w-4 cursor-pointer text-text-tertiary' onClick={onCancel} /> <RiCloseLine className='h-4 w-4 cursor-pointer text-text-tertiary' onClick={onCancel} />

+ 2
- 1
web/app/components/header/account-setting/members-page/invited-modal/index.tsx 查看文件

import { IS_CE_EDITION } from '@/config' import { IS_CE_EDITION } from '@/config'
import type { InvitationResult } from '@/models/common' import type { InvitationResult } from '@/models/common'
import Tooltip from '@/app/components/base/tooltip' import Tooltip from '@/app/components/base/tooltip'
import { noop } from 'lodash-es'


export type SuccessInvitationResult = Extract<InvitationResult, { status: 'success' }> export type SuccessInvitationResult = Extract<InvitationResult, { status: 'success' }>
export type FailedInvitationResult = Extract<InvitationResult, { status: 'failed' }> export type FailedInvitationResult = Extract<InvitationResult, { status: 'failed' }>


return ( return (
<div className={s.wrap}> <div className={s.wrap}>
<Modal isShow onClose={() => {}} className={s.modal}>
<Modal isShow onClose={noop} className={s.modal}>
<div className='mb-3 flex justify-between'> <div className='mb-3 flex justify-between'>
<div className=' <div className='
flex h-12 w-12 items-center justify-center rounded-xl flex h-12 w-12 items-center justify-center rounded-xl

+ 2
- 1
web/app/components/header/account-setting/menu-dialog.tsx 查看文件

import type { ReactNode } from 'react' import type { ReactNode } from 'react'
import { Dialog, DialogPanel, Transition, TransitionChild } from '@headlessui/react' import { Dialog, DialogPanel, Transition, TransitionChild } from '@headlessui/react'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import { noop } from 'lodash-es'


type DialogProps = { type DialogProps = {
className?: string className?: string


return ( return (
<Transition appear show={show} as={Fragment}> <Transition appear show={show} as={Fragment}>
<Dialog as="div" className="relative z-[60]" onClose={() => { }}>
<Dialog as="div" className="relative z-[60]" onClose={noop}>
<div className="fixed inset-0"> <div className="fixed inset-0">
<div className="flex min-h-full flex-col items-center justify-center"> <div className="flex min-h-full flex-col items-center justify-center">
<TransitionChild> <TransitionChild>

+ 2
- 1
web/app/components/header/app-selector/index.tsx 查看文件

import CreateAppDialog from '@/app/components/app/create-app-dialog' import CreateAppDialog from '@/app/components/app/create-app-dialog'
import AppIcon from '@/app/components/base/app-icon' import AppIcon from '@/app/components/base/app-icon'
import { useAppContext } from '@/context/app-context' import { useAppContext } from '@/context/app-context'
import { noop } from 'lodash-es'


type IAppSelectorProps = { type IAppSelectorProps = {
appItems: AppDetailResponse[] appItems: AppDetailResponse[]
<CreateAppDialog <CreateAppDialog
show={showNewAppDialog} show={showNewAppDialog}
onClose={() => setShowNewAppDialog(false)} onClose={() => setShowNewAppDialog(false)}
onSuccess={() => { }}
onSuccess={noop}
/> />
</div> </div>
) )

+ 12
- 11
web/app/components/plugins/marketplace/context.tsx 查看文件

getMarketplaceListFilterType, getMarketplaceListFilterType,
} from './utils' } from './utils'
import { useInstalledPluginList } from '@/service/use-plugins' import { useInstalledPluginList } from '@/service/use-plugins'
import { noop } from 'lodash-es'


export type MarketplaceContextValue = { export type MarketplaceContextValue = {
intersected: boolean intersected: boolean


export const MarketplaceContext = createContext<MarketplaceContextValue>({ export const MarketplaceContext = createContext<MarketplaceContextValue>({
intersected: true, intersected: true,
setIntersected: () => {},
setIntersected: noop,
searchPluginText: '', searchPluginText: '',
handleSearchPluginTextChange: () => {},
handleSearchPluginTextChange: noop,
filterPluginTags: [], filterPluginTags: [],
handleFilterPluginTagsChange: () => {},
handleFilterPluginTagsChange: noop,
activePluginType: 'all', activePluginType: 'all',
handleActivePluginTypeChange: () => {},
handleActivePluginTypeChange: noop,
page: 1, page: 1,
handlePageChange: () => {},
handlePageChange: noop,
plugins: undefined, plugins: undefined,
pluginsTotal: 0, pluginsTotal: 0,
resetPlugins: () => {},
resetPlugins: noop,
sort: DEFAULT_SORT, sort: DEFAULT_SORT,
handleSortChange: () => {},
handleQueryPlugins: () => {},
handleMoreClick: () => {},
handleSortChange: noop,
handleQueryPlugins: noop,
handleMoreClick: noop,
marketplaceCollectionsFromClient: [], marketplaceCollectionsFromClient: [],
setMarketplaceCollectionsFromClient: () => {},
setMarketplaceCollectionsFromClient: noop,
marketplaceCollectionPluginsMapFromClient: {}, marketplaceCollectionPluginsMapFromClient: {},
setMarketplaceCollectionPluginsMapFromClient: () => {},
setMarketplaceCollectionPluginsMapFromClient: noop,
isLoading: false, isLoading: false,
isSuccessCollections: false, isSuccessCollections: false,
}) })

+ 4
- 3
web/app/components/plugins/plugin-page/context.tsx 查看文件

import type { FilterState } from './filter-management' import type { FilterState } from './filter-management'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useTabSearchParams } from '@/hooks/use-tab-searchparams' import { useTabSearchParams } from '@/hooks/use-tab-searchparams'
import { noop } from 'lodash-es'


export type PluginPageContextValue = { export type PluginPageContextValue = {
containerRef: React.RefObject<HTMLDivElement> containerRef: React.RefObject<HTMLDivElement>
export const PluginPageContext = createContext<PluginPageContextValue>({ export const PluginPageContext = createContext<PluginPageContextValue>({
containerRef: { current: null }, containerRef: { current: null },
currentPluginID: undefined, currentPluginID: undefined,
setCurrentPluginID: () => { },
setCurrentPluginID: noop,
filters: { filters: {
categories: [], categories: [],
tags: [], tags: [],
searchQuery: '', searchQuery: '',
}, },
setFilters: () => { },
setFilters: noop,
activeTab: '', activeTab: '',
setActiveTab: () => { },
setActiveTab: noop,
options: [], options: [],
}) })



+ 3
- 2
web/app/components/plugins/plugin-page/empty/index.tsx 查看文件

import { useInstalledPluginList } from '@/service/use-plugins' import { useInstalledPluginList } from '@/service/use-plugins'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { SUPPORT_INSTALL_LOCAL_FILE_EXTENSIONS } from '@/config' import { SUPPORT_INSTALL_LOCAL_FILE_EXTENSIONS } from '@/config'
import { noop } from 'lodash-es'


const Empty = () => { const Empty = () => {
const { t } = useTranslation() const { t } = useTranslation()
</div> </div>
</div> </div>
{selectedAction === 'github' && <InstallFromGitHub {selectedAction === 'github' && <InstallFromGitHub
onSuccess={() => { }}
onSuccess={noop}
onClose={() => setSelectedAction(null)} onClose={() => setSelectedAction(null)}
/>} />}
{selectedAction === 'local' && selectedFile {selectedAction === 'local' && selectedFile
&& (<InstallFromLocalPackage && (<InstallFromLocalPackage
file={selectedFile} file={selectedFile}
onClose={() => setSelectedAction(null)} onClose={() => setSelectedAction(null)}
onSuccess={() => { }}
onSuccess={noop}
/> />
) )
} }

+ 4
- 3
web/app/components/plugins/plugin-page/index.tsx 查看文件

import { SUPPORT_INSTALL_LOCAL_FILE_EXTENSIONS } from '@/config' import { SUPPORT_INSTALL_LOCAL_FILE_EXTENSIONS } from '@/config'
import { LanguagesSupported } from '@/i18n/language' import { LanguagesSupported } from '@/i18n/language'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { noop } from 'lodash-es'


const PACKAGE_IDS_KEY = 'package-ids' const PACKAGE_IDS_KEY = 'package-ids'
const BUNDLE_INFO_KEY = 'bundle-info' const BUNDLE_INFO_KEY = 'bundle-info'
{currentFile && ( {currentFile && (
<InstallFromLocalPackage <InstallFromLocalPackage
file={currentFile} file={currentFile}
onClose={removeFile ?? (() => { })}
onSuccess={() => { }}
onClose={removeFile ?? noop}
onSuccess={noop}
/> />
)} )}
<input <input
type="file" type="file"
id="fileUploader" id="fileUploader"
accept={SUPPORT_INSTALL_LOCAL_FILE_EXTENSIONS} accept={SUPPORT_INSTALL_LOCAL_FILE_EXTENSIONS}
onChange={fileChangeHandle ?? (() => { })}
onChange={fileChangeHandle ?? noop}
/> />
</> </>
)} )}

+ 3
- 2
web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx 查看文件

import { useSelector as useAppContextSelector } from '@/context/app-context' import { useSelector as useAppContextSelector } from '@/context/app-context'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { SUPPORT_INSTALL_LOCAL_FILE_EXTENSIONS } from '@/config' import { SUPPORT_INSTALL_LOCAL_FILE_EXTENSIONS } from '@/config'
import { noop } from 'lodash-es'


type Props = { type Props = {
onSwitchToMarketplaceTab: () => void onSwitchToMarketplaceTab: () => void
</PortalToFollowElemContent> </PortalToFollowElemContent>
</div> </div>
{selectedAction === 'github' && <InstallFromGitHub {selectedAction === 'github' && <InstallFromGitHub
onSuccess={() => { }}
onSuccess={noop}
onClose={() => setSelectedAction(null)} onClose={() => setSelectedAction(null)}
/>} />}
{selectedAction === 'local' && selectedFile {selectedAction === 'local' && selectedFile
&& (<InstallFromLocalPackage && (<InstallFromLocalPackage
file={selectedFile} file={selectedFile}
onClose={() => setSelectedAction(null)} onClose={() => setSelectedAction(null)}
onSuccess={() => { }}
onSuccess={noop}
/> />
) )
} }

+ 2
- 1
web/app/components/tools/labels/selector.tsx 查看文件

import Checkbox from '@/app/components/base/checkbox' import Checkbox from '@/app/components/base/checkbox'
import type { Label } from '@/app/components/tools/labels/constant' import type { Label } from '@/app/components/tools/labels/constant'
import { useTags } from '@/app/components/plugins/hooks' import { useTags } from '@/app/components/plugins/hooks'
import { noop } from 'lodash-es'


type LabelSelectorProps = { type LabelSelectorProps = {
value: string[] value: string[]
<Checkbox <Checkbox
className='shrink-0' className='shrink-0'
checked={value.includes(label.name)} checked={value.includes(label.name)}
onCheck={() => { }}
onCheck={noop}
/> />
<div title={label.label} className='grow truncate text-sm leading-5 text-text-secondary'>{label.label}</div> <div title={label.label} className='grow truncate text-sm leading-5 text-text-secondary'>{label.label}</div>
</div> </div>

+ 2
- 1
web/app/components/tools/setting/build-in/config-credentials.tsx 查看文件

import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form' import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form'
import { LinkExternal02 } from '@/app/components/base/icons/src/vender/line/general' import { LinkExternal02 } from '@/app/components/base/icons/src/vender/line/general'
import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks' import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks'
import { noop } from 'lodash-es'


type Props = { type Props = {
collection: Collection collection: Collection
onCancel, onCancel,
onSaved, onSaved,
isHideRemoveBtn, isHideRemoveBtn,
onRemove = () => { },
onRemove = noop,
isSaving, isSaving,
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()

+ 2
- 1
web/app/components/tools/workflow-tool/confirm-modal/index.tsx 查看文件

import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
import Modal from '@/app/components/base/modal' import Modal from '@/app/components/base/modal'
import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback' import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
import { noop } from 'lodash-es'


type ConfirmModalProps = { type ConfirmModalProps = {
show: boolean show: boolean
<Modal <Modal
className={cn('w-[600px] max-w-[600px] p-8')} className={cn('w-[600px] max-w-[600px] p-8')}
isShow={show} isShow={show}
onClose={() => { }}
onClose={noop}
> >
<div className='absolute right-4 top-4 cursor-pointer p-2' onClick={onClose}> <div className='absolute right-4 top-4 cursor-pointer p-2' onClick={onClose}>
<RiCloseLine className='h-4 w-4 text-text-tertiary' /> <RiCloseLine className='h-4 w-4 text-text-tertiary' />

+ 2
- 1
web/app/components/workflow/dsl-export-confirm-modal.tsx 查看文件

import Checkbox from '@/app/components/base/checkbox' import Checkbox from '@/app/components/base/checkbox'
import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
import type { EnvironmentVariable } from '@/app/components/workflow/types' import type { EnvironmentVariable } from '@/app/components/workflow/types'
import { noop } from 'lodash-es'


export type DSLExportConfirmModalProps = { export type DSLExportConfirmModalProps = {
envList: EnvironmentVariable[] envList: EnvironmentVariable[]
return ( return (
<Modal <Modal
isShow={true} isShow={true}
onClose={() => { }}
onClose={noop}
className={cn('w-[480px] max-w-[480px]')} className={cn('w-[480px] max-w-[480px]')}
> >
<div className='title-2xl-semi-bold relative pb-6 text-text-primary'>{t('workflow.env.export.title')}</div> <div className='title-2xl-semi-bold relative pb-6 text-text-primary'>{t('workflow.env.export.title')}</div>

+ 2
- 2
web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx 查看文件

import { import {
getFilesInLogs, getFilesInLogs,
} from '@/app/components/base/file-uploader/utils' } from '@/app/components/base/file-uploader/utils'

import './style.css' import './style.css'
import { noop } from 'lodash-es'


// load file from local instead of cdn https://github.com/suren-atoyan/monaco-react/issues/482 // load file from local instead of cdn https://github.com/suren-atoyan/monaco-react/issues/482
loader.config({ paths: { vs: '/vs' } }) loader.config({ paths: { vs: '/vs' } })
const CodeEditor: FC<Props> = ({ const CodeEditor: FC<Props> = ({
value = '', value = '',
placeholder = '', placeholder = '',
onChange = () => { },
onChange = noop,
title = '', title = '',
headerRight, headerRight,
language, language,

+ 2
- 1
web/app/components/workflow/nodes/_base/components/file-type-item.tsx 查看文件

import TagInput from '@/app/components/base/tag-input' import TagInput from '@/app/components/base/tag-input'
import Checkbox from '@/app/components/base/checkbox' import Checkbox from '@/app/components/base/checkbox'
import { FileTypeIcon } from '@/app/components/base/file-uploader' import { FileTypeIcon } from '@/app/components/base/file-uploader'
import { noop } from 'lodash-es'


type Props = { type Props = {
type: SupportUploadFileTypes.image | SupportUploadFileTypes.document | SupportUploadFileTypes.audio | SupportUploadFileTypes.video | SupportUploadFileTypes.custom type: SupportUploadFileTypes.image | SupportUploadFileTypes.document | SupportUploadFileTypes.audio | SupportUploadFileTypes.video | SupportUploadFileTypes.custom
selected, selected,
onToggle, onToggle,
customFileTypes = [], customFileTypes = [],
onCustomFileTypesChange = () => { },
onCustomFileTypesChange = noop,
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()



+ 3
- 2
web/app/components/workflow/nodes/_base/components/input-support-select-var.tsx 查看文件

import PromptEditor from '@/app/components/base/prompt-editor' import PromptEditor from '@/app/components/base/prompt-editor'
import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
import Tooltip from '@/app/components/base/tooltip' import Tooltip from '@/app/components/base/tooltip'
import { noop } from 'lodash-es'


type Props = { type Props = {
instanceId?: string instanceId?: string
show: false, show: false,
selectable: false, selectable: false,
datasets: [], datasets: [],
onAddContext: () => { },
onAddContext: noop,
}} }}
historyBlock={{ historyBlock={{
show: false, show: false,
user: 'Human', user: 'Human',
assistant: 'Assistant', assistant: 'Assistant',
}, },
onEditRole: () => { },
onEditRole: noop,
}} }}
queryBlock={{ queryBlock={{
show: false, show: false,

+ 3
- 2
web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx 查看文件

import Badge from '@/app/components/base/badge' import Badge from '@/app/components/base/badge'
import Tooltip from '@/app/components/base/tooltip' import Tooltip from '@/app/components/base/tooltip'
import { isExceptionVariable } from '@/app/components/workflow/utils' import { isExceptionVariable } from '@/app/components/workflow/utils'
import { noop } from 'lodash-es'


const TRIGGER_DEFAULT_WIDTH = 227 const TRIGGER_DEFAULT_WIDTH = 227


className, className,
isShowNodeName = true, isShowNodeName = true,
value = [], value = [],
onOpen = () => { },
onOpen = noop,
onChange, onChange,
isSupportConstantValue, isSupportConstantValue,
defaultVarKindType = VarKindType.constant, defaultVarKindType = VarKindType.constant,
{isAddBtnTrigger {isAddBtnTrigger
? ( ? (
<div> <div>
<AddButton onClick={() => { }}></AddButton>
<AddButton onClick={noop}></AddButton>
</div> </div>
) )
: (<div ref={!isSupportConstantValue ? triggerRef : null} className={cn((open || isFocus) ? 'border-gray-300' : 'border-gray-100', 'group/wrap relative flex h-8 w-full items-center', !isSupportConstantValue && 'rounded-lg bg-components-input-bg-normal p-1', isInTable && 'border-none bg-transparent', readonly && 'bg-components-input-bg-disabled')}> : (<div ref={!isSupportConstantValue ? triggerRef : null} className={cn((open || isFocus) ? 'border-gray-300' : 'border-gray-100', 'group/wrap relative flex h-8 w-full items-center', !isSupportConstantValue && 'rounded-lg bg-components-input-bg-normal p-1', isInTable && 'border-none bg-transparent', readonly && 'bg-components-input-bg-disabled')}>

+ 2
- 1
web/app/components/workflow/nodes/assigner/components/var-list/index.tsx 查看文件

import Input from '@/app/components/base/input' import Input from '@/app/components/base/input'
import Textarea from '@/app/components/base/textarea' import Textarea from '@/app/components/base/textarea'
import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor' import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor'
import { noop } from 'lodash-es'


type Props = { type Props = {
readonly: boolean readonly: boolean
nodeId, nodeId,
list, list,
onChange, onChange,
onOpen = () => { },
onOpen = noop,
filterVar, filterVar,
filterToAssignedVar, filterToAssignedVar,
getAssignedVarType, getAssignedVarType,

+ 2
- 1
web/app/components/workflow/nodes/if-else/components/condition-wrap.tsx 查看文件

import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
import { PortalSelect as Select } from '@/app/components/base/select' import { PortalSelect as Select } from '@/app/components/base/select'
import { noop } from 'lodash-es'


type Props = { type Props = {
isSubVariable?: boolean isSubVariable?: boolean
nodeId: id = '', nodeId: id = '',
cases = [], cases = [],
readOnly, readOnly,
handleSortCase = () => { },
handleSortCase = noop,
handleRemoveCase, handleRemoveCase,
handleUpdateCondition, handleUpdateCondition,
handleAddCondition, handleAddCondition,

+ 3
- 2
web/app/components/workflow/nodes/knowledge-retrieval/components/metadata/metadata-filter/index.tsx 查看文件

import type { MetadataShape } from '@/app/components/workflow/nodes/knowledge-retrieval/types' import type { MetadataShape } from '@/app/components/workflow/nodes/knowledge-retrieval/types'
import { MetadataFilteringModeEnum } from '@/app/components/workflow/nodes/knowledge-retrieval/types' import { MetadataFilteringModeEnum } from '@/app/components/workflow/nodes/knowledge-retrieval/types'
import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal' import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal'
import { noop } from 'lodash-es'


type MetadataFilterProps = { type MetadataFilterProps = {
metadataFilterMode?: MetadataFilteringModeEnum metadataFilterMode?: MetadataFilteringModeEnum
provider={metadataModelConfig?.provider || ''} provider={metadataModelConfig?.provider || ''}
completionParams={metadataModelConfig?.completion_params || { temperature: 0.7 }} completionParams={metadataModelConfig?.completion_params || { temperature: 0.7 }}
modelId={metadataModelConfig?.name || ''} modelId={metadataModelConfig?.name || ''}
setModel={handleMetadataModelChange || (() => {})}
onCompletionParamsChange={handleMetadataCompletionParamsChange || (() => {})}
setModel={handleMetadataModelChange || noop}
onCompletionParamsChange={handleMetadataCompletionParamsChange || noop}
hideDebugWithMultipleModel hideDebugWithMultipleModel
debugWithMultipleModel={false} debugWithMultipleModel={false}
/> />

+ 3
- 2
web/app/components/workflow/nodes/start/components/var-item.tsx 查看文件

import { Edit03 } from '@/app/components/base/icons/src/vender/solid/general' import { Edit03 } from '@/app/components/base/icons/src/vender/solid/general'
import Badge from '@/app/components/base/badge' import Badge from '@/app/components/base/badge'
import ConfigVarModal from '@/app/components/app/configuration/config-var/config-modal' import ConfigVarModal from '@/app/components/app/configuration/config-var/config-modal'
import { noop } from 'lodash-es'


type Props = { type Props = {
readonly: boolean readonly: boolean
const VarItem: FC<Props> = ({ const VarItem: FC<Props> = ({
readonly, readonly,
payload, payload,
onChange = () => { },
onRemove = () => { },
onChange = noop,
onRemove = noop,
rightContent, rightContent,
varKeys = [], varKeys = [],
showLegacyBadge = false, showLegacyBadge = false,

+ 2
- 1
web/app/components/workflow/nodes/tool/components/input-var-list.tsx 查看文件

import { VarType } from '@/app/components/workflow/types' import { VarType } from '@/app/components/workflow/types'
import AppSelector from '@/app/components/plugins/plugin-detail-panel/app-selector' import AppSelector from '@/app/components/plugins/plugin-detail-panel/app-selector'
import ModelParameterModal from '@/app/components/plugins/plugin-detail-panel/model-selector' import ModelParameterModal from '@/app/components/plugins/plugin-detail-panel/model-selector'
import { noop } from 'lodash-es'


type Props = { type Props = {
readOnly: boolean readOnly: boolean
schema, schema,
value, value,
onChange, onChange,
onOpen = () => { },
onOpen = noop,
isSupportConstantValue, isSupportConstantValue,
filterVar, filterVar,
}) => { }) => {

+ 2
- 1
web/app/components/workflow/nodes/variable-assigner/components/var-list/index.tsx 查看文件

import VarReferencePicker from '@/app/components/workflow/nodes/_base/components/variable/var-reference-picker' import VarReferencePicker from '@/app/components/workflow/nodes/_base/components/variable/var-reference-picker'
import type { ValueSelector, Var } from '@/app/components/workflow/types' import type { ValueSelector, Var } from '@/app/components/workflow/types'
import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types' import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types'
import { noop } from 'lodash-es'


type Props = { type Props = {
readonly: boolean readonly: boolean
nodeId, nodeId,
list, list,
onChange, onChange,
onOpen = () => { },
onOpen = noop,
filterVar, filterVar,
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()

+ 2
- 1
web/app/components/workflow/panel/debug-and-preview/conversation-variable-modal.tsx 查看文件

import useTimestamp from '@/hooks/use-timestamp' import useTimestamp from '@/hooks/use-timestamp'
import { fetchCurrentValueOfConversationVariable } from '@/service/workflow' import { fetchCurrentValueOfConversationVariable } from '@/service/workflow'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import { noop } from 'lodash-es'


export type Props = { export type Props = {
conversationID: string conversationID: string
return ( return (
<Modal <Modal
isShow isShow
onClose={() => { }}
onClose={noop}
className={cn('h-[640px] w-[920px] max-w-[920px] p-0')} className={cn('h-[640px] w-[920px] max-w-[920px] p-0')}
> >
<div className='absolute right-4 top-4 cursor-pointer p-2' onClick={onHide}> <div className='absolute right-4 top-4 cursor-pointer p-2' onClick={onHide}>

+ 2
- 1
web/app/components/workflow/panel/debug-and-preview/index.tsx 查看文件

import Tooltip from '@/app/components/base/tooltip' import Tooltip from '@/app/components/base/tooltip'
import ActionButton, { ActionButtonState } from '@/app/components/base/action-button' import ActionButton, { ActionButtonState } from '@/app/components/base/action-button'
import { useStore } from '@/app/components/workflow/store' import { useStore } from '@/app/components/workflow/store'
import { noop } from 'lodash-es'


export type ChatWrapperRefType = { export type ChatWrapperRefType = {
handleRestart: () => void handleRestart: () => void
} }
const DebugAndPreview = () => { const DebugAndPreview = () => {
const { t } = useTranslation() const { t } = useTranslation()
const chatRef = useRef({ handleRestart: () => { } })
const chatRef = useRef({ handleRestart: noop })
const { handleCancelDebugAndPreviewPanel } = useWorkflowInteractions() const { handleCancelDebugAndPreviewPanel } = useWorkflowInteractions()
const { handleNodeCancelRunningStatus } = useNodesInteractions() const { handleNodeCancelRunningStatus } = useNodesInteractions()
const { handleEdgeCancelRunningStatus } = useEdgesInteractions() const { handleEdgeCancelRunningStatus } = useEdgesInteractions()

+ 2
- 1
web/app/components/workflow/run/utils/format-log/iteration/index.spec.ts 查看文件

import format from '.' import format from '.'
import graphToLogStruct from '../graph-to-log-struct' import graphToLogStruct from '../graph-to-log-struct'
import { noop } from 'lodash-es'


describe('iteration', () => { describe('iteration', () => {
const list = graphToLogStruct('start -> (iteration, iterationNode, plainNode1 -> plainNode2)') const list = graphToLogStruct('start -> (iteration, iterationNode, plainNode1 -> plainNode2)')
// const [startNode, iterationNode, ...iterations] = list // const [startNode, iterationNode, ...iterations] = list
const result = format(list as any, () => { })
const result = format(list as any, noop)
test('result should have no nodes in iteration node', () => { test('result should have no nodes in iteration node', () => {
expect((result as any).find((item: any) => !!item.execution_metadata?.iteration_id)).toBeUndefined() expect((result as any).find((item: any) => !!item.execution_metadata?.iteration_id)).toBeUndefined()
}) })

+ 2
- 1
web/app/components/workflow/run/utils/format-log/loop/index.spec.ts 查看文件

import format from '.' import format from '.'
import graphToLogStruct from '../graph-to-log-struct' import graphToLogStruct from '../graph-to-log-struct'
import { noop } from 'lodash-es'


describe('loop', () => { describe('loop', () => {
const list = graphToLogStruct('start -> (loop, loopNode, plainNode1 -> plainNode2)') const list = graphToLogStruct('start -> (loop, loopNode, plainNode1 -> plainNode2)')
const [startNode, loopNode, ...loops] = list const [startNode, loopNode, ...loops] = list
const result = format(list as any, () => { })
const result = format(list as any, noop)
test('result should have no nodes in loop node', () => { test('result should have no nodes in loop node', () => {
expect((result as any).find((item: any) => !!item.execution_metadata?.loop_id)).toBeUndefined() expect((result as any).find((item: any) => !!item.execution_metadata?.loop_id)).toBeUndefined()
}) })

+ 2
- 1
web/app/components/workflow/workflow-history-store.tsx 查看文件

import isDeepEqual from 'fast-deep-equal' import isDeepEqual from 'fast-deep-equal'
import type { Edge, Node } from './types' import type { Edge, Node } from './types'
import type { WorkflowHistoryEvent } from './hooks' import type { WorkflowHistoryEvent } from './hooks'
import { noop } from 'lodash-es'


export const WorkflowHistoryStoreContext = createContext<WorkflowHistoryStoreContextType>({ store: null, shortcutsEnabled: true, setShortcutsEnabled: () => {} })
export const WorkflowHistoryStoreContext = createContext<WorkflowHistoryStoreContextType>({ store: null, shortcutsEnabled: true, setShortcutsEnabled: noop })
export const Provider = WorkflowHistoryStoreContext.Provider export const Provider = WorkflowHistoryStoreContext.Provider


export function WorkflowHistoryProvider({ export function WorkflowHistoryProvider({

+ 4
- 3
web/app/education-apply/education-apply-page.tsx 查看文件

import { useToastContext } from '@/app/components/base/toast' import { useToastContext } from '@/app/components/base/toast'
import { EDUCATION_VERIFYING_LOCALSTORAGE_ITEM } from '@/app/education-apply/constants' import { EDUCATION_VERIFYING_LOCALSTORAGE_ITEM } from '@/app/education-apply/constants'
import { getLocaleOnClient } from '@/i18n' import { getLocaleOnClient } from '@/i18n'
import { noop } from 'lodash-es'


const EducationApplyAge = () => { const EducationApplyAge = () => {
const { t } = useTranslation() const { t } = useTranslation()
const { const {
isPending, isPending,
mutateAsync: educationAdd, mutateAsync: educationAdd,
} = useEducationAdd({ onSuccess: () => {} })
} = useEducationAdd({ onSuccess: noop })
const [modalShow, setShowModal] = useState<undefined | { title: string; desc: string; onConfirm?: () => void }>(undefined) const [modalShow, setShowModal] = useState<undefined | { title: string; desc: string; onConfirm?: () => void }>(undefined)
const { onPlanInfoChanged } = useProviderContext() const { onPlanInfoChanged } = useProviderContext()
const updateEducationStatus = useInvalidateEducationStatus() const updateEducationStatus = useInvalidateEducationStatus()
isShow={!!modalShow} isShow={!!modalShow}
title={modalShow?.title || ''} title={modalShow?.title || ''}
content={modalShow?.desc} content={modalShow?.desc}
onConfirm={modalShow?.onConfirm || (() => {})}
onCancel={modalShow?.onConfirm || (() => {})}
onConfirm={modalShow?.onConfirm || noop}
onCancel={modalShow?.onConfirm || noop}
/> />
</div> </div>
) )

+ 2
- 1
web/app/reset-password/page.tsx 查看文件

import Toast from '@/app/components/base/toast' import Toast from '@/app/components/base/toast'
import { sendResetPasswordCode } from '@/service/common' import { sendResetPasswordCode } from '@/service/common'
import I18NContext from '@/context/i18n' import I18NContext from '@/context/i18n'
import { noop } from 'lodash-es'


export default function CheckCode() { export default function CheckCode() {
const { t } = useTranslation() const { t } = useTranslation()
</p> </p>
</div> </div>


<form onSubmit={() => { }}>
<form onSubmit={noop}>
<input type='text' className='hidden' /> <input type='text' className='hidden' />
<div className='mb-2'> <div className='mb-2'>
<label htmlFor="email" className='system-md-semibold my-2 text-text-secondary'>{t('login.email')}</label> <label htmlFor="email" className='system-md-semibold my-2 text-text-secondary'>{t('login.email')}</label>

+ 2
- 1
web/app/signin/components/mail-and-code-auth.tsx 查看文件

import { sendEMailLoginCode } from '@/service/common' import { sendEMailLoginCode } from '@/service/common'
import { COUNT_DOWN_KEY, COUNT_DOWN_TIME_MS } from '@/app/components/signin/countdown' import { COUNT_DOWN_KEY, COUNT_DOWN_TIME_MS } from '@/app/components/signin/countdown'
import I18NContext from '@/context/i18n' import I18NContext from '@/context/i18n'
import { noop } from 'lodash-es'


type MailAndCodeAuthProps = { type MailAndCodeAuthProps = {
isInvite: boolean isInvite: boolean
} }
} }


return (<form onSubmit={() => { }}>
return (<form onSubmit={noop}>
<input type='text' className='hidden' /> <input type='text' className='hidden' />
<div className='mb-2'> <div className='mb-2'>
<label htmlFor="email" className='system-md-semibold my-2 text-text-secondary'>{t('login.email')}</label> <label htmlFor="email" className='system-md-semibold my-2 text-text-secondary'>{t('login.email')}</label>

+ 2
- 1
web/app/signin/components/mail-and-password-auth.tsx 查看文件

import { login } from '@/service/common' import { login } from '@/service/common'
import Input from '@/app/components/base/input' import Input from '@/app/components/base/input'
import I18NContext from '@/context/i18n' import I18NContext from '@/context/i18n'
import { noop } from 'lodash-es'


type MailAndPasswordAuthProps = { type MailAndPasswordAuthProps = {
isInvite: boolean isInvite: boolean
} }
} }


return <form onSubmit={() => { }}>
return <form onSubmit={noop}>
<div className='mb-3'> <div className='mb-3'>
<label htmlFor="email" className="system-md-semibold my-2 text-text-secondary"> <label htmlFor="email" className="system-md-semibold my-2 text-text-secondary">
{t('login.email')} {t('login.email')}

+ 4
- 3
web/context/app-context.tsx 查看文件

import MaintenanceNotice from '@/app/components/header/maintenance-notice' import MaintenanceNotice from '@/app/components/header/maintenance-notice'
import type { SystemFeatures } from '@/types/feature' import type { SystemFeatures } from '@/types/feature'
import { defaultSystemFeatures } from '@/types/feature' import { defaultSystemFeatures } from '@/types/feature'
import { noop } from 'lodash-es'


export type AppContextValue = { export type AppContextValue = {
apps: App[] apps: App[]
const AppContext = createContext<AppContextValue>({ const AppContext = createContext<AppContextValue>({
systemFeatures: defaultSystemFeatures, systemFeatures: defaultSystemFeatures,
apps: [], apps: [],
mutateApps: () => { },
mutateApps: noop,
userProfile: { userProfile: {
id: '', id: '',
name: '', name: '',
isCurrentWorkspaceOwner: false, isCurrentWorkspaceOwner: false,
isCurrentWorkspaceEditor: false, isCurrentWorkspaceEditor: false,
isCurrentWorkspaceDatasetOperator: false, isCurrentWorkspaceDatasetOperator: false,
mutateUserProfile: () => { },
mutateCurrentWorkspace: () => { },
mutateUserProfile: noop,
mutateCurrentWorkspace: noop,
pageContainerRef: createRef(), pageContainerRef: createRef(),
langeniusVersionInfo: initialLangeniusVersionInfo, langeniusVersionInfo: initialLangeniusVersionInfo,
useSelector, useSelector,

+ 2
- 1
web/context/datasets-context.tsx 查看文件



import { createContext, useContext } from 'use-context-selector' import { createContext, useContext } from 'use-context-selector'
import type { DataSet } from '@/models/datasets' import type { DataSet } from '@/models/datasets'
import { noop } from 'lodash-es'


export type DatasetsContextValue = { export type DatasetsContextValue = {
datasets: DataSet[] datasets: DataSet[]


const DatasetsContext = createContext<DatasetsContextValue>({ const DatasetsContext = createContext<DatasetsContextValue>({
datasets: [], datasets: [],
mutateDatasets: () => {},
mutateDatasets: noop,
currentDataset: undefined, currentDataset: undefined,
}) })



+ 29
- 28
web/context/debug-configuration.ts 查看文件

import { ANNOTATION_DEFAULT, DEFAULT_AGENT_SETTING, DEFAULT_CHAT_PROMPT_CONFIG, DEFAULT_COMPLETION_PROMPT_CONFIG } from '@/config' import { ANNOTATION_DEFAULT, DEFAULT_AGENT_SETTING, DEFAULT_CHAT_PROMPT_CONFIG, DEFAULT_COMPLETION_PROMPT_CONFIG } from '@/config'
import type { FormValue } from '@/app/components/header/account-setting/model-provider-page/declarations' import type { FormValue } from '@/app/components/header/account-setting/model-provider-page/declarations'
import type { Collection } from '@/app/components/tools/types' import type { Collection } from '@/app/components/tools/types'
import { noop } from 'lodash-es'


type IDebugConfiguration = { type IDebugConfiguration = {
appId: string appId: string
mode: '', mode: '',
modelModeType: ModelModeType.chat, modelModeType: ModelModeType.chat,
promptMode: PromptMode.simple, promptMode: PromptMode.simple,
setPromptMode: () => { },
setPromptMode: noop,
isAdvancedMode: false, isAdvancedMode: false,
isAgent: false, isAgent: false,
isFunctionCall: false, isFunctionCall: false,
isOpenAI: false, isOpenAI: false,
collectionList: [], collectionList: [],
canReturnToSimpleMode: false, canReturnToSimpleMode: false,
setCanReturnToSimpleMode: () => { },
setCanReturnToSimpleMode: noop,
chatPromptConfig: DEFAULT_CHAT_PROMPT_CONFIG, chatPromptConfig: DEFAULT_CHAT_PROMPT_CONFIG,
completionPromptConfig: DEFAULT_COMPLETION_PROMPT_CONFIG, completionPromptConfig: DEFAULT_COMPLETION_PROMPT_CONFIG,
currentAdvancedPrompt: [], currentAdvancedPrompt: [],
showHistoryModal: () => { },
showHistoryModal: noop,
conversationHistoriesRole: { conversationHistoriesRole: {
user_prefix: 'user', user_prefix: 'user',
assistant_prefix: 'assistant', assistant_prefix: 'assistant',
}, },
setConversationHistoriesRole: () => { },
setCurrentAdvancedPrompt: () => { },
setConversationHistoriesRole: noop,
setCurrentAdvancedPrompt: noop,
hasSetBlockStatus: { hasSetBlockStatus: {
context: false, context: false,
history: false, history: false,
query: false, query: false,
}, },
conversationId: '', conversationId: '',
setConversationId: () => { },
setConversationId: noop,
introduction: '', introduction: '',
setIntroduction: () => { },
setIntroduction: noop,
suggestedQuestions: [], suggestedQuestions: [],
setSuggestedQuestions: () => { },
setSuggestedQuestions: noop,
controlClearChatMessage: 0, controlClearChatMessage: 0,
setControlClearChatMessage: () => { },
setControlClearChatMessage: noop,
prevPromptConfig: { prevPromptConfig: {
prompt_template: '', prompt_template: '',
prompt_variables: [], prompt_variables: [],
}, },
setPrevPromptConfig: () => { },
setPrevPromptConfig: noop,
moreLikeThisConfig: { moreLikeThisConfig: {
enabled: false, enabled: false,
}, },
setMoreLikeThisConfig: () => { },
setMoreLikeThisConfig: noop,
suggestedQuestionsAfterAnswerConfig: { suggestedQuestionsAfterAnswerConfig: {
enabled: false, enabled: false,
}, },
setSuggestedQuestionsAfterAnswerConfig: () => { },
setSuggestedQuestionsAfterAnswerConfig: noop,
speechToTextConfig: { speechToTextConfig: {
enabled: false, enabled: false,
}, },
setSpeechToTextConfig: () => { },
setSpeechToTextConfig: noop,
textToSpeechConfig: { textToSpeechConfig: {
enabled: false, enabled: false,
voice: '', voice: '',
language: '', language: '',
}, },
setTextToSpeechConfig: () => { },
setTextToSpeechConfig: noop,
citationConfig: { citationConfig: {
enabled: false, enabled: false,
}, },
setCitationConfig: () => { },
setCitationConfig: noop,
moderationConfig: { moderationConfig: {
enabled: false, enabled: false,
}, },
embedding_provider_name: '', embedding_provider_name: '',
}, },
}, },
setAnnotationConfig: () => { },
setModerationConfig: () => { },
setAnnotationConfig: noop,
setModerationConfig: noop,
externalDataToolsConfig: [], externalDataToolsConfig: [],
setExternalDataToolsConfig: () => { },
setExternalDataToolsConfig: noop,
formattingChanged: false, formattingChanged: false,
setFormattingChanged: () => { },
setFormattingChanged: noop,
inputs: {}, inputs: {},
setInputs: () => { },
setInputs: noop,
query: '', query: '',
setQuery: () => { },
setQuery: noop,
completionParams: { completionParams: {
max_tokens: 16, max_tokens: 16,
temperature: 1, // 0-2 temperature: 1, // 0-2
presence_penalty: 1, // -2-2 presence_penalty: 1, // -2-2
frequency_penalty: 1, // -2-2 frequency_penalty: 1, // -2-2
}, },
setCompletionParams: () => { },
setCompletionParams: noop,
modelConfig: { modelConfig: {
provider: 'OPENAI', // 'OPENAI' provider: 'OPENAI', // 'OPENAI'
model_id: 'gpt-3.5-turbo', // 'gpt-3.5-turbo' model_id: 'gpt-3.5-turbo', // 'gpt-3.5-turbo'
dataSets: [], dataSets: [],
agentConfig: DEFAULT_AGENT_SETTING, agentConfig: DEFAULT_AGENT_SETTING,
}, },
setModelConfig: () => { },
setModelConfig: noop,
dataSets: [], dataSets: [],
showSelectDataSet: () => { },
setDataSets: () => { },
showSelectDataSet: noop,
setDataSets: noop,
datasetConfigs: { datasetConfigs: {
retrieval_model: RETRIEVE_TYPE.multiWay, retrieval_model: RETRIEVE_TYPE.multiWay,
reranking_model: { reranking_model: {
datasetConfigsRef: { datasetConfigsRef: {
current: null, current: null,
}, },
setDatasetConfigs: () => { },
setDatasetConfigs: noop,
hasSetContextVar: false, hasSetContextVar: false,
isShowVisionConfig: false, isShowVisionConfig: false,
visionConfig: { visionConfig: {
detail: Resolution.low, detail: Resolution.low,
transfer_methods: [TransferMethod.remote_url], transfer_methods: [TransferMethod.remote_url],
}, },
setVisionConfig: () => { },
setVisionConfig: noop,
isAllowVideoUpload: false, isAllowVideoUpload: false,
isShowDocumentConfig: false, isShowDocumentConfig: false,
rerankSettingModalOpen: false, rerankSettingModalOpen: false,
setRerankSettingModalOpen: () => { },
setRerankSettingModalOpen: noop,
}) })


export const useDebugConfigurationContext = () => useContext(DebugConfigurationContext) export const useDebugConfigurationContext = () => useContext(DebugConfigurationContext)

+ 3
- 2
web/context/explore-context.ts 查看文件

import { createContext } from 'use-context-selector' import { createContext } from 'use-context-selector'
import type { InstalledApp } from '@/models/explore' import type { InstalledApp } from '@/models/explore'
import { noop } from 'lodash-es'


type IExplore = { type IExplore = {
controlUpdateInstalledApps: number controlUpdateInstalledApps: number


const ExploreContext = createContext<IExplore>({ const ExploreContext = createContext<IExplore>({
controlUpdateInstalledApps: 0, controlUpdateInstalledApps: 0,
setControlUpdateInstalledApps: () => { },
setControlUpdateInstalledApps: noop,
hasEditPermission: false, hasEditPermission: false,
installedApps: [], installedApps: [],
setInstalledApps: () => { },
setInstalledApps: noop,
}) })


export default ExploreContext export default ExploreContext

+ 13
- 12
web/context/modal-context.tsx 查看文件

import type { UpdatePluginPayload } from '@/app/components/plugins/types' import type { UpdatePluginPayload } from '@/app/components/plugins/types'
import UpdatePlugin from '@/app/components/plugins/update-plugin' import UpdatePlugin from '@/app/components/plugins/update-plugin'
import { removeSpecificQueryParam } from '@/utils' import { removeSpecificQueryParam } from '@/utils'
import { noop } from 'lodash-es'


export type ModalState<T> = { export type ModalState<T> = {
payload: T payload: T
setShowUpdatePluginModal: Dispatch<SetStateAction<ModalState<UpdatePluginPayload> | null>> setShowUpdatePluginModal: Dispatch<SetStateAction<ModalState<UpdatePluginPayload> | null>>
} }
const ModalContext = createContext<ModalContextState>({ const ModalContext = createContext<ModalContextState>({
setShowAccountSettingModal: () => { },
setShowApiBasedExtensionModal: () => { },
setShowModerationSettingModal: () => { },
setShowExternalDataToolModal: () => { },
setShowPricingModal: () => { },
setShowAnnotationFullModal: () => { },
setShowModelModal: () => { },
setShowExternalKnowledgeAPIModal: () => { },
setShowModelLoadBalancingModal: () => { },
setShowModelLoadBalancingEntryModal: () => { },
setShowOpeningModal: () => { },
setShowUpdatePluginModal: () => { },
setShowAccountSettingModal: noop,
setShowApiBasedExtensionModal: noop,
setShowModerationSettingModal: noop,
setShowExternalDataToolModal: noop,
setShowPricingModal: noop,
setShowAnnotationFullModal: noop,
setShowModelModal: noop,
setShowExternalKnowledgeAPIModal: noop,
setShowModelLoadBalancingModal: noop,
setShowModelLoadBalancingEntryModal: noop,
setShowOpeningModal: noop,
setShowUpdatePluginModal: noop,
}) })


export const useModalContext = () => useContext(ModalContext) export const useModalContext = () => useContext(ModalContext)

+ 3
- 2
web/context/provider-context.tsx 查看文件

import { import {
useEducationStatus, useEducationStatus,
} from '@/service/use-education' } from '@/service/use-education'
import { noop } from 'lodash-es'


type ProviderContextState = { type ProviderContextState = {
modelProviders: ModelProvider[] modelProviders: ModelProvider[]
} }
const ProviderContext = createContext<ProviderContextState>({ const ProviderContext = createContext<ProviderContextState>({
modelProviders: [], modelProviders: [],
refreshModelProviders: () => { },
refreshModelProviders: noop,
textGenerationModelList: [], textGenerationModelList: [],
supportRetrievalMethods: [], supportRetrievalMethods: [],
isAPIKeySet: true, isAPIKeySet: true,
}, },
isFetchedPlan: false, isFetchedPlan: false,
enableBilling: false, enableBilling: false,
onPlanInfoChanged: () => { },
onPlanInfoChanged: noop,
enableReplaceWebAppLogo: false, enableReplaceWebAppLogo: false,
modelLoadBalancingEnabled: false, modelLoadBalancingEnabled: false,
datasetOperatorEnabled: false, datasetOperatorEnabled: false,

Loading…
取消
儲存