Skip to content

fix(ui): ignore whitespace-only changes in account profile fields#38248

Closed
sharanyamahajan wants to merge 10 commits into
RocketChat:developfrom
sharanyamahajan:fix/ui-ignore-whitespace-profile-fields
Closed

fix(ui): ignore whitespace-only changes in account profile fields#38248
sharanyamahajan wants to merge 10 commits into
RocketChat:developfrom
sharanyamahajan:fix/ui-ignore-whitespace-profile-fields

Conversation

@sharanyamahajan
Copy link
Copy Markdown

@sharanyamahajan sharanyamahajan commented Jan 18, 2026

Proposed changes (including videos or screenshots)

This pull request fixes a UX issue in Account Settings → Profile where adding only whitespace (such as leading or trailing spaces) to text fields caused the "Save Changes" button to appear, even though no meaningful data change would be persisted.

The fix normalizes text input values before they are passed to react-hook-form, ensuring that whitespace-only edits do not mark the form as dirty. This aligns the client-side change detection with the existing server-side behavior, where values are already trimmed on save.

The change is limited to the profile form UI and does not affect backend logic, APIs, or data storage.

Issue(s)

Fixes #

Steps to test or reproduce

  1. Go to Account Settings → Profile.
  2. Focus any text field (e.g., Name, Username, Nickname, Bio, or Status Message).
  3. Add only spaces before or after the existing value.
  4. Observe that the "Save Changes" button does not appear.
  5. Modify the field with an actual content change and verify that the "Save Changes" button appears as expected.

Further comments

This is a small, scoped UI fix focused on improving form behavior and preventing false-positive change detection. No alternative approaches were required, and no side effects are expected.

Summary by CodeRabbit

  • New Features

    • Added visual loading skeleton indicators for contextual list displays to improve perceived performance
  • Bug Fixes

    • Improved form validation and error handling in user profile management
    • Enhanced input field handling with automatic trimming for cleaner data entry
  • Refactor

    • Streamlined internal database access patterns and sidebar item management

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

@sharanyamahajan sharanyamahajan requested review from a team as code owners January 18, 2026 18:34
@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot Bot commented Jan 18, 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 Jan 18, 2026

⚠️ No Changeset found

Latest commit: f59fa13

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

CLAassistant commented Jan 18, 2026

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 18, 2026

Walkthrough

This PR refactors multiple components and simplifies the data access layer. Changes include sidebar item guard logic, account profile form layout consolidation, a new skeleton loading component, MongoDB configuration adjustments, and a significant overhaul of the BaseRaw model API with removal of legacy methods and redesigned delete/trash handling.

Changes

Cohort / File(s) Summary
Sidebar and Form UI
apps/meteor/client/lib/createSidebarItems.ts, apps/meteor/client/views/account/profile/AccountProfileForm.tsx
Sidebar: Added index validation guard and replaced delete with splice for item removal. Profile form: Consolidated layout structure, removed redundant error renderings, added input trimming normalization, inlined validation rules, and simplified field grouping.
Loading Skeleton
apps/meteor/client/views/room/contextualBar/lib/ContextualListSkeleton.tsx
New React component providing a vertical skeleton loader with configurable item count (default 6), each row containing a square skeleton and text placeholders.
Server Configuration
apps/meteor/packages/rocketchat-mongo-config/server/index.js
Added error handling wrapper for MONGO_OPTIONS JSON parsing, introduced default retryWrites: false for connections without explicit retryWrites, and simplified TLS configuration.
Database Model Layer
packages/models/src/models/BaseRaw.ts
Significant API reduction: removed insertMany, insertOne, removeById/removeByIds, deleteOne, deleteMany, find, findPaginated, and update variants. Redesigned delete flow with integrated trash and rollback handling; added public col property; simplified findOne and countDocuments paths.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant BaseRaw
    participant PrimaryCollection as Primary<br/>Collection
    participant TrashCollection as Trash<br/>Collection
    participant Rollback as Error &<br/>Rollback

    Client->>BaseRaw: findOneAndDelete(query)
    BaseRaw->>PrimaryCollection: Check if trash exists
    
    alt Trash Enabled
        BaseRaw->>TrashCollection: Move record to trash
        BaseRaw->>PrimaryCollection: Delete from primary
        PrimaryCollection-->>BaseRaw: Success or Error
        
        alt Deletion Failed
            BaseRaw->>Rollback: Rollback triggered
            Rollback->>TrashCollection: Delete trash record
            Rollback-->>BaseRaw: Rollback error
            BaseRaw-->>Client: Original error
        else Success
            BaseRaw-->>Client: Deleted record
        end
    else No Trash
        BaseRaw->>PrimaryCollection: Direct delete
        PrimaryCollection-->>Client: Deleted record
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Poem

