Skip to content

Conversation

@sharanyamahajan
Copy link

@sharanyamahajan sharanyamahajan commented Jan 22, 2026

Proposed changes (including videos or screenshots)

This PR refactors the Menu component to improve ref handling by removing an any-typed ref and an explicit FIXME comment.

The component is updated to use a properly typed forwardRef<HTMLDivElement>, ensuring:

  • Stronger type safety
  • Direct access to the underlying DOM element
  • Removal of internal component field access
  • Cleaner and more maintainable code

This is a type-only refactor and does not introduce any UI or behavioral changes. Existing subcomponents (Menu.Group, Menu.Item, Menu.Popover) continue to work as before.


Issue(s)

Fixes #38273


Steps to test or reproduce

  1. Use the Menu component anywhere it is currently rendered.
  2. Verify that the menu renders and positions correctly.
  3. Confirm that refs pointing to Menu now resolve to the underlying HTMLDivElement.
  4. Ensure no visual or functional changes are observed.

Further comments

This change addresses acknowledged technical debt by removing an any-typed ref and aligning the component with standard Preact ref patterns. The refactor is intentionally minimal and scoped to improve type safety without affecting runtime behavior.

Note:
A local build was attempted on Windows; it failed in @rocket.chat/favicon due to the use of the Unix-only rm command. This failure is environment-specific and unrelated to the changes in this PR. CI is expected to validate the update successfully.

GitHub currently reports that this branch cannot be automatically merged due to parallel changes in the same area. The branch is rebased on the latest develop, and final conflict resolution can be handled during merge if required.

Summary by CodeRabbit

  • New Features

    • Added loading skeleton state indicators for improved visual feedback in room contextual panels.
    • Enhanced menu component structure with new organizational sub-components.
  • Bug Fixes

    • Improved database connection option handling to properly merge user-provided configurations.
    • Refined email routing behavior in non-development environments.
  • Refactor

    • Simplified database query API for improved reliability and reduced complexity.

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

@sharanyamahajan sharanyamahajan requested review from a team as code owners January 22, 2026 16:58
@changeset-bot
Copy link

changeset-bot bot commented Jan 22, 2026

⚠️ No Changeset found

Latest commit: 7c4aa39

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

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Jan 22, 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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 22, 2026

Walkthrough

This PR refactors and enhances multiple components across the codebase: adds defensive logic to sidebar item deregistration, introduces a new skeleton loading component for contextual lists, refactors MongoDB configuration and email handling, restructures the Menu component to use forwardRef with typed sub-components, and consolidates BaseRaw model methods with enhanced trash rollback support.

Changes

Cohort / File(s) Summary
Sidebar Management
apps/meteor/client/lib/createSidebarItems.ts
Guards unregisterSidebarItem against non-existent indices using splice instead of direct deletion to prevent undefined holes.
Contextual UI Components
apps/meteor/client/views/room/contextualBar/lib/ContextualListSkeleton.tsx
New React component rendering skeleton rows with avatar and text placeholders for loading states; configurable item count (default 6).
Database & Email Configuration
apps/meteor/packages/rocketchat-mongo-config/server/index.js
Merges user-provided MONGO_OPTIONS into connection settings via Object.assign; redirects Email.sendAsync through PassThrough stream in non-test/non-dev environments.
Livechat Menu Component
packages/livechat/src/components/Menu/index.tsx
Refactors Menu to use forwardRef with typed props; adds Group and Item sub-components; introduces PopoverMenuWrapper for dynamic positioning and PopoverMenu composition.
Base Model API Consolidation
packages/models/src/models/BaseRaw.ts
Consolidates find/delete methods with simplified overloads; enhances deleteOne with trash rollback logic on failure; conditionally applies timestamp updates based on preventSetUpdatedAt flag.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • #37661 — Moves ContextualBar and subcomponents to ui-client package, affecting the same component surface where ContextualListSkeleton is added.

Suggested labels

stat: ready to merge, stat: QA assured

Suggested reviewers

  • MartinSchoeler
  • gabriellsh
  • tassoevan

Poem

🐰 Menu finds its way with refs so true,
A skeleton dances in loading's blue,
Config flows, and models align,
Each change a hop on the timeline!
Type safety hops, no more "any" in sight!

🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR makes changes to multiple files beyond the Menu component refactor, including modifications to createSidebarItems.ts, ContextualListSkeleton.tsx, rocketchat-mongo-config/server/index.js, and BaseRaw.ts, which are unrelated to issue #38273's Menu component refactor objective. Review the changeset and verify whether all non-Menu modifications are necessary. If unrelated, separate them into a different PR or confirm they address unstated requirements from issue #38273.
Out of Scope Changes check ⚠️ Warning Multiple files modified fall outside the stated scope of refactoring the Menu component: createSidebarItems.ts (unregisterSidebarItem logic), ContextualListSkeleton.tsx (new component), rocketchat-mongo-config/server/index.js (Mongo/Email config), and BaseRaw.ts (CRUD method consolidation). Either document why these changes are required for the Menu refactor or move them to separate PRs. Limit this PR to packages/livechat/src/components/Menu/index.tsx changes only.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'refactor(menu): replace any-typed ref with forwardRef' directly describes the main change in the PR, which focuses on refactoring the Menu component to use forwardRef for type-safe ref handling.
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

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
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/packages/rocketchat-mongo-config/server/index.js (1)

31-38: Validate MONGO_OPTIONS is a plain object before merging.
If the JSON parses to null, an array, or a primitive, the merge either fails or yields unexpected keys. Please guard and emit a clearer error for non-object values.

🛠️ Proposed fix
-	try {
-		const mongoOptions = JSON.parse(mongoOptionStr);
-		Object.assign(mongoConnectionOptions, mongoOptions);
-	} catch (error) {
-		throw new Error('Invalid MONGO_OPTIONS environment variable: must be valid JSON.', { cause: error });
-	}
+	let mongoOptions;
+	try {
+		mongoOptions = JSON.parse(mongoOptionStr);
+	} catch (error) {
+		throw new Error('Invalid MONGO_OPTIONS environment variable: must be valid JSON.', { cause: error });
+	}
+
+	if (mongoOptions === null || typeof mongoOptions !== 'object' || Array.isArray(mongoOptions)) {
+		throw new Error('Invalid MONGO_OPTIONS environment variable: must be a JSON object.');
+	}
+	Object.assign(mongoConnectionOptions, mongoOptions);
🧹 Nitpick comments (4)
packages/models/src/models/BaseRaw.ts (2)

170-170: Remove marker comments.

These /* ===================== FIXED METHOD ===================== */ style comments are debug/development artifacts that add noise without providing meaningful documentation. As per coding guidelines, avoid code comments in the implementation.

Proposed fix
-	/* ===================== FIXED METHOD ===================== */
-
 	async findOneAndDelete(filter: Filter<T>, options?: FindOneAndDeleteOptions): Promise<WithId<T> | null> {
-	/* ======================================================== */
-
 	private setUpdatedAt(record: UpdateFilter<T> | InsertionModel<T>): void {

Also applies to: 222-222


157-168: any-typed options parameter undermines type safety.

Both findOneById and findOne implementation signatures use options?: any, which defeats TypeScript's type checking for MongoDB FindOptions. Consider using proper union types or a constrained generic to preserve type safety.

Suggested approach
-	async findOneById(_id: T['_id'], options?: any): Promise<T | null> {
+	async findOneById(_id: T['_id'], options?: FindOptions<T>): Promise<T | null> {
 		const query: Filter<T> = { _id } as Filter<T>;
 		return options ? this.findOne(query, options) : this.findOne(query);
 	}

-	async findOne<P extends Document = T>(query: Filter<T> | T['_id'] = {}, options?: any): Promise<WithId<T> | WithId<P> | null> {
+	async findOne<P extends Document = T>(query: Filter<T> | T['_id'] = {}, options?: FindOptions<T> | FindOptions<P>): Promise<WithId<T> | WithId<P> | null> {
apps/meteor/packages/rocketchat-mongo-config/server/index.js (1)

15-18: Avoid inline TODO/FIX comments in implementation.
Please move the TODO/FIX note to the issue tracker and keep the code comment-free to match the project’s style expectations. As per coding guidelines, ...

packages/livechat/src/components/Menu/index.tsx (1)

10-13: Consider removing the section divider comments.
These banner comments add noise, and the local guidelines prefer comment-free implementation blocks.

🧹 Suggested cleanup
-/* ------------------------------------------------------------------ */
-/* Menu */
-/* ------------------------------------------------------------------ */
-
-/* ------------------------------------------------------------------ */
-/* Group */
-/* ------------------------------------------------------------------ */
-
-/* ------------------------------------------------------------------ */
-/* Item */
-/* ------------------------------------------------------------------ */
-
-/* ------------------------------------------------------------------ */
-/* PopoverMenuWrapper */
-/* ------------------------------------------------------------------ */
-
-/* ------------------------------------------------------------------ */
-/* PopoverMenu */
-/* ------------------------------------------------------------------ */
-
-/* ------------------------------------------------------------------ */
-/* Static bindings */
-/* ------------------------------------------------------------------ */
As per coding guidelines, avoid implementation comments.

Also applies to: 33-36, 48-51, 77-80, 156-159, 185-187

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 5 files

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Menu component uses any-typed ref with FIXME comment

2 participants