Skip to content

refactor(ui): replace obsolete TextCopy with CodeSnippet in TwoFactorTOTP#39957

Open
thekishandev wants to merge 1 commit intoRocketChat:developfrom
thekishandev:refactor/replace-textcopy-component-39956
Open

refactor(ui): replace obsolete TextCopy with CodeSnippet in TwoFactorTOTP#39957
thekishandev wants to merge 1 commit intoRocketChat:developfrom
thekishandev:refactor/replace-textcopy-component-39956

Conversation

@thekishandev
Copy link
Copy Markdown

@thekishandev thekishandev commented Mar 29, 2026

Proposed changes

This PR removes the absolute final usage of the deprecated <TextCopy> component in the .tsx codebase, replacing it with the globally supported @rocket.chat/fuselage <CodeSnippet>. Since it was the last consumer, the obsolete TextCopy component file itself has been permanently deleted from the codebase to sanitize the /components directory and reduce bundle payload.

Root Cause / Problem

The TwoFactorTOTP view component was still relying on the obsolete internal <TextCopy> component instead of the design system.

// BEFORE
<TextCopy text={totpSecret || ''} />

Solution / Behavior

Replaced with official Fuselage , leveraging useClipboard for identical UX copy feedback. Safely deleted apps/meteor/client/components/TextCopy.tsx entirely.

// AFTER
<CodeSnippet buttonText={hasCopied ? t('Copied') : t('Copy')} buttonDisabled={hasCopied} onClick={() => copy()}>
	{totpSecret || ''}
</CodeSnippet>

Issue(s)

Closes #39956

Validation & Testing

Tested locally (Standard copy-to-clipboard functionality verified)
Confirmed TextCopy does not explicitly exist anywhere else

Type of change

refactor (non-breaking change replacing legacy UI architecture)

Summary by CodeRabbit

Refactor

  • Updated the copy-to-clipboard interaction in the security settings interface with improved visual feedback on successful copy actions.

@thekishandev thekishandev requested a review from a team as a code owner March 29, 2026 19:29
Copilot AI review requested due to automatic review settings March 29, 2026 19:29
@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot bot commented Mar 29, 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
Copy Markdown

changeset-bot bot commented Mar 29, 2026

⚠️ No Changeset found

Latest commit: bf1f2fd

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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 29, 2026

Walkthrough

This pull request removes the obsolete TextCopy component and replaces its sole remaining usage in TwoFactorTOTP.tsx with the standardized CodeSnippet component, consolidating clipboard functionality using useClipboard.

Changes

Cohort / File(s) Summary
Component Removal
apps/meteor/client/components/TextCopy.tsx
Deleted the legacy TextCopy component (45 lines) that provided a copy-to-clipboard UI wrapper with toast notification.
Component Replacement
apps/meteor/client/views/account/security/TwoFactorTOTP.tsx
Replaced TextCopy with CodeSnippet component and integrated useClipboard hook for direct clipboard operations, eliminating the prior component-based copy logic.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Suggested labels

type: chore, area: authentication

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: replacing TextCopy with CodeSnippet in TwoFactorTOTP, which aligns with the changeset.
Linked Issues check ✅ Passed The PR successfully replaces TextCopy with CodeSnippet in TwoFactorTOTP and deletes the obsolete TextCopy component, fulfilling all coding requirements from issue #39956.
Out of Scope Changes check ✅ Passed All changes are directly related to the linked issue objectives: replacing TextCopy with CodeSnippet and deleting the obsolete component.
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.


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.

Copy link
Copy Markdown
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
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR completes the migration away from the deprecated internal TextCopy component by updating the TwoFactorTOTP security view to use Fuselage’s CodeSnippet, and then deleting the now-unused TextCopy component implementation.

Changes:

  • Replaced TextCopy usage in TwoFactorTOTP with CodeSnippet + useClipboard.
  • Removed the legacy apps/meteor/client/components/TextCopy.tsx component file.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
apps/meteor/client/views/account/security/TwoFactorTOTP.tsx Swaps deprecated copy UI for Fuselage CodeSnippet and wires clipboard behavior.
apps/meteor/client/components/TextCopy.tsx Deletes the obsolete component now that it has no consumers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +38 to +39
const { copy, hasCopied } = useClipboard(totpSecret || '');

Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

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

This refactor changes copy feedback: the previous TextCopy used useClipboardWithToast, which dispatches a success toast on copy. The new useClipboard usage only updates hasCopied/button label, so the toast is lost. If the intent is to preserve existing UX (and match the PR description), switch to useClipboardWithToast(totpSecret ?? '') or pass onCopySuccess/onCopyError options to useClipboard to keep the toast behavior.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
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.

🧹 Nitpick comments (1)
apps/meteor/client/views/account/security/TwoFactorTOTP.tsx (1)

157-159: CodeSnippet props are correct — no changes needed.

The onClick prop is the correct handler for the copy button action in the fuselage CodeSnippet component, confirmed across multiple usages in the codebase (Installation.tsx, SaveE2EPasswordModal.tsx, BackupCodesModal.tsx).

