Skip to content

Comments

fix(workflows): resolve text overflow issue in workflow rename header#24322

Closed
lukmaann wants to merge 1 commit intocalcom:mainfrom
lukmaann:fix/workflows-mobile-responsive
Closed

fix(workflows): resolve text overflow issue in workflow rename header#24322
lukmaann wants to merge 1 commit intocalcom:mainfrom
lukmaann:fix/workflows-mobile-responsive

Conversation

@lukmaann
Copy link

@lukmaann lukmaann commented Oct 7, 2025

What does this PR do?

This PR fixes the text overflow issue in the workflow rename header on mobile devices.
When users renamed workflows with long titles, the header layout broke and caused overflow issues, making it hard to use on small screens.

This update ensures:


Visual Demo

Video Demo (Before and After):

Before:

bug-24257-before.mp4

After:

bug-24257-after.mp4

The before video shows how the workflow rename header overflowed on mobile when long names were entered.
The after video demonstrates the fixed behavior — titles now wrap correctly, and the layout remains intact and responsive.


Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. (N/A)
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  1. Navigate to /workflows on a mobile device or in browser DevTools (e.g., iPhone 14 view).
  2. Try renaming a workflow with a very long name.
  3. Verify that:
    • The header layout no longer overflows horizontally.
    • Long names wrap to multiple lines gracefully.
    • Buttons and form controls remain accessible and properly aligned.
  4. Confirm that other workflow form elements (inputs, buttons) maintain proper spacing and touch targets.

Checklist

  • I haven't read the contributing guide
  • My code doesn't follow the style guidelines of this project
  • I haven't commented my code, particularly in hard-to-understand areas
  • I haven't checked if my changes generate no new warnings

@vercel
Copy link

vercel bot commented Oct 7, 2025

@lukmaann is attempting to deploy a commit to the cal Team on Vercel.

A member of the Team first needs to authorize it.

@graphite-app graphite-app bot requested a review from a team October 7, 2025 10:35
@graphite-app graphite-app bot added the community Created by Linear-GitHub Sync label Oct 7, 2025
@CLAassistant
Copy link

CLAassistant commented Oct 7, 2025

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 7, 2025

Walkthrough

This PR refactors the workflows page (packages/features/ee/workflows/pages/workflow.tsx): consolidates TRPC query enabled flags; simplifies permission evaluation and read-only mode via readonlyWorkflow; unifies name editing handlers and submission; streamlines scroll-related effect; refactors form data setup, including isMixedEventType and activeOn calculations; compacts translation of reminderBody/emailSubject and step mappings; normalizes verification checks and error setting; centralizes validation error composition; routes saves through a single validate-and-submit path; and updates UI markup/classes for the header, name display (with Tooltip), badges, buttons, and DeleteDialog navigation.

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning This PR implements the header text overflow fix described in issue #24257 but does not address the broader mobile-responsiveness fixes originally called out in linked issues #24256 and CAL-6516, so it only partially fulfills the linked objectives. Please extend this PR or create follow-up work to cover the additional mobile layout issues referenced in #24256 and CAL-6516 or clarify that only the header overflow was in scope.
Out of Scope Changes Check ⚠️ Warning The changes include extensive refactoring of TRPC queries, permission helpers, form initialization, validation, translation logic, and scrolling effects that are unrelated to the stated goal of fixing text overflow in the workflow rename header. Consider isolating the UI fix into a focused PR and moving the broader logic refactors into separate changes to maintain clear scope and easier review.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly and accurately describes the primary change of this PR by explicitly stating the fix to the text overflow issue in the workflow rename header, and it follows conventional prefix and formatting without extraneous detail.
Description Check ✅ Passed The description clearly outlines the purpose of the PR, details the issue being fixed, summarizes visual demos, lists testing steps, and references the relevant issue numbers, demonstrating direct relevance to the changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • CAL-24257: Entity not found: Issue - Could not find referenced Issue.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@dosubot dosubot bot added workflows area: workflows, automations 🧹 Improvements Improvements to existing features. Mostly UX/UI labels Oct 7, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/features/ee/workflows/pages/workflow.tsx (1)

259-290: Indexing validation errors by stepNumber risks misalignment; use array index

Using step.stepNumber - 1 can set errors on the wrong item if ordering drifts. Index by iteration index.

Apply:

