Skip to content

feat(routing-forms): unify booking questions UI with event-types#28505

Closed
victorjzq wants to merge 1 commit intocalcom:mainfrom
victorjzq:fix/issue-18987
Closed

feat(routing-forms): unify booking questions UI with event-types#28505
victorjzq wants to merge 1 commit intocalcom:mainfrom
victorjzq:fix/issue-18987

Conversation

@victorjzq
Copy link

Summary

Closes #18987

This PR unifies the routing forms field editor with the event-types booking questions UI, implementing PeerRich's explicit requirement that the systems should not be maintained individually.

Changes

  • Single source of truth for field types: FieldTypes in packages/app-store/routing-forms/lib/FieldTypes.ts is now derived from fieldTypesConfigMap (same source event-types uses). Adding a new input type to event-types automatically makes it available in routing forms.

  • Dialog-based field editor: Replaced the inline card editor in FormEdit.tsx with a dialog-based UI that mirrors the event-types FormBuilder. Fields are now shown as a list with edit/delete/reorder actions.

  • Identifier asked FIRST, not prefilled: In the new dialog, the identifier field is shown first and starts empty (no auto-fill from label), matching event-types behavior.

  • New field types in RAQB: Added widget and type definitions for all newly available field types (address, url, multiemail, boolean, checkbox, radio) in the react-awesome-query-builder config.

  • Options support extended: isOptionsField and listValues now handle checkbox and radio types in addition to select and multiselect.

Before / After

Before: Routing forms had 7 hardcoded field types; inline card editor; identifier auto-filled from label.

After: Routing forms share all non-system field types with event-types; dialog editor matching event-types FormBuilder; identifier is shown first with no prefill.

Test plan

  • Create a new routing form and click "Add question" — dialog opens with identifier field first (empty)
  • Add a question of each new type (address, url, phone, email, etc.) — all should appear in the dropdown
  • Add a select/multiselect/checkbox/radio question — options input should appear in the dialog
  • Edit an existing field — dialog opens pre-populated with existing values
  • Reorder fields with arrow buttons
  • Delete a field
  • Verify routing conditions (RAQB) work for all new field types
  • Verify that adding a new type to fieldTypesConfigMap with systemOnly: false automatically makes it available in routing forms

- Derive FieldTypes from fieldTypesConfigMap so routing forms and
  event-types share a single source of truth for input types
- Add RAQB widget/type support for new field types (address, url,
  multiemail, boolean, checkbox, radio)
- Replace inline card-based field editor in FormEdit with a
  dialog-based UI matching the event-types FormBuilder
- Show identifier field FIRST in the dialog with no prefill, matching
  event-types behavior
- Extend isOptionsField and listValues to handle checkbox and radio types

Closes calcom#18987
@github-actions github-actions bot added $50 event-types area: event types, event-types routing-forms area: routing forms, routing, forms ✨ feature New feature or request 💎 Bounty A bounty on Algora.io 🧹 Improvements Improvements to existing features. Mostly UX/UI labels Mar 19, 2026
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 6 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/app-store/routing-forms/lib/formSubmissionUtils.ts">

<violation number="1" location="packages/app-store/routing-forms/lib/formSubmissionUtils.ts:46">
P1: Newly included checkbox/radio option fields can hit an unguarded `.toString()` on nullish response values, causing a runtime TypeError during form submission processing.</violation>
</file>

<file name="packages/app-store/routing-forms/components/react-awesome-query-builder/config/config.ts">

<violation number="1" location="packages/app-store/routing-forms/components/react-awesome-query-builder/config/config.ts:27">
P2: Boolean fields are configured as text type/widget, enabling string operators and unconstrained values for a boolean question.</violation>
</file>

<file name="apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/FormEdit.tsx">

<violation number="1" location="apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/FormEdit.tsx:333">
P2: Router fields lost move up/down controls due to `!isRouterField` gating, causing a reorder regression (especially between router fields).</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.


function isOptionsField(field: Pick<SerializableField, "type" | "options">) {
return (field.type === "select" || field.type === "multiselect") && field.options;
return (field.type === "select" || field.type === "multiselect" || field.type === "checkbox" || field.type === "radio") && field.options;
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Newly included checkbox/radio option fields can hit an unguarded .toString() on nullish response values, causing a runtime TypeError during form submission processing.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/app-store/routing-forms/lib/formSubmissionUtils.ts, line 46:

<comment>Newly included checkbox/radio option fields can hit an unguarded `.toString()` on nullish response values, causing a runtime TypeError during form submission processing.</comment>

<file context>
@@ -43,7 +43,7 @@ export type FORM_SUBMITTED_WEBHOOK_RESPONSES = Record<
 
 function isOptionsField(field: Pick<SerializableField, "type" | "options">) {
-  return (field.type === "select" || field.type === "multiselect") && field.options;
+  return (field.type === "select" || field.type === "multiselect" || field.type === "checkbox" || field.type === "radio") && field.options;
 }
 
</file context>
Fix with Cubic

multiemail: {
...BasicConfig.widgets.text,
},
boolean: {
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Boolean fields are configured as text type/widget, enabling string operators and unconstrained values for a boolean question.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/app-store/routing-forms/components/react-awesome-query-builder/config/config.ts, line 27:

<comment>Boolean fields are configured as text type/widget, enabling string operators and unconstrained values for a boolean question.</comment>

<file context>
@@ -15,6 +15,24 @@ function getWidgetsWithoutFactory(_configFor: ConfigFor) {
+    multiemail: {
+      ...BasicConfig.widgets.text,
+    },
+    boolean: {
+      ...BasicConfig.widgets.text,
+    },
</file context>
Fix with Cubic

key={typedField.id}
data-testid="field"
className="hover:bg-cal-muted group relative flex items-center justify-between p-4 transition">
{!isRouterField && (
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Router fields lost move up/down controls due to !isRouterField gating, causing a reorder regression (especially between router fields).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/FormEdit.tsx, line 333:

<comment>Router fields lost move up/down controls due to `!isRouterField` gating, causing a reorder regression (especially between router fields).</comment>

<file context>
@@ -258,119 +225,209 @@ const FormEdit = ({
+                  key={typedField.id}
+                  data-testid="field"
+                  className="hover:bg-cal-muted group relative flex items-center justify-between p-4 transition">
+                  {!isRouterField && (
+                    <>
+                      {index >= 1 && (
</file context>
Fix with Cubic

Copy link
Member

@romitg2 romitg2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you for your work, going with this #28145

also side note, we prefer contributions following our pr description guidelines. please attach video demo if it involves visual changes.

@romitg2 romitg2 closed this Mar 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💎 Bounty A bounty on Algora.io event-types area: event types, event-types ✨ feature New feature or request 🧹 Improvements Improvements to existing features. Mostly UX/UI routing-forms area: routing forms, routing, forms size/XL $50

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CAL-5097] add the same "booking questions" to routing forms

2 participants