Skip to content

Studio UI: Need official extension point to add custom fields to Workflow Transition modal (no component to override) #2721

@Chauhan-Mukesh

Description

@Chauhan-Mukesh

Problem statement

I need to add custom Select fields (reviewers, dependent references) into the Workflow Transition modal when an object transition happens. This was possible in Pimcore Admin (ExtJS) via panel overrides. In Studio UI, I can’t find a documented component/slot/processor to extend the workflow modal form, and attempts to override a modal component fail because no workflow modal is registered in the ComponentRegistry.


Environment

  • Pimcore Platform version: 2025.4
  • Studio UI bundle: vendor/pimcore/studio-ui-bundle (current)

What I want to do

  • Inject extra form fields (multi-select reviewers and reference objects) into the Workflow Transition modal.
  • Validate and submit those values alongside workflow notes.
  • Do this using official Studio UI extension points to avoid console errors and DOM hacking.

What I tried

  1. ComponentRegistry override approach
    • Assumed a workflow modal component exists (“element.editor.workflow.modal”), similar to other registered components.
      Attempted override via container + serviceIds.
    • Attempted override via container + serviceIds.
import { type IAbstractPlugin, type AbstractModule, container } from '@pimcore/studio-ui-bundle'
import { serviceIds } from '@pimcore/studio-ui-bundle/app'
import type { ComponentRegistry } from '@pimcore/studio-ui-bundle/modules/app'
import { EnhancedWorkflowModal } from './components/enhanced-workflow-modal'
import { WorkflowDebugger } from '../utils/debug'

const WorkflowTransitionExtensionModule: AbstractModule = {
  onInit (): void {
    try {
      WorkflowDebugger.log('WorkflowTransitionExtension', 'Initializing module...')
      const componentRegistry = container.get<ComponentRegistry>(
        serviceIds['App/ComponentRegistry/ComponentRegistry']
      )
      if (!componentRegistry) {
        WorkflowDebugger.error('WorkflowTransitionExtension', 'Component registry not found')
        return
      }

      // Attempt override (fails: component does not exist)
      try {
        componentRegistry.override({
          name: 'element.editor.workflow.modal',
          component: EnhancedWorkflowModal
        })
      } catch (overrideError) {
        WorkflowDebugger.warn('WorkflowTransitionExtension', 'Could not override workflow modal', overrideError)
      }
    } catch (error) {
      WorkflowDebugger.error('WorkflowTransitionExtension', 'Initialization error', error)
    }
  }
}

export const WorkflowTransitionExtensionPlugin: IAbstractPlugin = {
  name: 'WorkflowTransitionExtensionPlugin',
  priority: 100,
  onStartup ({ moduleSystem }): void {
    WorkflowDebugger.log('WorkflowTransitionExtensionPlugin', 'Starting up...')
    moduleSystem.registerModule(WorkflowTransitionExtensionModule)
    WorkflowDebugger.log('WorkflowTransitionExtensionPlugin', 'Module registered')
  }
}

Observed logs/errors:

  • No component named "element.editor.workflow.modal" found to override
  • ErrorModalService: Modal instance is not set. Call setModalInstance first.
  • ComponentRegistry configs list element.editor.tab.workflow, but no workflow modal entry.
  1. Processor Registry pattern

    • Looked at abstract-processor-registry and hook-processor-registry types.
    • Couldn’t find a documented workflow form processor registry to inject fields.
  2. DOM MutationObserver workaround

    • As a fallback, observed AntD modal creation and injected custom fields (select) before notes.
    • Captured values and appended hidden inputs before submit.
import { WorkflowDebugger } from '../../utils/debug'
import { ReviewerService } from '../services/reviewer-service'
import { type ReviewerUser, type ReferenceObject, type WorkflowFieldValues } from '../types'

export class WorkflowModalEnhancer {
  private observer: MutationObserver | null = null
  private processedModals = new Set<Element>()
  private reviewers: ReviewerUser[] = []
  private customFieldValues: WorkflowFieldValues = {}

  initialize (): void {
    this.loadReviewers().catch(() => {})
    this.observer = new MutationObserver((mutations) => {
      mutations.forEach((m) => m.addedNodes.forEach((n) => {
        if (n instanceof HTMLElement) this.checkForWorkflowModal(n)
      }))
    })
    this.observer.observe(document.body, { childList: true, subtree: true })
  }

  // ... detect modal, inject selects, hook submit, etc.
}
  1. Hooking workflow APIs
    • Explored hooks like useWorkflow, useSubmitWorkflow, useElementDraft/useElementContext for context, but without an exposed modal component or slots, couldn’t integrate a React-based custom form.

Sample service/hook used

export class ReviewerService {
  static async getReviewerUsers (): Promise<ReviewerUser[]> {
    const res = await fetch('/getReviewerUsersList', { method: 'GET', credentials: 'same-origin' })
    if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`)
    const data = await res.json()
    return Array.isArray(data.reviewers) ? data.reviewers : []
  }

  static async fetchRequiredByReferences (objectKey: string, objectId: number) {
    const res = await fetch('/getRequiredByReferences', {
      method: 'POST', credentials: 'same-origin',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ objectKey, objectId })
    })
    if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`)
    const data = await res.json()
    return {
      requiredByObjects: Array.isArray(data.requiredByObjects) ? data.requiredByObjects : [],
      preSelected: Array.isArray(data.preSelected) ? data.preSelected : [],
      hasData: Boolean(data.hasData)
    }
  }
}

Questions/requests

  • Is there an official extension point (component name, slot, registry) to add custom fields into the Workflow Transition modal in Studio UI?
  • If yes, what is the ComponentRegistry name to override or the slot to register into?
  • If not, can you provide guidance or add a feature:
    • A dedicated component registry entry for the workflow modal (e.g., element.editor.workflow.modal)
    • A slot or processor registry for workflow form fields
    • A documented way to pass additional form values through submitWorkflowAction
  • Or any other example that says how I can extend core components and add other UI elements to it wherever I want to add

Here is current feature Screenshot that I implemented in ExtJS:

image

Here, in current UI I've added two select boxes on notes modal, which is commonly used to add comments while workflow state change.

Thanks in advance for clarifying the supported extension mechanism for workflow transition modals in Studio UI.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions