Custom controls overview

OpenModalForm row actions and feature-specific modals

Custom controls are React forms opened when a row action uses action_type: "custom_control" and the API returns onSuccess: "OpenModalForm".

There is no dynamic registry — each form is a component in ./ApiTables/table-modals/custom-controls/, wired manually in ./ApiTables/table-modals/ApiTablesModals.tsx by URL substring match.

Flow

Prefetch POST loads form defaults (fields, options) into customControlAction before the popup renders.

State field

rowActions.customControlAction — cleared by handleCloseModal_getCustomControlRequest(null).

<Popup isVisible={!!customControlAction} containerClass="lg:min-w-4xl">
  {/* URL includes checks */}
</Popup>

First matching includes() wins — order matters if URLs overlap.

Typical control component props

interface Props {
  action: CustomControlAction; // server payload + metadata
  closeModal: () => void;
  rowRefetch?: (row: Row) => void; // optional local row patch
}

Read form data from action.payload or legacy action_payload. Submit via useUtilsProvider() handlers.

Structure can pass customElement: "withdrawal_requests" (string) into tableCore:

  • Not a modal — injects CalculateWithdrawalAmount in ./ApiTables/core/TableBody.tsx via ./ApiTables/core/TableCustomElements.tsx
  • React node customElement prop renders above table in ./ApiTables/ApiTablesComponent.tsx

Unwired files

Several components exist under ./ApiTables/table-modals/custom-controls/ but are not imported in ./ApiTables/table-modals/ApiTablesModals.tsx (e.g. EditUser, EditPendingOrder, LinkSlotToProduct). See Wired controls.

On this page