Note: While onClick={copy} would simplify the code, the onClick={() => copy()} pattern is consistently used throughout the codebase for this component, so either form is acceptable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/client/views/account/security/TwoFactorTOTP.tsx` around lines 157
- 159, The CodeSnippet usage is fine: keep the onClick prop as provided
(onClick={() => copy()}) and leave buttonText and buttonDisabled unchanged; no
code change required for CodeSnippet in TwoFactorTOTP.tsx — if you prefer you
may optionally simplify to onClick={copy} for consistency with other usages but
it's not necessary.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/meteor/client/views/account/security/TwoFactorTOTP.tsx`:
- Around line 157-159: The CodeSnippet usage is fine: keep the onClick prop as
provided (onClick={() => copy()}) and leave buttonText and buttonDisabled
unchanged; no code change required for CodeSnippet in TwoFactorTOTP.tsx — if you
prefer you may optionally simplify to onClick={copy} for consistency with other
usages but it's not necessary.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2678c773-f6c0-49f0-99e4-b91a8ebb4eed

📥 Commits

Reviewing files that changed from the base of the PR and between 4235cd9 and bf1f2fd.

📒 Files selected for processing (2)
  • apps/meteor/client/components/TextCopy.tsx
  • apps/meteor/client/views/account/security/TwoFactorTOTP.tsx
💤 Files with no reviewable changes (1)
  • apps/meteor/client/components/TextCopy.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Agent
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

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

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/client/views/account/security/TwoFactorTOTP.tsx
🧠 Learnings (4)
📓 Common learnings
Learnt from: smirk-dev
Repo: RocketChat/Rocket.Chat PR: 39625
File: apps/meteor/app/api/server/v1/push.ts:85-97
Timestamp: 2026-03-14T14:58:58.834Z
Learning: In RocketChat/Rocket.Chat, the `push.token` POST/DELETE endpoints in `apps/meteor/app/api/server/v1/push.ts` were already migrated to the chained router API pattern on `develop` prior to PR `#39625`. `cleanTokenResult` (which strips `authToken` and returns `PushTokenResult`) and `isPushTokenPOSTProps`/`isPushTokenDELETEProps` validators already exist on `develop`. PR `#39625` only migrates `push.get` and `push.info` to the chained pattern. Do not flag `cleanTokenResult` or `PushTokenResult` as newly introduced behavior-breaking changes when reviewing this PR.
📚 Learning: 2026-03-27T14:52:56.865Z
Learnt from: dougfabris
Repo: RocketChat/Rocket.Chat PR: 39892
File: apps/meteor/client/views/room/contextualBar/Threads/Thread.tsx:150-155
Timestamp: 2026-03-27T14:52:56.865Z
Learning: In Rocket.Chat, there are two different `ModalBackdrop` components with different prop APIs. During review, confirm the import source: (1) `rocket.chat/fuselage` `ModalBackdrop` uses `ModalBackdropProps` based on `BoxProps` (so it supports `onClick` and other Box/DOM props) and does not have an `onDismiss` prop; (2) `rocket.chat/ui-client` `ModalBackdrop` uses a narrower props interface like `{ children?: ReactNode; onDismiss?: () => void }` and handles Escape keypress and outside mouse-up, and it does not forward arbitrary DOM props such as `onClick`. Flag mismatched props (e.g., `onDismiss` passed to the fuselage component or `onClick` passed to the ui-client component) and ensure the usage matches the correct component being imported.

Applied to files:

  • apps/meteor/client/views/account/security/TwoFactorTOTP.tsx
📚 Learning: 2025-11-17T15:07:13.273Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37398
File: packages/fuselage-ui-kit/src/surfaces/FuselageSurfaceRenderer.tsx:357-363
Timestamp: 2025-11-17T15:07:13.273Z
Learning: In packages/fuselage-ui-kit/src/surfaces/FuselageSurfaceRenderer.tsx, IconElement is a presentational, non-actionable element that does not require wrapping in AppIdProvider, similar to plain_text and mrkdwn renderers. Only actionable elements (those with actions, actionId, or interactive behavior) should be wrapped in AppIdProvider.

Applied to files:

  • apps/meteor/client/views/account/security/TwoFactorTOTP.tsx
📚 Learning: 2026-01-19T18:08:13.423Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38169
File: packages/ui-client/src/hooks/useGoToDirectMessage.ts:20-27
Timestamp: 2026-01-19T18:08:13.423Z
Learning: In React hooks, including custom hooks like useUserSubscriptionByName, must always be called unconditionally and in the same order on every render, per the Rules of Hooks. Passing empty strings or fallback values to hooks is the correct approach when dealing with potentially undefined values, rather than conditionally calling the hook based on whether the value exists.

Applied to files:

  • apps/meteor/client/views/account/security/TwoFactorTOTP.tsx
🔇 Additional comments (2)
apps/meteor/client/views/account/security/TwoFactorTOTP.tsx (2)

1-2: LGTM!

Imports are correctly sourced from the fuselage design system packages, aligning with the goal of using standardized components.


38-39: LGTM!

Hook is called unconditionally following React's Rules of Hooks, with appropriate fallback for potentially undefined totpSecret. Based on learnings: "Passing empty strings or fallback values to hooks is the correct approach when dealing with potentially undefined values."

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor(ui): replace obsolete TextCopy with CodeSnippet in TwoFactorTOTP

2 participants