-    values.steps.forEach((step) => {
+    values.steps.forEach((step, index) => {
       const stripped = step.reminderBody?.replace(/<[^>]+>/g, "") || "";
       const isBodyEmpty =
         !isSMSOrWhatsappAction(step.action) && !isCalAIAction(step.action) && stripped.length <= 1;

       if (isBodyEmpty) {
-        form.setError(`steps.${step.stepNumber - 1}.reminderBody`, {
+        form.setError(`steps.${index}.reminderBody`, {
           type: "custom",
           message: t("fill_this_field"),
         });
       }
@@
-      if (
+      if (
         (step.action === WorkflowActions.SMS_NUMBER || step.action === WorkflowActions.WHATSAPP_NUMBER) &&
         !verifiedNumbers?.find((v) => v.phoneNumber === step.sendTo)
       ) {
         isVerified = false;
-        form.setError(`steps.${step.stepNumber - 1}.sendTo`, { type: "custom", message: t("not_verified") });
+        form.setError(`steps.${index}.sendTo`, { type: "custom", message: t("not_verified") });
       }
@@
-      if (step.action === WorkflowActions.EMAIL_ADDRESS && !verifiedEmails?.find((v) => v === step.sendTo)) {
+      if (step.action === WorkflowActions.EMAIL_ADDRESS && !verifiedEmails?.find((v) => v === step.sendTo)) {
         isVerified = false;
-        form.setError(`steps.${step.stepNumber - 1}.sendTo`, { type: "custom", message: t("not_verified") });
+        form.setError(`steps.${index}.sendTo`, { type: "custom", message: t("not_verified") });
       }
     });

Additionally, consider avoiding in‑place mutation of values.steps when translating variables; clone and use a normalized payload to keep RHF state intact:

const payloadSteps = values.steps.map((s) => ({
  ...s,
  reminderBody: s.reminderBody
    ? translateVariablesToEnglish(s.reminderBody, { locale: i18n.language, t })
    : s.reminderBody,
  emailSubject: s.emailSubject
    ? translateVariablesToEnglish(s.emailSubject, { locale: i18n.language, t })
    : s.emailSubject,
}));

…and pass steps: payloadSteps to the mutation.

🧹 Nitpick comments (6)
packages/features/ee/workflows/pages/workflow.tsx (6)

247-251: Localize error toast message

Direct string interpolation violates i18n guidance for .tsx; prefer t().

-      if (err instanceof HttpError) {
-        showToast(`${err.statusCode}: ${err.message}`, "error");
-      }
+      if (err instanceof HttpError) {
+        // Consider logging `err` for diagnostics, but show a localized toast
+        showToast(t("something_went_wrong"), "error");
+      }

As per coding guidelines


311-315: Avoid throwing on client validation; surface a toast and return

Throwing here can cause unhandled promise rejections depending on the Form wrapper. Prefer a toast + early return.

-      throw new Error(`${t("workflow_validation_failed")}: ${errs.join("; ")}`);
+      showToast(`${t("workflow_validation_failed")}: ${errs.join("; ")}`, "error");
+      return;

154-156: Limit smooth scroll to transition (pending → settled) to avoid jank

Prevent repeated scrolls; respect reduced motion if needed.

-  useEffect(() => {
-    requestAnimationFrame(() => window.scrollTo({ top: 0, behavior: "smooth" }));
-  }, [isPending]);
+  useEffect(() => {
+    if (prevIsPending.current && !isPending) {
+      requestAnimationFrame(() => window.scrollTo({ top: 0, behavior: "smooth" }));
+    }
+    prevIsPending.current = isPending;
+  }, [isPending]);

Add once, outside:

// at top
import { useRef } from "react";
// near other state
const prevIsPending = useRef(isPending);

349-357: RHF integration: don’t override register’s onChange without forwarding

Overriding onChange prevents RHF from tracking dirtiness/touched during editing.

const nameField = form.register("name");

<Input
  {...nameField}
  data-testid="workflow-name"
  onChange={(e) => {
    setNameValue(e.target.value);
    nameField.onChange(e);
  }}
  onKeyDown={handleNameKeyDown}
  onBlur={handleNameSubmit}
  className="text-default focus:shadow-outline-gray-focused h-auto w-full whitespace-nowrap border-none p-1 text-sm font-semibold leading-none focus:ring-0"
  autoFocus
/>

Alternatively, use Controller.


455-457: Prefer client-side navigation over full reload

Use Next.js router to navigate after delete.

// at top: import { useRouter } from "next/navigation";
const router = useRouter();
// ...
additionalFunction={async () => {
  router.push("/workflows");
}}

359-366: Allow wrapping on mobile and truncation on larger screens
Switch the span’s classes to enable wrapping on small screens and truncate on sm+:

-                        className="text-default hover:bg-muted min-w-0 cursor-pointer truncate whitespace-nowrap rounded p-1 text-sm font-semibold leading-none sm:min-w-[100px]"
+                        className="text-default hover:bg-muted min-w-0 cursor-pointer break-words whitespace-normal rounded p-1 text-sm font-semibold leading-snug sm:whitespace-nowrap sm:truncate sm:min-w-[100px]"

Consider disabling the Tooltip on touch devices where hover isn’t available.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3fc8c6c and 3302f2e.

📒 Files selected for processing (1)
  • packages/features/ee/workflows/pages/workflow.tsx (15 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Always use t() for text localization in frontend code; direct text embedding should trigger a warning

Files:

  • packages/features/ee/workflows/pages/workflow.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • packages/features/ee/workflows/pages/workflow.tsx
**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.

Files:

  • packages/features/ee/workflows/pages/workflow.tsx
🧠 Learnings (2)
📓 Common learnings
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/features/calAIPhone/providers/retellAI/services/AgentService.ts:83-88
Timestamp: 2025-08-26T20:23:28.396Z
Learning: In calcom/cal.com PR #22995, the workflow update handler in packages/trpc/server/routers/viewer/workflows/update.handler.ts includes workflow-level authorization via isAuthorized(userWorkflow, ctx.user.id, "workflow.update") which validates the user can update the workflow before calling updateToolsFromAgentId (per maintainer Udit-takkar).
📚 Learning: 2025-08-26T20:09:17.089Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/features/ee/workflows/components/WorkflowStepContainer.tsx:641-649
Timestamp: 2025-08-26T20:09:17.089Z
Learning: In packages/features/ee/workflows/components/WorkflowStepContainer.tsx, Cal.AI actions are intentionally filtered out/hidden for organization workflows when props.isOrganization is true. This restriction is by design per maintainer Udit-takkar in PR #22995, despite the broader goal of enabling Cal.AI self-serve.

Applied to files:

  • packages/features/ee/workflows/pages/workflow.tsx
🧬 Code graph analysis (1)
packages/features/ee/workflows/pages/workflow.tsx (6)
packages/trpc/react/trpc.ts (2)
  • trpc (54-138)
  • RouterOutputs (143-143)
packages/lib/server/repository/workflow-permissions.ts (1)
  • WorkflowPermissions (4-9)
packages/features/ee/workflows/lib/actionHelperFunctions.ts (3)
  • isSMSAction (25-27)
  • isSMSOrWhatsappAction (33-35)
  • isCalAIAction (37-39)
packages/lib/constants.ts (1)
  • SENDER_ID (30-30)
packages/ui/components/button/Button.tsx (1)
  • Button (221-349)
packages/features/ee/workflows/components/WorkflowDetailsPage.tsx (1)
  • WorkflowDetailsPage (38-242)
🔇 Additional comments (5)
packages/features/ee/workflows/pages/workflow.tsx (5)

213-218: Verify sender/senderName mapping

You set senderName = step.sender and sender = SENDER_ID for non‑SMS. In WorkflowDetailsPage.addAction, non‑SMS uses senderName = SENDER_NAME and sender = SENDER_ID. Please confirm DB semantics so UI displays a human "From name" for email steps and preserves SMS sender IDs for SMS steps. If needed, map like:

// Example mapping (if applicable):
senderName: isSMSAction(step.action) ? SENDER_NAME : step.sender ?? SENDER_NAME,
sender: isSMSAction(step.action) ? step.sender : SENDER_ID,

(Based on learnings)


331-336: Header container changes improve mobile resilience

min-w-0 on flex containers and compact paddings look good for overflow control.


395-419: Action buttons sizing/alignment

Using size="sm", spacing tweaks and disabled states are appropriate for mobile.


427-438: Prop wiring to WorkflowDetailsPage

Passing permissions, allOptions, and handlers is consistent with the refactor.


96-105: Guard getVerifiedEmails query by teamId
Change the enabled flag to verifiedEmailsProp ? false : !!workflow?.team?.id so the query only fires when teamId is defined.

Comment on lines +183 to 187
if (!workflowData) return;
if (workflowData.userId && workflowData.activeOn.find((a) => !!a.eventType.teamId)) {
setIsMixedEventType(true);
}

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Potential undefined access on activeOn

workflowData.activeOn.find(...) can throw if activeOn is undefined/null. Use optional chaining.

Apply:

-    if (workflowData.userId && workflowData.activeOn.find((a) => !!a.eventType.teamId)) {
+    if (workflowData.userId && workflowData.activeOn?.find((a) => !!a.eventType.teamId)) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!workflowData) return;
if (workflowData.userId && workflowData.activeOn.find((a) => !!a.eventType.teamId)) {
setIsMixedEventType(true);
}
if (!workflowData) return;
if (workflowData.userId && workflowData.activeOn?.find((a) => !!a.eventType.teamId)) {
setIsMixedEventType(true);
}
🤖 Prompt for AI Agents
In packages/features/ee/workflows/pages/workflow.tsx around lines 183 to 187,
the code accesses workflowData.activeOn without guarding against undefined which
can throw; update the condition to safely handle missing activeOn by using
optional chaining or a fallback array (e.g. workflowData.activeOn?.find(...) or
(workflowData.activeOn || []).find(...)) so the find call won't run on
undefined, and keep the existing userId check and setIsMixedEventType(true)
behavior.

@pallava-joshi
Copy link
Contributor

closing in ref #24257

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community Created by Linear-GitHub Sync 🧹 Improvements Improvements to existing features. Mostly UX/UI size/L workflows area: workflows, automations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mobile Responsiveness Issues on Workflows Page: Poor Layout and Text Overflow

3 participants