🐰 Hoppy refactoring hops along,
Sidebar guards now strong and long,
Forms grow sleek, deletion flows with grace,
Trash rolls back to find its place,
Rabbit cheers this cleaner space!

🚥 Pre-merge checks | ✅ 3
✅ 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 accurately describes the main change: trimming whitespace from account profile form fields to prevent false dirty state detection.
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
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.

3 issues found across 5 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="apps/meteor/packages/rocketchat-mongo-config/server/index.js">

<violation number="1" location="apps/meteor/packages/rocketchat-mongo-config/server/index.js:39">
P1: Logging raw MONGO_OPTIONS on parse error can leak TLS keys/credentials to logs</violation>
</file>

<file name="apps/meteor/client/views/account/profile/AccountProfileForm.tsx">

<violation number="1" location="apps/meteor/client/views/account/profile/AccountProfileForm.tsx:170">
P1: onChange trims input on every keystroke, stripping trailing spaces/newlines and preventing normal typing of multi-word or multi-line bios</violation>

<violation number="2" location="apps/meteor/client/views/account/profile/AccountProfileForm.tsx:266">
P1: Validation still blocks email submission, but error feedback was removed so users get no indication of what is wrong.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Object.assign(mongoConnectionOptions, mongoOptions);
} catch (error) {
console.error('Failed to parse MONGO_OPTIONS environment variable');
console.error('Provided value:', mongoOptionStr);
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Jan 18, 2026

Choose a reason for hiding this comment

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

P1: Logging raw MONGO_OPTIONS on parse error can leak TLS keys/credentials to logs

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/meteor/packages/rocketchat-mongo-config/server/index.js, line 39:

<comment>Logging raw MONGO_OPTIONS on parse error can leak TLS keys/credentials to logs</comment>

<file context>
@@ -22,28 +23,43 @@ const mongoConnectionOptions = {
+		Object.assign(mongoConnectionOptions, mongoOptions);
+	} catch (error) {
+		console.error('Failed to parse MONGO_OPTIONS environment variable');
+		console.error('Provided value:', mongoOptionStr);
+		console.error('Error:', error.message);
+		console.error('Please ensure MONGO_OPTIONS contains valid JSON');
</file context>
Suggested change
console.error('Provided value:', mongoOptionStr);
console.error('MONGO_OPTIONS is not valid JSON; value omitted for security');
Fix with Cubic

required: t('Required_field', { field: t('Email') }),
validate: { validateEmail: (email) => (validateEmail(email) ? undefined : t('error-invalid-email-address')) },
}}
rules={{ required: t('Required_field', { field: t('Email') }), validate: validateEmail }}
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Jan 18, 2026

Choose a reason for hiding this comment

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

P1: Validation still blocks email submission, but error feedback was removed so users get no indication of what is wrong.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/meteor/client/views/account/profile/AccountProfileForm.tsx, line 266:

<comment>Validation still blocks email submission, but error feedback was removed so users get no indication of what is wrong.</comment>

<file context>
@@ -303,69 +249,34 @@ const AccountProfileForm = (props: AllHTMLAttributes<HTMLFormElement>): ReactEle
-								required: t('Required_field', { field: t('Email') }),
-								validate: { validateEmail: (email) => (validateEmail(email) ? undefined : t('error-invalid-email-address')) },
-							}}
+							rules={{ required: t('Required_field', { field: t('Email') }), validate: validateEmail }}
 							render={({ field }) => (
 								<TextInput
</file context>
Fix with Cubic

<TextInput
{...field}
id={nameId}
onChange={(e) => field.onChange(e.target.value.trim())}
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Jan 18, 2026

Choose a reason for hiding this comment

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

P1: onChange trims input on every keystroke, stripping trailing spaces/newlines and preventing normal typing of multi-word or multi-line bios

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/meteor/client/views/account/profile/AccountProfileForm.tsx, line 170:

<comment>onChange trims input on every keystroke, stripping trailing spaces/newlines and preventing normal typing of multi-word or multi-line bios</comment>

<file context>
@@ -162,136 +154,90 @@ const AccountProfileForm = (props: AllHTMLAttributes<HTMLFormElement>): ReactEle
 									<TextInput
 										{...field}
 										id={nameId}
+										onChange={(e) => field.onChange(e.target.value.trim())}
 										error={errors.name?.message}
 										disabled={!allowRealNameChange}
</file context>
Fix with Cubic

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.

Actionable comments posted: 6

🤖 Fix all issues with AI agents
In `@apps/meteor/client/views/account/profile/AccountProfileForm.tsx`:
- Line 235: The TextInput currently trims on every keystroke via onChange={(e)
=> field.onChange(e.target.value.trim())}, which prevents entering spaces;
change this to remove the onChange trim and instead handle final trimming on
blur so multi-word nicknames work: replace the onChange prop with an onBlur
handler on the TextInput that calls field.onChange(e.target.value.trim()),
keeping the {...field} and id={nicknameId} intact.
- Line 252: The bio input is trimming on every keystroke via the onChange
handler (field.onChange(e.target.value.trim())), preventing spaces; change the
onChange to pass the raw value (field.onChange(e.target.value)) and move
trimming to the onBlur handler (call field.onChange(e.target.value.trim()) or
call field.onBlur with a trimmed value) so trimming happens only when the user
leaves the field; update the Bio input in AccountProfileForm.tsx to use the new
onBlur behavior and keep field.onChange for live typing.
- Around line 186-196: The username TextInput in AccountProfileForm.tsx is not
showing validation feedback; update the Controller render for the username field
to consume fieldState (render={({ field, fieldState }) => ...}) and pass the
validation error into the TextInput (e.g., error/message prop and an
invalid/hasError boolean) using fieldState.error?.message so required +
validateUsername errors surface to the user while preserving id=usernameId,
onChange trimming, and disabled={!canChangeUsername}.
- Line 211: In AccountProfileForm.tsx the status field currently trims input on
every onChange (the line using onChange={(e) =>
field.onChange(e.target.value.trim())}), causing spaces to be stripped
mid-typing; change this so onChange passes the raw value (e.g. onChange={(e) =>
field.onChange(e.target.value)}) and add an onBlur handler that applies trimming
(e.g. onBlur={(e) => field.onChange(e.target.value.trim())}) so trimming happens
only when the field loses focus; update the JSX for the same status field,
keeping references to field.onChange and adding the onBlur that calls
field.onChange with the trimmed value.
- Line 170: Remove the inline .trim() from the onChange handler so spaces can be
typed (change onChange={(e) => field.onChange(e.target.value.trim())} to simply
call field.onChange with the raw value), and add an onBlur handler that trims
the final value and updates the form (e.g., onBlur={(e) =>
field.onChange(e.target.value.trim())}); target the same field object used in
the form (field.onChange / field.onBlur) to ensure trimming happens only on blur
rather than every keystroke.
- Around line 266-276: The email and username form controls in
AccountProfileForm.tsx are validating but not showing errors; after the
Controller render for the email field (which uses validateEmail) and the
username field (which uses validateUsername), add FieldError components that
display the react-hook-form errors (e.g. errors.email?.message and
errors.username?.message) following the same pattern used elsewhere in the form
so validation messages from validateEmail and validateUsername are rendered to
the user.
🧹 Nitpick comments (1)
packages/models/src/models/BaseRaw.ts (1)

170-170: Remove debug comment markers.

The /* ===================== FIXED METHOD ===================== */ comment (and its closing marker on line 222) appear to be development artifacts. Either remove them or replace with meaningful documentation explaining the fix rationale.

Suggested removal
-	/* ===================== FIXED METHOD ===================== */
-
 	async findOneAndDelete(filter: Filter<T>, options?: FindOneAndDeleteOptions): Promise<WithId<T> | null> {

And at line 222:

-	/* ======================================================== */
-
 	private setUpdatedAt(record: UpdateFilter<T> | InsertionModel<T>): void {

<TextInput
{...field}
id={nameId}
onChange={(e) => field.onChange(e.target.value.trim())}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Trimming on every keystroke prevents typing multi-word values.

Calling .trim() inside onChange removes spaces immediately as the user types. This makes it impossible to enter values like "John Doe" — the space after "John" is stripped before the user can type "Doe".

To achieve the PR objective (ignore whitespace-only changes without breaking input), trim on blur instead:

🐛 Proposed fix: trim on blur instead of onChange
 								<TextInput
 									{...field}
 									id={nameId}
-									onChange={(e) => field.onChange(e.target.value.trim())}
+									onBlur={(e) => field.onChange(e.target.value.trim())}
 									error={errors.name?.message}
 									disabled={!allowRealNameChange}
 								/>
🤖 Prompt for AI Agents
In `@apps/meteor/client/views/account/profile/AccountProfileForm.tsx` at line 170,
Remove the inline .trim() from the onChange handler so spaces can be typed
(change onChange={(e) => field.onChange(e.target.value.trim())} to simply call
field.onChange with the raw value), and add an onBlur handler that trims the
final value and updates the form (e.g., onBlur={(e) =>
field.onChange(e.target.value.trim())}); target the same field object used in
the form (field.onChange / field.onBlur) to ensure trimming happens only on blur
rather than every keystroke.

Comment on lines 186 to 196
render={({ field }) => (
<TextInput
{...field}
id={usernameId}
onChange={(e) => field.onChange(e.target.value.trim())}
disabled={!canChangeUsername}
error={errors.username?.message}
addon={<Icon name='at' size='x20' />}
aria-required='true'
aria-invalid={errors.username ? 'true' : 'false'}
aria-describedby={`${usernameId}-error ${usernameId}-hint`}
/>
)}
/>
</FieldRow>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing error display for username validation.

The username field has validation rules (required + validateUsername) but doesn't pass the error to the TextInput. Users won't see validation feedback.

Proposed fix
 									<TextInput
 										{...field}
 										id={usernameId}
-										onChange={(e) => field.onChange(e.target.value.trim())}
+										onBlur={(e) => field.onChange(e.target.value.trim())}
+										error={errors.username?.message}
 										disabled={!canChangeUsername}
 										addon={<Icon name='at' size='x20' />}
 									/>
📝 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
render={({ field }) => (
<TextInput
{...field}
id={usernameId}
onChange={(e) => field.onChange(e.target.value.trim())}
disabled={!canChangeUsername}
error={errors.username?.message}
addon={<Icon name='at' size='x20' />}
aria-required='true'
aria-invalid={errors.username ? 'true' : 'false'}
aria-describedby={`${usernameId}-error ${usernameId}-hint`}
/>
)}
/>
</FieldRow>
render={({ field }) => (
<TextInput
{...field}
id={usernameId}
onBlur={(e) => field.onChange(e.target.value.trim())}
error={errors.username?.message}
disabled={!canChangeUsername}
addon={<Icon name='at' size='x20' />}
/>
)}
/>
</FieldRow>
🤖 Prompt for AI Agents
In `@apps/meteor/client/views/account/profile/AccountProfileForm.tsx` around lines
186 - 196, The username TextInput in AccountProfileForm.tsx is not showing
validation feedback; update the Controller render for the username field to
consume fieldState (render={({ field, fieldState }) => ...}) and pass the
validation error into the TextInput (e.g., error/message prop and an
invalid/hasError boolean) using fieldState.error?.message so required +
validateUsername errors surface to the user while preserving id=usernameId,
onChange trimming, and disabled={!canChangeUsername}.

{...field}
id={statusTextId}
error={errors?.statusText?.message}
onChange={(e) => field.onChange(e.target.value.trim())}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Same keystroke trimming issue affects status messages.

Users cannot type status messages like "Working from home" — spaces are removed on each keystroke. Apply the same onBlur fix here.

-									onChange={(e) => field.onChange(e.target.value.trim())}
+									onBlur={(e) => field.onChange(e.target.value.trim())}
📝 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
onChange={(e) => field.onChange(e.target.value.trim())}
onBlur={(e) => field.onChange(e.target.value.trim())}
🤖 Prompt for AI Agents
In `@apps/meteor/client/views/account/profile/AccountProfileForm.tsx` at line 211,
In AccountProfileForm.tsx the status field currently trims input on every
onChange (the line using onChange={(e) =>
field.onChange(e.target.value.trim())}), causing spaces to be stripped
mid-typing; change this so onChange passes the raw value (e.g. onChange={(e) =>
field.onChange(e.target.value)}) and add an onBlur handler that applies trimming
(e.g. onBlur={(e) => field.onChange(e.target.value.trim())}) so trimming happens
only when the field loses focus; update the JSX for the same status field,
keeping references to field.onChange and adding the onBlur that calls
field.onChange with the trimmed value.

name='nickname'
render={({ field }) => (
<TextInput {...field} id={nicknameId} flexGrow={1} addon={<Icon name='edit' size='x20' alignSelf='center' />} />
<TextInput {...field} id={nicknameId} onChange={(e) => field.onChange(e.target.value.trim())} />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Nickname field has the same trimming issue.

Apply onBlur instead of onChange for consistency and to allow multi-word nicknames.

🤖 Prompt for AI Agents
In `@apps/meteor/client/views/account/profile/AccountProfileForm.tsx` at line 235,
The TextInput currently trims on every keystroke via onChange={(e) =>
field.onChange(e.target.value.trim())}, which prevents entering spaces; change
this to remove the onChange trim and instead handle final trimming on blur so
multi-word nicknames work: replace the onChange prop with an onBlur handler on
the TextInput that calls field.onChange(e.target.value.trim()), keeping the
{...field} and id={nicknameId} intact.

{...field}
id={bioId}
error={errors.bio?.message}
onChange={(e) => field.onChange(e.target.value.trim())}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Bio field is most affected — users cannot type any spaces.

A bio is freeform text that naturally contains spaces. Trimming on every keystroke completely breaks this field. Use onBlur to trim only when the user leaves the field.

-								onChange={(e) => field.onChange(e.target.value.trim())}
+								onBlur={(e) => field.onChange(e.target.value.trim())}
📝 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
onChange={(e) => field.onChange(e.target.value.trim())}
onBlur={(e) => field.onChange(e.target.value.trim())}
🤖 Prompt for AI Agents
In `@apps/meteor/client/views/account/profile/AccountProfileForm.tsx` at line 252,
The bio input is trimming on every keystroke via the onChange handler
(field.onChange(e.target.value.trim())), preventing spaces; change the onChange
to pass the raw value (field.onChange(e.target.value)) and move trimming to the
onBlur handler (call field.onChange(e.target.value.trim()) or call field.onBlur
with a trimmed value) so trimming happens only when the user leaves the field;
update the Bio input in AccountProfileForm.tsx to use the new onBlur behavior
and keep field.onChange for live typing.

Comment on lines +266 to 276
rules={{ required: t('Required_field', { field: t('Email') }), validate: validateEmail }}
render={({ field }) => (
<TextInput
{...field}
id={emailId}
flexGrow={1}
error={errors.email?.message}
addon={<Icon name={isUserVerified ? 'circle-check' : 'mail'} size='x20' />}
onChange={(e) => field.onChange(e.target.value.trim())}
disabled={!allowEmailChange}
aria-required='true'
aria-invalid={errors.email ? 'true' : 'false'}
aria-describedby={`${emailId}-error ${emailId}-hint`}
addon={<Icon name={isUserVerified ? 'circle-check' : 'mail'} size='x20' />}
/>
)}
/>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the full context of the AccountProfileForm.tsx file
cat -n apps/meteor/client/views/account/profile/AccountProfileForm.tsx | head -300 | tail -100

Repository: RocketChat/Rocket.Chat

Length of output: 3560


🏁 Script executed:

# Check for validateEmail implementation
rg "validateEmail" -A 10 --type ts --type tsx

Repository: RocketChat/Rocket.Chat

Length of output: 93


🏁 Script executed:

# Search for validateEmail without type restriction
rg "export.*validateEmail"

Repository: RocketChat/Rocket.Chat

Length of output: 724


🏁 Script executed:

# Also search for where validateEmail is imported from
rg "import.*validateEmail" apps/meteor/client/views/account/profile/

Repository: RocketChat/Rocket.Chat

Length of output: 181


🏁 Script executed:

# Check the TextInput component to see if it handles errors
fd -name "TextInput*" -type f | head -10

Repository: RocketChat/Rocket.Chat

Length of output: 296


🏁 Script executed:

# Get the full validateEmail implementation
cat packages/tools/src/validateEmail.ts

Repository: RocketChat/Rocket.Chat

Length of output: 527


🏁 Script executed:

# Check the TextInput component
fd "TextInput" -type f | grep -E "\.(tsx|ts)$" | head -5

Repository: RocketChat/Rocket.Chat

Length of output: 236


🏁 Script executed:

# Search for how Controller passes errors in this form
rg "fieldState|errors\[" apps/meteor/client/views/account/profile/AccountProfileForm.tsx

Repository: RocketChat/Rocket.Chat

Length of output: 48


🏁 Script executed:

# Find TextInput component
fd "TextInput" --type f

Repository: RocketChat/Rocket.Chat

Length of output: 259


🏁 Script executed:

# Search for how formState or errors are accessed in the form
rg "formState|fieldState|\.errors" apps/meteor/client/views/account/profile/AccountProfileForm.tsx -A 2 -B 2

Repository: RocketChat/Rocket.Chat

Length of output: 165


🏁 Script executed:

# Read the complete email field section and see if errors are passed
cat -n apps/meteor/client/views/account/profile/AccountProfileForm.tsx | sed -n '260,278p'

Repository: RocketChat/Rocket.Chat

Length of output: 797


🏁 Script executed:

# Search for how TextInput is used in other fields with validation
rg "TextInput" apps/meteor/client/views/account/profile/AccountProfileForm.tsx -B 5 -A 3

Repository: RocketChat/Rocket.Chat

Length of output: 1767


🏁 Script executed:

# Find the TextInput component definition
cat apps/meteor/client/views/omnichannel/additionalForms/EeTextInput.tsx | head -50

Repository: RocketChat/Rocket.Chat

Length of output: 657


🏁 Script executed:

# Check how errors are displayed in the form - look for FieldError usage
rg "FieldError" apps/meteor/client/views/account/profile/AccountProfileForm.tsx -B 3 -A 1

Repository: RocketChat/Rocket.Chat

Length of output: 127


🏁 Script executed:

# Let's also check the render prop signature to see if fieldState is available
rg "render=.*fieldState" apps/meteor/client/views/account/profile/AccountProfileForm.tsx

Repository: RocketChat/Rocket.Chat

Length of output: 48


🏁 Script executed:

# Check if validateUsername has the same issue (it also uses validate)
rg "validateUsername" -A 10 packages/tools/src/ | head -30

Repository: RocketChat/Rocket.Chat

Length of output: 48


🏁 Script executed:

# Let's check if other fields with validate function use error display
rg "validate:" apps/meteor/client/views/account/profile/AccountProfileForm.tsx -B 8 -A 8

Repository: RocketChat/Rocket.Chat

Length of output: 1193


🏁 Script executed:

# Search for how FieldError is being used elsewhere in the codebase
rg "FieldError" apps/meteor/client/views/account/ -B 3 -A 1 | head -40

Repository: RocketChat/Rocket.Chat

Length of output: 3753


🏁 Script executed:

# Check if react-hook-form's validate prop accepts boolean returns
web_search
What does react-hook-form validate return type expect - boolean vs string error message

Repository: RocketChat/Rocket.Chat

Length of output: 159


🌐 Web query:

react-hook-form validate function return type boolean vs error message

💡 Result:

Short answer: React Hook Form's validate function may return boolean (true = valid, false = invalid) or a string (treated as the field's error message). It also supports returning a Promise resolving to boolean or string. Use boolean when you only need pass/fail; return a string when you want a custom error message shown. [1][2]

Notes:

  • When shouldUseNativeValidation is enabled, validation messages must be strings for native browser display. [2]
  • You can also set errors manually (with message) via setError. [3]

Examples:

  • Simple boolean: validate: value => value.length > 3
  • Message: validate: value => value.length > 3 || "Must be longer than 3 characters"
  • Async: validate: async value => (await check(value)) ? true : "Already taken"

Sources:
[1] React Hook Form — register / validate docs.
[2] React Hook Form — useForm (shouldUseNativeValidation).
[3] React Hook Form — setError API.


🏁 Script executed:

# Let's check validateUsername to see if it has the same issue
rg "validateUsername" -B 5 -A 15 --max-count=1

Repository: RocketChat/Rocket.Chat

Length of output: 13694


🏁 Script executed:

# Check if there's any form submission handling or error checking for email
rg "email.*error\|error.*email" apps/meteor/client/views/account/profile/AccountProfileForm.tsx -i

Repository: RocketChat/Rocket.Chat

Length of output: 48


Add error display for email and username validation.

The email field has validation rules but doesn't render validation errors to the user. While validateEmail from @rocket.chat/tools returns boolean (which is valid for react-hook-form's validate), the field lacks a FieldError component to display validation failures. Additionally, validateUsername returns error strings but also doesn't display errors. Both should follow the pattern used elsewhere in the account forms by rendering {errors.fieldName && <FieldError>{errors.fieldName.message}</FieldError>} after the field.

🤖 Prompt for AI Agents
In `@apps/meteor/client/views/account/profile/AccountProfileForm.tsx` around lines
266 - 276, The email and username form controls in AccountProfileForm.tsx are
validating but not showing errors; after the Controller render for the email
field (which uses validateEmail) and the username field (which uses
validateUsername), add FieldError components that display the react-hook-form
errors (e.g. errors.email?.message and errors.username?.message) following the
same pattern used elsewhere in the form so validation messages from
validateEmail and validateUsername are rendered to the user.

@MartinSchoeler
Copy link
Copy Markdown
Member

Apart from the unrelated changes, this is a duplicate of #38244

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.

3 participants