Skip to content

Conversation

@amankv1234
Copy link

@amankv1234 amankv1234 commented Jan 28, 2026

What was done

Refactored ReturnChatQueueModal to use the shared GenericModal component instead of composing the modal structure manually.

Why

This aligns the Omnichannel modal with the standardized modal pattern used across the codebase, reducing duplicated boilerplate and improving consistency and maintainability.

Changes

  • Replaced raw Fuselage modal primitives with GenericModal
  • Mapped existing header, icon, content, and footer actions to GenericModal props
  • Removed redundant modal layout code

Verification

  • Confirmed the modal renders correctly
  • Confirmed cancel and confirm actions behave the same as before

Notes

This is a refactor-only change; no visual or functional behavior was modified.

Proposed changes (including videos or screenshots)

Issue(s)

Steps to test or reproduce

Further comments

Summary by CodeRabbit

  • Refactor

    • Replaced bespoke modal implementations with a unified GenericModal for consistent appearance and behavior.
    • Simplified modal layouts and component signatures, flattening form structure while preserving fields, validation, submission gating, and navigation flows.
  • New Features

    • Unified transcript options: consolidated PDF/email controls and conditionally show contact/subject inputs when email is enabled.

✏️ Tip: You can customize this high-level summary in your review settings.

## What was done
Refactored `ReturnChatQueueModal` to use the shared `GenericModal` component instead of composing the modal structure manually.

##  Why
This aligns the Omnichannel modal with the standardized modal pattern used across the codebase, reducing duplicated boilerplate and improving consistency and maintainability.

##  Changes
- Replaced raw Fuselage modal primitives with `GenericModal`
- Mapped existing header, icon, content, and footer actions to `GenericModal` props
- Removed redundant modal layout code

### Verification
- Confirmed the modal renders correctly
- Confirmed cancel and confirm actions behave the same as before

##  Notes
This is a refactor-only change; no visual or functional behavior was modified.
@amankv1234 amankv1234 requested a review from a team as a code owner January 28, 2026 10:17
@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Jan 28, 2026

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link

changeset-bot bot commented Jan 28, 2026

⚠️ No Changeset found

Latest commit: 80cb5c7

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@CLAassistant
Copy link

CLAassistant commented Jan 28, 2026

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 28, 2026

Walkthrough

Replaced bespoke modal compositions with GenericModal across several Omnichannel modals, preserving existing fields, validation, submission, and cancel behavior while simplifying component signatures and layout.

Changes

Cohort / File(s) Summary
Return Chat Queue Modal
apps/meteor/client/views/omnichannel/modals/ReturnChatQueueModal.tsx
Replaced manual Modal subcomponents with GenericModal; removed spread props; deconstructed onCancel and onMoveChat; migrated title/icon/confirm/cancel handling to GenericModal props and children.
Close Chat Modal
apps/meteor/client/views/omnichannel/modals/CloseChatModal.tsx
Replaced legacy ModalHeader/ModalContent/ModalFooter with GenericModal; flattened form layout into GenericModal children; preserved comment, tags, transcript fields, validation, submission logic, and confirm/cancel/disabled wiring.
Enterprise Departments Modal
apps/meteor/client/views/omnichannel/modals/EnterpriseDepartmentsModal.tsx
Replaced bespoke modal with GenericModal; introduced onUpgrade using useCheckoutUrl; moved informational content into modal body; kept onClose navigation behavior.
Forward Chat Modal
apps/meteor/client/views/omnichannel/modals/ForwardChatModal.tsx
Replaced legacy modal subcomponents with GenericModal; removed extra props spread; wired confirm to form submit and confirmDisabled to field presence; retained react-hook-form wiring and username→userId resolution logic.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

Suggested labels

stat: ready to merge, stat: QA assured

Suggested reviewers

  • lucas-a-pelegrino
  • dougfabris

Poem

🐇 I hopped through JSX with nimble paws,
Replaced stacked panes with simpler laws.
Fields stayed true and handlers kept,
One GenericModal now adept.
I thumped a drum and munched a carrot—cheers! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'refactor: refactor code' is vague and generic, using non-descriptive language that fails to convey the specific nature of the changes. Use a more specific title that describes the main refactoring effort, such as 'refactor: migrate omnichannel modals to GenericModal' to clearly communicate the scope and purpose of the changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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)
  • PATCH-1: Request failed with status code 404

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.

@amankv1234 amankv1234 changed the title Refactor ReturnChatQueueModal to use GenericModal refactor: refactor code Jan 28, 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.

No issues found across 1 file

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

