refactor(ui): adopt react-hook-form for account & settings forms#6618
refactor(ui): adopt react-hook-form for account & settings forms#6618luannmoreira wants to merge 2 commits into
Conversation
Continues the incremental react-hook-form migration (shellhub-io/team#152) after the SignUp pilot, converting the account & settings forms: the Profile edit and change-password drawers, the Settings rename-namespace drawer, and the admin SAML configuration drawer. Each form reuses the shared RHF field wrappers and a per-form resolver adapter over the existing validators. Adds a FormTextareaField wrapper for the SAML certificate field. Validation UX is preserved (errors surface only once a field diverges from its saved value), including the recovery-email cross-field rule, the changed-fields-only profile payload, and the SAML metadata/manual mode semantics. Form-level server errors now use RHF root errors, and reset-on-open keeps drawer-local UI state in sync via useResetOnOpen. The previously untested SAML drawer gains coverage for its mode toggle, per-mode required-field gating, and submit payloads.
|
Claude finished @luannmoreira's task in 7m 59s —— View job Code Review CompleteReviewed 17 files across code quality, security, testing, language patterns, and architecture. 1 inline issue posted (1 high). The migration itself is clean: The one real finding is a validation regression in If you've addressed the feedback and want a new review, tag |
Validate name/username/email unconditionally in editProfileResolver so a cleared required field surfaces its "… is required" error and blocks Save, instead of silently submitting a blank value. recoveryEmail stays optional. Also drop an unnecessary type assertion in Profile.test.tsx that failed the console lint step.
|
Superseded by #6619, which reorganizes this work into the umbrella react-hook-form migration PR (team#152) with one commit per topic (Profile, Settings, SAML config). Same diff; continuing there. |
What
Migrates the Account & settings form group to react-hook-form: the Profile
edit and change-password drawers, the Settings rename-namespace drawer, and the
admin SAML configuration drawer. Next step of the incremental migration tracked
in shellhub-io/team#152, following the SignUp and auth-form migrations.
Why
Each of these forms hand-threaded
useState+onChange+ per-field errorcomputation. Reusing the established RHF field wrappers and resolver-adapter
pattern removes that boilerplate and gives the SAML drawer real validation
structure and its first tests.
Changes
useController-bound wrapper over a raw<textarea>(INPUT styling +classNameoverride,aria-invalid/aria-describedby), for the SAML certificate field. Joins the existing threewrappers.
EditProfileDrawerandChangePasswordDrawermoved touseFormwith per-form resolvers (
editProfileResolver,changePasswordResolver)reusing the existing validators (relocated into
pages/profile/validate.tsunchanged, preserving messages). Recovery-email remains a cross-field rule —
changing the primary email re-triggers it via
trigger("recoveryEmail"). Theprofile payload is still built from changed fields only (
dirtyFields).EditNameDrawerbound viauseControllerover the existingNamespaceNameField, delegating tovalidateNamespaceName(wrapped?? trueso a valid name is not treated as invalid).
SamlConfigDrawermoved touseFormwithsamlResolverreplicatingthe metadata-URL-vs-manual conditional rules;
useWatchdrives the mode UI andbuildBodywas refactored to a pure function of the form values.saved value; empty required fields gate the submit button rather than showing an
error. Form-level server errors use RHF
rooterrors; drawer-local UI state(SAML
showAdvanced, change-passwordsuccess) resets on open viauseResetOnOpen.and device-auto-accept toggles, the delete-confirm and leave dialogs, and the
Profile delete-account dialogs.
Testing
vitestin theuicontainer — full console suite green (2701 tests). Newcoverage:
FormTextareaField, the three resolvers, and the previously-untestedSamlConfigDrawer(metadata to manual toggle, per-mode required-field gating, andthe submit payload for both modes). Worth probing: the recovery-email cross-field
path (change only the primary email and confirm the recovery-email error appears)
and that prefilled edit drawers show no error until a field is changed.