dify/web/context/modal-context-provider.tsx

337 lines
12 KiB
TypeScript

'use client'
import type { ReactNode } from 'react'
import type { ModalState, ModelModalType } from './modal-context'
import type { OpeningStatement } from '@/app/components/base/features/types'
import type { CreateExternalAPIReq } from '@/app/components/datasets/external-api/declarations'
import type { ModelLoadBalancingModalProps } from '@/app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-modal'
import type { UpdatePluginPayload } from '@/app/components/plugins/types'
import type { InputVar } from '@/app/components/workflow/types'
import type { ExternalDataTool } from '@/models/common'
import type { ModerationConfig, PromptVariable } from '@/models/debug'
import { useAtomValue } from 'jotai'
import { useCallback, useState } from 'react'
import { useProviderContext } from '@/context/provider-context'
import { currentWorkspaceIdAtom } from '@/context/workspace-state'
import { usePricingModal } from '@/hooks/use-query-params'
import dynamic from '@/next/dynamic'
import { useTriggerEventsLimitModal } from './hooks/use-trigger-events-limit-modal'
import { ModalContext } from './modal-context'
const ModerationSettingModal = dynamic(
() =>
import('@/app/components/base/features/new-feature-panel/moderation/moderation-setting-modal'),
{
ssr: false,
},
)
const ExternalDataToolModal = dynamic(
() => import('@/app/components/app/configuration/tools/external-data-tool-modal'),
{
ssr: false,
},
)
const Pricing = dynamic(() => import('@/app/components/billing/pricing'), {
ssr: false,
})
const AnnotationFullModal = dynamic(
() => import('@/app/components/billing/annotation-full/modal'),
{
ssr: false,
},
)
const ModelModal = dynamic(
() => import('@/app/components/header/account-setting/model-provider-page/model-modal'),
{
ssr: false,
},
)
const ExternalAPIModal = dynamic(
() => import('@/app/components/datasets/external-api/external-api-modal'),
{
ssr: false,
},
)
const ModelLoadBalancingModal = dynamic(
() =>
import('@/app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-modal'),
{
ssr: false,
},
)
const OpeningSettingModal = dynamic(
() => import('@/app/components/base/features/new-feature-panel/conversation-opener/modal'),
{
ssr: false,
},
)
const UpdatePlugin = dynamic(() => import('@/app/components/plugins/update-plugin'), {
ssr: false,
})
const TriggerEventsLimitModal = dynamic(
() => import('@/app/components/billing/trigger-events-limit-modal'),
{
ssr: false,
},
)
type ModalContextProviderProps = {
children: ReactNode
}
export const ModalContextProvider = ({ children }: ModalContextProviderProps) => {
const [showPricingModal, setPricingModalOpen] = usePricingModal()
const [showModerationSettingModal, setShowModerationSettingModal] =
useState<ModalState<ModerationConfig> | null>(null)
const [showExternalDataToolModal, setShowExternalDataToolModal] =
useState<ModalState<ExternalDataTool> | null>(null)
const [showModelModal, setShowModelModal] = useState<ModalState<ModelModalType> | null>(null)
const [showExternalKnowledgeAPIModal, setShowExternalKnowledgeAPIModal] =
useState<ModalState<CreateExternalAPIReq> | null>(null)
const [showModelLoadBalancingModal, setShowModelLoadBalancingModal] =
useState<ModelLoadBalancingModalProps | null>(null)
const [showOpeningModal, setShowOpeningModal] = useState<ModalState<
OpeningStatement & {
promptVariables?: PromptVariable[]
workflowVariables?: InputVar[]
onAutoAddPromptVariable?: (variable: PromptVariable[]) => void
}
> | null>(null)
const [showUpdatePluginModal, setShowUpdatePluginModal] =
useState<ModalState<UpdatePluginPayload> | null>(null)
const currentWorkspaceId = useAtomValue(currentWorkspaceIdAtom)
const [showAnnotationFullModal, setShowAnnotationFullModal] = useState(false)
const { plan, isFetchedPlan } = useProviderContext()
const {
showTriggerEventsLimitModal,
setShowTriggerEventsLimitModal,
persistTriggerEventsLimitModalDismiss,
} = useTriggerEventsLimitModal({
plan,
isFetchedPlan,
currentWorkspaceId,
})
const handleCancelModerationSettingModal = () => {
setShowModerationSettingModal(null)
if (showModerationSettingModal?.onCancelCallback) showModerationSettingModal.onCancelCallback()
}
const handleCancelExternalDataToolModal = () => {
setShowExternalDataToolModal(null)
if (showExternalDataToolModal?.onCancelCallback) showExternalDataToolModal.onCancelCallback()
}
const handleCancelModelModal = useCallback(() => {
setShowModelModal(null)
if (showModelModal?.onCancelCallback) showModelModal.onCancelCallback()
}, [showModelModal])
const handleSaveModelModal = useCallback(
(formValues?: Record<string, unknown>) => {
if (showModelModal?.onSaveCallback)
showModelModal.onSaveCallback(showModelModal.payload, formValues)
setShowModelModal(null)
},
[showModelModal],
)
const handleRemoveModelModal = useCallback(
(formValues?: Record<string, unknown>) => {
if (showModelModal?.onRemoveCallback)
showModelModal.onRemoveCallback(showModelModal.payload, formValues)
setShowModelModal(null)
},
[showModelModal],
)
const handleCancelExternalApiModal = useCallback(() => {
setShowExternalKnowledgeAPIModal(null)
if (showExternalKnowledgeAPIModal?.onCancelCallback)
showExternalKnowledgeAPIModal.onCancelCallback()
}, [showExternalKnowledgeAPIModal])
const handleSaveExternalApiModal = useCallback(
async (updatedFormValue: CreateExternalAPIReq) => {
if (showExternalKnowledgeAPIModal?.onSaveCallback)
showExternalKnowledgeAPIModal.onSaveCallback(updatedFormValue)
setShowExternalKnowledgeAPIModal(null)
},
[showExternalKnowledgeAPIModal],
)
const handleEditExternalApiModal = useCallback(
async (updatedFormValue: CreateExternalAPIReq) => {
if (showExternalKnowledgeAPIModal?.onEditCallback)
showExternalKnowledgeAPIModal.onEditCallback(updatedFormValue)
setShowExternalKnowledgeAPIModal(null)
},
[showExternalKnowledgeAPIModal],
)
const handleCancelOpeningModal = useCallback(() => {
setShowOpeningModal(null)
if (showOpeningModal?.onCancelCallback) showOpeningModal.onCancelCallback()
}, [showOpeningModal])
const handleSaveModeration = (newModerationConfig: ModerationConfig) => {
if (showModerationSettingModal?.onSaveCallback)
showModerationSettingModal.onSaveCallback(newModerationConfig)
setShowModerationSettingModal(null)
}
const handleSaveExternalDataTool = (newExternalDataTool: ExternalDataTool) => {
if (showExternalDataToolModal?.onSaveCallback)
showExternalDataToolModal.onSaveCallback(newExternalDataTool)
setShowExternalDataToolModal(null)
}
const handleValidateBeforeSaveExternalDataTool = (newExternalDataTool: ExternalDataTool) => {
if (showExternalDataToolModal?.onValidateBeforeSaveCallback)
return showExternalDataToolModal?.onValidateBeforeSaveCallback(newExternalDataTool)
return true
}
const handleSaveOpeningModal = (newOpening: OpeningStatement) => {
if (showOpeningModal?.onSaveCallback) showOpeningModal.onSaveCallback(newOpening)
setShowOpeningModal(null)
}
const handleShowPricingModal = useCallback(() => {
setPricingModalOpen(true)
}, [setPricingModalOpen])
const handleCancelPricingModal = useCallback(() => {
setPricingModalOpen(false)
}, [setPricingModalOpen])
const hasBlockingModalOpen = Boolean(
showModerationSettingModal ||
showExternalDataToolModal ||
showPricingModal ||
showAnnotationFullModal ||
showModelModal ||
showExternalKnowledgeAPIModal ||
showModelLoadBalancingModal ||
showOpeningModal ||
showUpdatePluginModal ||
showTriggerEventsLimitModal,
)
return (
<ModalContext.Provider
value={{
hasBlockingModalOpen,
setShowModerationSettingModal,
setShowExternalDataToolModal,
setShowPricingModal: handleShowPricingModal,
setShowAnnotationFullModal: () => setShowAnnotationFullModal(true),
setShowModelModal,
setShowExternalKnowledgeAPIModal,
setShowModelLoadBalancingModal,
setShowOpeningModal,
setShowUpdatePluginModal,
setShowTriggerEventsLimitModal,
}}
>
<>
{children}
{!!showModerationSettingModal && (
<ModerationSettingModal
data={showModerationSettingModal.payload}
onCancel={handleCancelModerationSettingModal}
onSave={handleSaveModeration}
/>
)}
{!!showExternalDataToolModal && (
<ExternalDataToolModal
data={showExternalDataToolModal.payload}
onCancel={handleCancelExternalDataToolModal}
onSave={handleSaveExternalDataTool}
onValidateBeforeSave={handleValidateBeforeSaveExternalDataTool}
/>
)}
{!!showPricingModal && <Pricing onCancel={handleCancelPricingModal} />}
{showAnnotationFullModal && (
<AnnotationFullModal
show={showAnnotationFullModal}
onHide={() => setShowAnnotationFullModal(false)}
/>
)}
{!!showModelModal && (
<ModelModal
provider={showModelModal.payload.currentProvider}
configurateMethod={showModelModal.payload.currentConfigurationMethod}
currentCustomConfigurationModelFixedFields={
showModelModal.payload.currentCustomConfigurationModelFixedFields
}
isModelCredential={showModelModal.payload.isModelCredential}
credential={showModelModal.payload.credential}
model={showModelModal.payload.model}
mode={showModelModal.payload.mode}
onCancel={handleCancelModelModal}
onSave={handleSaveModelModal}
onRemove={handleRemoveModelModal}
/>
)}
{!!showExternalKnowledgeAPIModal && (
<ExternalAPIModal
data={showExternalKnowledgeAPIModal.payload}
datasetBindings={showExternalKnowledgeAPIModal.datasetBindings ?? []}
onSave={handleSaveExternalApiModal}
onCancel={handleCancelExternalApiModal}
onEdit={handleEditExternalApiModal}
isEditMode={showExternalKnowledgeAPIModal.isEditMode ?? false}
/>
)}
{Boolean(showModelLoadBalancingModal) && (
<ModelLoadBalancingModal {...showModelLoadBalancingModal!} />
)}
{showOpeningModal && (
<OpeningSettingModal
data={showOpeningModal.payload}
onSave={handleSaveOpeningModal}
onCancel={handleCancelOpeningModal}
promptVariables={showOpeningModal.payload.promptVariables}
workflowVariables={showOpeningModal.payload.workflowVariables}
onAutoAddPromptVariable={showOpeningModal.payload.onAutoAddPromptVariable}
/>
)}
{!!showUpdatePluginModal && (
<UpdatePlugin
{...showUpdatePluginModal.payload}
onCancel={() => {
setShowUpdatePluginModal(null)
showUpdatePluginModal.onCancelCallback?.()
}}
onSave={() => {
setShowUpdatePluginModal(null)
showUpdatePluginModal.onSaveCallback?.()
}}
/>
)}
{!!showTriggerEventsLimitModal && (
<TriggerEventsLimitModal
show
usage={showTriggerEventsLimitModal.payload.usage}
total={showTriggerEventsLimitModal.payload.total}
resetInDays={showTriggerEventsLimitModal.payload.resetInDays}
onClose={() => {
persistTriggerEventsLimitModalDismiss()
setShowTriggerEventsLimitModal(null)
}}
onUpgrade={() => {
persistTriggerEventsLimitModalDismiss()
setShowTriggerEventsLimitModal(null)
handleShowPricingModal()
}}
/>
)}
</>
</ModalContext.Provider>
)
}