🤖 Fix all issues with AI agents
In `@apps/meteor/client/views/omnichannel/modals/CloseChatModal.tsx`:
- Line 178: Remove the noisy inline implementation comment inside the
CloseChatModal component's JSX (the comment text like {/* Transcript section
unchanged */}); instead delete that JSX comment altogether so the markup is
cleaner and follows the guideline to avoid implementation comments in
CloseChatModal (look for the JSX block in the CloseChatModal function where the
transcript section is rendered and remove the inline comment).

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.

No issues found across 2 files

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

🤖 Fix all issues with AI agents
In `@apps/meteor/client/views/omnichannel/modals/ReturnChatQueueModal.tsx`:
- Line 14: Remove the stray development comment "//model to genericmodel" from
the ReturnChatQueueModal component (ReturnChatQueueModal.tsx); delete the line
entirely (do not replace it with another comment) so the codebase contains no
leftover dev notes or typos.

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: 0

Caution

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

⚠️ Outside diff range comments (1)
apps/meteor/client/views/omnichannel/modals/CloseChatModal.tsx (1)

82-107: Broken validation logic: stale errors and inverted condition.

Two issues prevent correct validation:

  1. Stale errors reference: setError schedules a state update but errors in this closure still holds the previous render's value. The checks on line 102 will never see the errors just set above.

  2. Inverted condition: !errors.comment || errors.tags reads "proceed if no comment error OR there are tag errors", which is the opposite of the intended logic. Also, errors.subject is never checked.

Refactor to validate inline and return early, avoiding reliance on stale state:

🐛 Proposed fix
 const onSubmit = useCallback(
   ({ comment, tags, transcriptPDF, transcriptEmail, subject }: CloseChatModalFormData) => {
     const preferences = {
       omnichannelTranscriptPDF: !!transcriptPDF,
       omnichannelTranscriptEmail: alwaysSendTranscript ? true : !!transcriptEmail,
     };
     const requestData = transcriptEmail && visitorEmail ? { email: visitorEmail, subject } : undefined;

+    let hasError = false;
+
     if (!comment?.trim() && commentRequired) {
       setError('comment', { type: 'custom', message: t('Required_field', { field: t('Comment') }) });
+      hasError = true;
     }

     if (transcriptEmail && !subject) {
       setError('subject', { type: 'custom', message: t('Required_field', { field: t('Subject') }) });
+      hasError = true;
     }

     if (!tags?.length && tagRequired) {
       setError('tags', { type: 'custom', message: t('error-tags-must-be-assigned-before-closing-chat') });
+      hasError = true;
     }

-    if (!errors.comment || errors.tags) {
+    if (!hasError) {
       onConfirm(comment, tags, preferences, requestData);
     }
   },
-  [commentRequired, tagRequired, visitorEmail, errors, setError, t, onConfirm, alwaysSendTranscript],
+  [commentRequired, tagRequired, visitorEmail, setError, t, onConfirm, alwaysSendTranscript],
 );

@amankv1234
Copy link
Author

Thanks for the review!
I've refactored the submit validation to avoid relying on stale form state, fixed the inverted condition, and now validate inline using a local error flag as suggested.

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: 0

Caution

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

⚠️ Outside diff range comments (1)
apps/meteor/client/views/omnichannel/modals/CloseChatModal.tsx (1)

162-170: Potential issue: subject in dependency array may cause unintended resets.

Including subject in the dependency array while also calling setValue('subject', ...) can create unexpected behavior. If the user clears the subject field, the empty string is falsy, so subject || customSubject || t(...) resets it to the default value—preventing the user from intentionally clearing it.

While subject is required when transcriptEmail is enabled (so an empty value would fail validation anyway), this pattern is confusing and could mask bugs.

Consider removing subject from the dependency array and only setting the default when transcriptEmail first becomes true:

Suggested approach
 useEffect(() => {
   if (transcriptEmail) {
     if (!visitorEmail) {
       dispatchToastMessage({ type: 'error', message: t('Customer_without_registered_email') });
       return;
     }
-    setValue('subject', subject || customSubject || t('Transcript_of_your_livechat_conversation'));
+    setValue('subject', customSubject || t('Transcript_of_your_livechat_conversation'), { shouldDirty: false });
   }
-}, [transcriptEmail, setValue, visitorEmail, subject, t, customSubject, dispatchToastMessage]);
+}, [transcriptEmail, setValue, visitorEmail, t, customSubject, dispatchToastMessage]);

@amankv1234
Copy link
Author

amankv1234 commented Jan 29, 2026

Thanks for pointing this out!
I’ve updated the effect to avoid resetting the subject based on its own value.
The default subject is now set only when transcriptEmail becomes true, removed subject from the dependency array, and used shouldDirty: false to preserve user input.

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

Labels

duplicate Closed as Duplicate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants