Revert "fix: ContextualBar state and refresh behavior on custom sounds (#38442)"#38818
Revert "fix: ContextualBar state and refresh behavior on custom sounds (#38442)"#38818
Conversation
|
Looks like this PR is ready to merge! 🎉 |
|
WalkthroughChanges remove _id query parameter support from the custom-sounds list endpoint and related test coverage. UI components no longer explicitly close after save actions and now refetch data instead. The close prop is made optional across sound editing components. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ 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. Comment |
There was a problem hiding this comment.
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 (2)
apps/meteor/client/views/admin/customSounds/EditCustomSound.tsx (1)
19-29:⚠️ Potential issue | 🟠 MajorQuery fires with no guard when
_idisundefined, populating the form with an arbitrary sound.
_idis typedstring | undefined. When it isundefined,JSON.stringify({ _id: undefined })produces'{}'(JSON.stringify silently dropsundefinedvalues), so the list query runs unrestricted andsounds[0]returns whichever sound sorts first — silently mis-populating the edit form.Add an
enabledguard so the query is suppressed until a valid_idis available:🐛 Proposed fix
const { data, isPending, refetch } = useQuery({ queryKey: ['custom-sounds', _id], + enabled: !!_id, queryFn: async () => { const { sounds } = await getSounds({ query: JSON.stringify({ _id }) }); if (sounds.length === 0) { throw new Error(t('No_results_found')); } return sounds[0]; }, meta: { apiErrorToastMessage: true }, });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/meteor/client/views/admin/customSounds/EditCustomSound.tsx` around lines 19 - 29, The useQuery call in EditCustomSound.tsx fires when _id is undefined, causing getSounds to receive '{}' and returning the wrong sound; update the useQuery invocation (the hook that destructures { data, isPending, refetch }) to include an enabled guard that only runs when a valid _id exists (e.g., enabled: Boolean(_id) or typeof _id === 'string'), so the queryFn (which calls getSounds and returns sounds[0]) is suppressed until _id is defined.apps/meteor/client/views/admin/customSounds/EditSound.tsx (1)
152-152:⚠️ Potential issue | 🟡 MinorCancel button is silently non-functional when
closeis not provided.
closeis now optional, so when the component renders without acloseprop, this button becomes a no-op click target with no visual indication to the user. Consider guarding or rendering the button conditionally:💡 Proposed fix
-<Button onClick={close}>{t('Cancel')}</Button> +{close && <Button onClick={close}>{t('Cancel')}</Button>}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/meteor/client/views/admin/customSounds/EditSound.tsx` at line 152, The Cancel Button inside the EditSound component currently calls an optional prop close and becomes a silent no-op when close is undefined; update the JSX around the Button (the Button that calls close) to either render the Button only when the close prop exists or render a disabled/aria-disabled Button with an explanatory title/tooltip when close is absent, so users get a visible affordance—locate the EditSound component and the Button that references close and implement the conditional render or disable logic accordingly.
🧹 Nitpick comments (1)
apps/meteor/client/views/admin/customSounds/EditCustomSound.tsx (1)
41-44:handleChangerecreated on every render; wrap inuseCallback.Without memoisation, every render of
EditCustomSoundproduces a newhandleChangereference. BecauseEditSoundhasonChangein theuseCallbackdependency arrays for bothhandleSaveandhandleDeleteButtonClick, those callbacks also recreate on every parent render — creating an avoidable re-render cascade.♻️ Proposed fix
-const handleChange: () => void = () => { - onChange?.(); - refetch?.(); -}; +import { useCallback } from 'react'; +// (add useCallback to existing import) + +const handleChange = useCallback(() => { + onChange?.(); + refetch(); +}, [onChange, refetch]);Note:
refetchfromuseQueryis always a stable function reference — the?.optional-chaining is also unnecessary here.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/meteor/client/views/admin/customSounds/EditCustomSound.tsx` around lines 41 - 44, The handleChange function in EditCustomSound is recreated every render; wrap it in useCallback to stabilize its reference so handleSave and handleDeleteButtonClick no longer re-create on each parent render. Replace the current const handleChange = () => { onChange?.(); refetch?.(); } with a useCallback that calls onChange (if present) and refetch (no optional chaining) and list onChange in the dependency array — e.g. useCallback(() => { onChange?.(); refetch(); }, [onChange]) — so handleChange remains stable across renders.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
.changeset/hip-melons-bow.mdapps/meteor/app/api/server/v1/custom-sounds.tsapps/meteor/client/views/admin/customSounds/AddCustomSound.tsxapps/meteor/client/views/admin/customSounds/EditCustomSound.tsxapps/meteor/client/views/admin/customSounds/EditSound.tsxapps/meteor/tests/end-to-end/api/custom-sounds.ts
💤 Files with no reviewable changes (3)
- apps/meteor/tests/end-to-end/api/custom-sounds.ts
- apps/meteor/client/views/admin/customSounds/AddCustomSound.tsx
- .changeset/hip-melons-bow.md
🧰 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/app/api/server/v1/custom-sounds.tsapps/meteor/client/views/admin/customSounds/EditSound.tsxapps/meteor/client/views/admin/customSounds/EditCustomSound.tsx
🧠 Learnings (1)
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.
Applied to files:
apps/meteor/app/api/server/v1/custom-sounds.ts
⏰ 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). (2)
- GitHub Check: 📦 Build Packages
- GitHub Check: CodeQL-Build
🔇 Additional comments (2)
apps/meteor/app/api/server/v1/custom-sounds.ts (1)
16-16: LGTM —_idcleanly removed from type and schema.The narrowing of
CustomSoundsListtoPaginatedRequest<{ name?: string }>combined withadditionalProperties: falseon the schema correctly rejects any stray_idroot-level query parameter. The genericquerystring param (handled byparseJsonQuery) remains available for callers that need richer MongoDB-style filters.apps/meteor/client/views/admin/customSounds/EditCustomSound.tsx (1)
23-23: Thequeryparameter is deprecated and only functions with explicit environment variable enablement.
parseJsonQueryrequires theALLOW_UNSAFE_QUERY_AND_FIELDS_API_PARAMS=TRUEenvironment variable to parse thequeryparameter at all (lines 116-130 of parseJsonQuery.ts). Without it, the query remains empty in production. When enabled, the parameter is sanitized via theclean()function, which removes dangerous properties and filters out MongoDB operators not in the allowlist (['$or', '$and', '$regex']). However, field-level filtering including_idis allowed since it's not in the API's excluded fields list. The deprecation notice targets version 9.0.0 removal.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/meteor/client/views/admin/customSounds/EditSound.tsx`:
- Around line 97-100: The handler handleSave currently calls the async
saveAction in a fire-and-forget manner causing onChange()/refetch to run before
the save completes; update handleSave (the useCallback that references
saveAction, sound, onChange) to await saveAction(sound) and only call onChange()
after the await (and handle/rethrow/log any errors as appropriate) so that
EditCustomSound's refetch runs after the server mutation has committed.
---
Outside diff comments:
In `@apps/meteor/client/views/admin/customSounds/EditCustomSound.tsx`:
- Around line 19-29: The useQuery call in EditCustomSound.tsx fires when _id is
undefined, causing getSounds to receive '{}' and returning the wrong sound;
update the useQuery invocation (the hook that destructures { data, isPending,
refetch }) to include an enabled guard that only runs when a valid _id exists
(e.g., enabled: Boolean(_id) or typeof _id === 'string'), so the queryFn (which
calls getSounds and returns sounds[0]) is suppressed until _id is defined.
In `@apps/meteor/client/views/admin/customSounds/EditSound.tsx`:
- Line 152: The Cancel Button inside the EditSound component currently calls an
optional prop close and becomes a silent no-op when close is undefined; update
the JSX around the Button (the Button that calls close) to either render the
Button only when the close prop exists or render a disabled/aria-disabled Button
with an explanatory title/tooltip when close is absent, so users get a visible
affordance—locate the EditSound component and the Button that references close
and implement the conditional render or disable logic accordingly.
---
Nitpick comments:
In `@apps/meteor/client/views/admin/customSounds/EditCustomSound.tsx`:
- Around line 41-44: The handleChange function in EditCustomSound is recreated
every render; wrap it in useCallback to stabilize its reference so handleSave
and handleDeleteButtonClick no longer re-create on each parent render. Replace
the current const handleChange = () => { onChange?.(); refetch?.(); } with a
useCallback that calls onChange (if present) and refetch (no optional chaining)
and list onChange in the dependency array — e.g. useCallback(() => {
onChange?.(); refetch(); }, [onChange]) — so handleChange remains stable across
renders.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #38818 +/- ##
===========================================
- Coverage 70.58% 70.55% -0.04%
===========================================
Files 3182 3182
Lines 112430 112467 +37
Branches 20375 20390 +15
===========================================
- Hits 79361 79351 -10
- Misses 31017 31064 +47
Partials 2052 2052
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
Issue
I need to rollback this PR (#38442) in order to merge the cleaner version of these fixes:
CORE-1819 Address technical debt following CORE-1789 (custom-sounds single resource fetch)
Summary by CodeRabbit
Release Notes
Bug Fixes
Changes