Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Langgenius Dify Modal Context

From Leeroopedia
Knowledge Sources
Domains Frontend, UI State Management, Modal Management
Last Updated 2026-02-12 07:00 GMT

Overview

A centralized React context provider that manages the lifecycle of all application-level modal dialogs in the Dify frontend.

Description

The ModalContext is a comprehensive modal management system implemented as a React context using the use-context-selector library. It provides a single point of control for showing, hiding, and interacting with over a dozen distinct modal types throughout the Dify application, including account settings, pricing, model configuration, API-based extensions, moderation settings, external data tools, opening statement configuration, plugin updates, education notices, and trigger events limit modals.

The context stores ModalState objects for each modal type, where each state includes a typed payload along with optional callback functions for cancel, save, remove, edit, and validation-before-save operations. This pattern decouples the triggering of modals from their rendering location, allowing any component in the tree to open a modal without importing the modal component directly.

The ModalContextProvider component uses Next.js dynamic imports with ssr: false for all modal components, ensuring they are only loaded client-side when actually needed. Some modal states (account settings, pricing) are synchronized with URL query parameters via nuqs hooks, enabling deep-linking to specific modal views. The provider wires up all open/close/save/cancel handlers and renders the conditionally-visible modal components as siblings of the wrapped children.

Usage

Use useModalContext() or useModalContextSelector() from any component within the provider tree to trigger any application-level modal. This is the preferred mechanism for opening modals that need to be accessible from many different parts of the UI without prop drilling. The provider should be placed high in the component tree, typically wrapping the main application layout.

Code Reference

Source Location

Signature

export type ModalState<T> = {
  payload: T
  onCancelCallback?: () => void
  onSaveCallback?: (newPayload?: T, formValues?: Record<string, any>) => void
  onRemoveCallback?: (newPayload?: T, formValues?: Record<string, any>) => void
  onEditCallback?: (newPayload: T) => void
  onValidateBeforeSaveCallback?: (newPayload: T) => boolean
  isEditMode?: boolean
  datasetBindings?: { id: string, name: string }[]
}

export type ModelModalType = {
  currentProvider: ModelProvider
  currentConfigurationMethod: ConfigurationMethodEnum
  currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields
  isModelCredential?: boolean
  credential?: Credential
  model?: CustomModel
  mode?: ModelModalModeEnum
}

export type ModalContextState = {
  setShowAccountSettingModal: Dispatch<SetStateAction<ModalState<AccountSettingTab> | null>>
  setShowApiBasedExtensionModal: Dispatch<SetStateAction<ModalState<ApiBasedExtension> | null>>
  setShowModerationSettingModal: Dispatch<SetStateAction<ModalState<ModerationConfig> | null>>
  setShowExternalDataToolModal: Dispatch<SetStateAction<ModalState<ExternalDataTool> | null>>
  setShowPricingModal: () => void
  setShowAnnotationFullModal: () => void
  setShowModelModal: Dispatch<SetStateAction<ModalState<ModelModalType> | null>>
  setShowExternalKnowledgeAPIModal: Dispatch<SetStateAction<ModalState<CreateExternalAPIReq> | null>>
  setShowModelLoadBalancingModal: Dispatch<SetStateAction<ModelLoadBalancingModalProps | null>>
  setShowOpeningModal: Dispatch<SetStateAction<ModalState<OpeningStatement & { ... }> | null>>
  setShowUpdatePluginModal: Dispatch<SetStateAction<ModalState<UpdatePluginPayload> | null>>
  setShowEducationExpireNoticeModal: Dispatch<SetStateAction<ModalState<ExpireNoticeModalPayloadProps> | null>>
  setShowTriggerEventsLimitModal: Dispatch<SetStateAction<ModalState<TriggerEventsLimitModalPayload> | null>>
}

export const useModalContext: () => ModalContextState
export const useModalContextSelector: <T,>(selector: (state: ModalContextState) => T) => T
export const ModalContextProvider: FC<{ children: React.ReactNode }>

Import

import { useModalContext, useModalContextSelector, ModalContextProvider } from '@/context/modal-context'

I/O Contract

Inputs

Name Type Required Description
children React.ReactNode Yes Child components that will have access to the modal context

Outputs

Name Type Description
setShowAccountSettingModal null>> Opens or closes the account settings modal with a specific tab
setShowApiBasedExtensionModal null>> Opens or closes the API-based extension configuration modal
setShowModerationSettingModal null>> Opens or closes the moderation setting modal
setShowExternalDataToolModal null>> Opens or closes the external data tool modal
setShowPricingModal () => void Opens the pricing/billing modal
setShowAnnotationFullModal () => void Opens the annotation full modal
setShowModelModal null>> Opens or closes the model configuration modal
setShowExternalKnowledgeAPIModal null>> Opens or closes the external knowledge API modal
setShowModelLoadBalancingModal null>> Opens or closes the model load balancing modal
setShowOpeningModal null>> Opens or closes the conversation opening statement modal
setShowUpdatePluginModal null>> Opens or closes the plugin update modal
setShowEducationExpireNoticeModal null>> Opens or closes the education expiration notice modal
setShowTriggerEventsLimitModal null>> Opens or closes the trigger events limit modal

Usage Examples

Opening the Account Settings Modal

import { useModalContext } from '@/context/modal-context'

function MyComponent() {
  const { setShowAccountSettingModal } = useModalContext()

  const handleOpenSettings = () => {
    setShowAccountSettingModal({
      payload: 'members',
      onCancelCallback: () => console.log('Settings closed'),
    })
  }

  return <button onClick={handleOpenSettings}>Open Settings</button>
}

Opening the Pricing Modal

import { useModalContextSelector } from '@/context/modal-context'

function UpgradeButton() {
  const setShowPricingModal = useModalContextSelector(s => s.setShowPricingModal)

  return <button onClick={setShowPricingModal}>Upgrade Plan</button>
}

Opening the Model Configuration Modal

import { useModalContext } from '@/context/modal-context'

function ModelConfig({ provider, configMethod }) {
  const { setShowModelModal } = useModalContext()

  const handleConfigure = () => {
    setShowModelModal({
      payload: {
        currentProvider: provider,
        currentConfigurationMethod: configMethod,
      },
      onSaveCallback: (payload, formValues) => {
        console.log('Model saved:', payload, formValues)
      },
    })
  }

  return <button onClick={handleConfigure}>Configure Model</button>
}

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment