Skip to content

refactor(platform): real-time form validation and legacy integration cleanup#1409

Merged
Israeltheminer merged 3 commits into
mainfrom
refactor/form-validation-and-integration-cleanup
Apr 11, 2026
Merged

refactor(platform): real-time form validation and legacy integration cleanup#1409
Israeltheminer merged 3 commits into
mainfrom
refactor/form-validation-and-integration-cleanup

Conversation

@Israeltheminer

@Israeltheminer Israeltheminer commented Apr 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add isValid prop to FormDialog and enable onChange validation mode across all settings forms (account, branding, API keys, teams, members, providers) to disable submit buttons when validation fails
  • Remove 6 legacy per-integration dialog components (circuly, protel, shopify connect/disconnect dialogs) now replaced by the generic integration-manage flow
  • Fix integration credential/config labels to use startCase formatting
  • Make branding appName required with inline validation error
  • Fix conversations empty state integrations link to use ?tab=all
  • Add configuration i18n key for integration manage dialog (en + de)

Test plan

  • Verify submit buttons are disabled when form fields have validation errors across all settings dialogs
  • Verify submit buttons re-enable when validation passes
  • Confirm no regressions in integration manage flow (circuly, protel, shopify still work via generic dialog)
  • Confirm branding form rejects empty appName
  • Verify credential/config labels in integration manage show human-readable labels

Summary by CodeRabbit

  • New Features

    • Forms now validate in real-time as you type, with submit buttons automatically disabling based on validation status.
  • Improvements

    • Enhanced form validation feedback across account settings, API keys, branding, organizations, teams, and integrations dialogs.
    • Improved credential field labeling in integration settings for better clarity.
  • Changes

    • App name field in branding settings is now required with validation.
    • Removed legacy integration dialogs for streamlined settings experience.
  • Localization

    • Added "Configuration" label translations.

… integration dialogs

Add isValid prop to FormDialog and wire up onChange validation across all
settings forms to disable submit buttons when validation fails. Remove
legacy per-integration dialog components (circuly, protel, shopify) now
replaced by the generic integration-manage flow. Also fix integration
credential labels to use startCase formatting, make branding appName
required, and update integrations tab link.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

Use exact: false in getByLabelText queries since the required prop
adds an aria-label asterisk to the label text.
@coderabbitai

coderabbitai Bot commented Apr 11, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR extends the FormDialog component with form validation state support by introducing an optional isValid prop that tracks the validation status of forms. Multiple form dialogs across settings, organization, and team management features are updated to enable real-time validation through mode: 'onChange' configuration, extract the validation state from react-hook-form's formState.isValid, and pass this state to FormDialog for submit button control. Additionally, three large integration-specific dialog components for Circuly, Protel, and Shopify are removed, credential input labels are formatted using startCase for consistency, the branding schema is updated to require the appName field, and localization entries for "Configuration" are added.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the two main changes: real-time form validation enhancements and removal of legacy integration components.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/form-validation-and-integration-cleanup

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@services/platform/app/features/settings/branding/components/branding-form.tsx`:
- Line 203: The form currently passes raw validator text to the UI via
errorMessage={formState.errors.appName?.message}; instead, map validation types
to translation keys and pass a localized message (e.g. use the i18n hook t) —
read formState.errors.appName?.type (or code from your resolver) in the
BrandingForm component and convert it to t('settings.branding.errors.required')
/ t('settings.branding.errors.tooLong') etc., then supply that localized string
to the errorMessage prop; update any helper functions in branding-form.tsx that
build validation output to return a translation key or resolved t(...) string
rather than the raw resolver message.

In
`@services/platform/app/features/settings/integrations/components/integration-manage/integration-credentials-form.tsx`:
- Line 234: The label currently uses startCase(binding) directly (see
label={startCase(binding)} in IntegrationCredentialsForm) which bypasses i18n;
change it to resolve a translation key first (e.g., call the component's
translation hook/function to look up something like
"integration.fields.{binding}" with a defaultValue/fallback of
startCase(binding)) and replace both occurrences (the label prop at
startCase(binding) and the similar occurrence around line 253) so the UI shows
localized text while falling back to startCase for missing keys.

In
`@services/platform/app/features/settings/organization/components/member-edit-dialog.tsx`:
- Around line 146-147: The submit button should not be disabled solely because
formState.isValid is false; update the submit gating in MemberEditDialog
(member-edit-dialog.tsx) to allow submission while still preventing duplicate
requests via isSubmitting, and ensure all validation errors are surfaced inline:
render field-level error messages for displayName and other fields, add
aria-invalid on invalid inputs and role="alert" on error message elements, and
remove or relax the isValid check from the submit disabled condition so users
can see and correct errors instead of hitting a dead-end.

In `@services/platform/lib/shared/schemas/branding.ts`:
- Line 24: brandingJsonSchema currently allows appName to be omitted while the
form schema makes appName required; update the persisted schema
(brandingJsonSchema) to require appName (match z.string().min(1).max(100)
semantics used in the form) so there is no schema drift between the form and
persisted data, and add a small backfill/migration to normalize legacy records
where appName is undefined or empty string (set to a sane default or
reject/notify) before enabling the stricter validation; reference the
brandingJsonSchema and the appName field when making these changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d267c25c-ef4e-4ba1-8f22-9173c73b3b35

📥 Commits

Reviewing files that changed from the base of the PR and between 2d1eeae and abd78b9.

📒 Files selected for processing (20)
  • services/platform/app/components/ui/dialog/form-dialog.tsx
  • services/platform/app/features/conversations/components/activate-conversations-empty-state.tsx
  • services/platform/app/features/settings/account/components/account-form.tsx
  • services/platform/app/features/settings/api-keys/components/api-key-create-dialog.tsx
  • services/platform/app/features/settings/branding/components/branding-form.tsx
  • services/platform/app/features/settings/integrations/components/circuly-disconnect-confirmation-dialog.tsx
  • services/platform/app/features/settings/integrations/components/circuly-integration-dialog.tsx
  • services/platform/app/features/settings/integrations/components/integration-manage/integration-credentials-form.tsx
  • services/platform/app/features/settings/integrations/components/protel-disconnect-confirmation-dialog.tsx
  • services/platform/app/features/settings/integrations/components/protel-integration-dialog.tsx
  • services/platform/app/features/settings/integrations/components/shopify-disconnect-confirmation-dialog.tsx
  • services/platform/app/features/settings/integrations/components/shopify-integration-dialog.tsx
  • services/platform/app/features/settings/organization/components/member-add-dialog.tsx
  • services/platform/app/features/settings/organization/components/member-edit-dialog.tsx
  • services/platform/app/features/settings/providers/components/provider-add-dialog.tsx
  • services/platform/app/features/settings/teams/components/team-create-dialog.tsx
  • services/platform/app/features/settings/teams/components/team-edit-dialog.tsx
  • services/platform/lib/shared/schemas/branding.ts
  • services/platform/messages/de.json
  • services/platform/messages/en.json
💤 Files with no reviewable changes (6)
  • services/platform/app/features/settings/integrations/components/shopify-disconnect-confirmation-dialog.tsx
  • services/platform/app/features/settings/integrations/components/protel-disconnect-confirmation-dialog.tsx
  • services/platform/app/features/settings/integrations/components/shopify-integration-dialog.tsx
  • services/platform/app/features/settings/integrations/components/protel-integration-dialog.tsx
  • services/platform/app/features/settings/integrations/components/circuly-disconnect-confirmation-dialog.tsx
  • services/platform/app/features/settings/integrations/components/circuly-integration-dialog.tsx

label={t('branding.appName')}
placeholder={t('branding.appNamePlaceholder')}
required
errorMessage={formState.errors.appName?.message}

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 | 🟠 Major

Avoid rendering raw validator messages directly

Line 203 displays resolver text directly, which can leak non-localized/default English validation text to users. Prefer a translation key-driven message.

Suggested fix
-            errorMessage={formState.errors.appName?.message}
+            errorMessage={
+              formState.errors.appName
+                ? t('branding.validation.appNameRequired')
+                : undefined
+            }

As per coding guidelines: "Do NOT hardcode text, use the translation hooks/functions instead for user-facing UI".

📝 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
errorMessage={formState.errors.appName?.message}
errorMessage={
formState.errors.appName
? t('branding.validation.appNameRequired')
: undefined
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@services/platform/app/features/settings/branding/components/branding-form.tsx`
at line 203, The form currently passes raw validator text to the UI via
errorMessage={formState.errors.appName?.message}; instead, map validation types
to translation keys and pass a localized message (e.g. use the i18n hook t) —
read formState.errors.appName?.type (or code from your resolver) in the
BrandingForm component and convert it to t('settings.branding.errors.required')
/ t('settings.branding.errors.tooLong') etc., then supply that localized string
to the errorMessage prop; update any helper functions in branding-form.tsx that
build validation output to return a translation key or resolved t(...) string
rather than the raw resolver message.

key={binding}
id={`manage-credential-${binding}`}
label={binding}
label={startCase(binding)}

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 | 🟠 Major

Localize dynamic field labels instead of rendering raw startCase text.

Using startCase(...) directly for visible form labels bypasses i18n and will surface English-like labels in localized UIs. Resolve labels via translation keys first, with startCase only as a fallback.

Proposed fix
-              label={startCase(binding)}
+              label={
+                t(`integrations.dynamicFields.${binding}` as never, {
+                  defaultValue: startCase(binding),
+                })
+              }
...
-                label={startCase(field.key)}
+                label={
+                  t(`integrations.dynamicFields.${field.key}` as never, {
+                    defaultValue: startCase(field.key),
+                  })
+                }
As per coding guidelines, user-facing UI text in TSX must use translation hooks/functions rather than hardcoded/generated strings.

Also applies to: 253-253

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

In
`@services/platform/app/features/settings/integrations/components/integration-manage/integration-credentials-form.tsx`
at line 234, The label currently uses startCase(binding) directly (see
label={startCase(binding)} in IntegrationCredentialsForm) which bypasses i18n;
change it to resolve a translation key first (e.g., call the component's
translation hook/function to look up something like
"integration.fields.{binding}" with a defaultValue/fallback of
startCase(binding)) and replace both occurrences (the label prop at
startCase(binding) and the similar occurrence around line 253) so the UI shows
localized text while falling back to startCase for missing keys.

Comment thread services/platform/lib/shared/schemas/branding.ts
Replace raw validator message with translated error message per i18n
coding standards.
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.

1 participant