Skip to content

feat(admin): adding uniformity in cancel and back buttons present in SCIM & Jans Lock#2408

Closed
faisalsiddique4400 wants to merge 32 commits intomainfrom
admin-ui-issue-2361-scim
Closed

feat(admin): adding uniformity in cancel and back buttons present in SCIM & Jans Lock#2408
faisalsiddique4400 wants to merge 32 commits intomainfrom
admin-ui-issue-2361-scim

Conversation

@faisalsiddique4400
Copy link
Contributor

@faisalsiddique4400 faisalsiddique4400 commented Nov 3, 2025

feat(admin): adding uniformity in cancel and back buttons present in SCIM & Jank Lock

Summary

This update introduces consistent behavior for Cancel, Back, and Apply buttons across Admin UI forms, including correct enabling and disabling based on form state.

Improvements

Button Updated Behavior
Cancel Resets all fields to their previous values without navigating away. Disabled until a change is made.
Back Navigates to the previous page. If there is no navigation history, returns to Dashboard. Always enabled.
Apply Saves the changes without leaving the page. Enabled only when the form has unsaved changes.

Additional Enhancements

  • Buttons now correctly detect dirty form states.
  • Apply button is dynamically enabled and disabled based on whether changes exist.
  • Cancel button is disabled until a field is modified.
  • Prevents accidental navigation or state loss in multi step configuration pages.

Affected Modules

This change is applied across all forms where configuration changes are possible, including but not limited to:

  • SCIM
  • Jans Lock

Parent issue: #2268

Testing Steps

  1. Open suggested config form.
  2. Modify any field.
  3. Verify that:
    • Apply and Cancel buttons become enabled.
    • Apply saves configuration and stays on page.
    • Cancel reverts values and disables itself afterward.
  4. Back button should navigate appropriately.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added back navigation support with translated "Back" labels across all supported languages.
    • Introduced improved form footer component with configurable Back, Cancel, and Apply actions.
    • Enhanced form state tracking for detecting unsaved changes.
  • Bug Fixes

    • Improved property field preservation during data transformation.
    • Enhanced component label handling with dynamic configuration support.
  • Improvements

    • Added visual loading indicators during form submissions for better user feedback.

faisalsiddique4400 and others added 30 commits October 30, 2025 13:55
…Jans Lock (#2405)

* feat(admin): adding uniformity in cancel and back buttons present in Jans Lock

* feat(admin): adding uniformity in cancel and back buttons present in Jans Lock

* Code Rabbit fixes
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 3, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

This pull request introduces multi-language translation strings for a "back" action, adds utility functions for form and storage management, creates a new form footer component with configurable action buttons, and refactors existing form components to integrate enhanced form state tracking and submission handling across the admin UI.

Changes

Cohort / File(s) Summary
Translation Files
admin-ui/app/locales/{en,es,fr,pt}/translation.json
Added "back" action translation keys across English, Spanish, French, and Portuguese locales (values: "Back", "Atrás", "Retour", "Voltar").
Utility Function Enhancements
admin-ui/app/utils/Util.ts
Relaxed generic constraint in trimObjectStrings from Record<string, unknown> to object; updated mapPropertyToKeyValue to use nullish coalescing for key/value extraction and trim results.
New Form Utilities
admin-ui/app/utils/formUtils.ts
Added two utility functions: isObjectEqual for shallow/deep object equality checks and hasFormChanges to detect form data modifications with key exclusion support.
New Storage Utilities
admin-ui/app/utils/storageUtils.ts
Introduced new module with typed localStorage interface: getStorageItem, setStorageItem, removeStorageItem and convenience getters (getStorageNumber, getStorageBoolean, getStorageJSON, setStorageJSON) with error handling.
Gluu Component Enhancements
admin-ui/app/routes/Apps/Gluu/GluuProperties.tsx, admin-ui/app/routes/Apps/Gluu/GluuTypeAhead.tsx
GluuProperties: changed removeProperty to use Array.splice instead of delete+filter. GluuTypeAhead: expanded labelKey prop to accept function ((option: Option) => string), improved value extraction logic, and tightened dependency tracking.
New Form Footer Component
admin-ui/app/routes/Apps/Gluu/GluuFormFooter.tsx
New memoized React component with configurable Back/Cancel/Apply buttons, dynamic layout calculation, i18n support, loading states, and navigation/callback handling.
Jans Lock Configuration Updates
admin-ui/plugins/jans-lock/components/JansLock.tsx, admin-ui/plugins/jans-lock/components/JansLockConfiguration.tsx
Added isSubmitting prop propagation. JansLockConfiguration: replaced GluuCommitFooter with GluuFormFooter, introduced useMemo-based trimmedValuesAndPatches and isFormDirty derivations, refactored submission to use precomputed patches.
Jans Lock Patch Logic
admin-ui/plugins/jans-lock/helper/utils.ts
Added guards in patch add-branch to skip empty arrays and empty objects when a field is not present in original config.
Custom Script Form Update
admin-ui/plugins/admin/components/CustomScripts/CustomScriptForm.tsx
Updated transformPropertyForApi to preserve optional hide and description fields from input properties; added type assertions when assigning results.
SCIM Plugin Refactoring
admin-ui/plugins/scim/components/ScimConfiguration.tsx
Replaced GluuCommitFooter with GluuFormFooter; introduced useMemo for isFormDirty (via createJsonPatchFromDifferences) and isFormValid (via new schema validation); updated validation schema source; enhanced cancel behavior with stable callback.
SCIM Schema & Exports
admin-ui/plugins/scim/helper/schema.ts, admin-ui/plugins/scim/helper/index.ts
Renamed exported schema from scimConfigurationValidationSchema to scimConfigurationSchema; removed validation wrapper and simplified URL validation logic; added re-export of schema module in helper index.

Sequence Diagram

sequenceDiagram
    participant User
    participant JansLockConfiguration
    participant GluuFormFooter
    participant formik as Formik
    participant API as patchMutation

    User->>JansLockConfiguration: Render form (isSubmitting prop)
    JansLockConfiguration->>JansLockConfiguration: useMemo: compute trimmedValuesAndPatches<br/>(trimmed values + patch ops)
    JansLockConfiguration->>JansLockConfiguration: Derive isFormDirty, isFormValid
    JansLockConfiguration->>GluuFormFooter: Render footer<br/>(showBack, showCancel, showApply,<br/>isLoading=isSubmitting)
    
    alt User clicks Apply
        User->>GluuFormFooter: Click Apply button
        GluuFormFooter->>JansLockConfiguration: onApply callback
        JansLockConfiguration->>formik: submitForm()
        JansLockConfiguration->>JansLockConfiguration: Submission flow using<br/>precomputed patches
        JansLockConfiguration->>API: Send PATCH request
        API-->>JansLockConfiguration: Response (isPending=true during)
        JansLockConfiguration->>JansLockConfiguration: Update isSubmitting state
        GluuFormFooter->>GluuFormFooter: Display loading in buttons
    else User clicks Cancel
        User->>GluuFormFooter: Click Cancel button
        GluuFormFooter->>JansLockConfiguration: onCancel callback
        JansLockConfiguration->>formik: Reset form
    else User clicks Back
        User->>GluuFormFooter: Click Back button
        GluuFormFooter->>GluuFormFooter: Navigate to /home/dashboard
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • JansLockConfiguration refactoring: Memoization of patch operations and form state derivations introduces new control flow that requires careful verification of dependency arrays and correctness of precomputed patches.
  • New storage utilities module: Multiple typed wrapper functions with error handling require review of type safety and fallback logic across all convenience getters.
  • GluuFormFooter component creation: New component with complex conditional rendering, layout logic, navigation, and loading state handling requires thorough review of edge cases and button visibility combinations.
  • ScimConfiguration form state updates: Integration of form dirty/valid checks and footer replacement mirrors JansLockConfiguration changes; verify schema validation consistency and form reset behavior.
  • Util.ts and formUtils.ts changes: New equality and change detection functions should be validated against expected comparison semantics (shallow vs. deep).

Possibly related PRs

Suggested reviewers

  • syntrydy
  • duttarnab

Poem

🐰 A footer emerges, with buttons so fine,
Back, Cancel, Apply—in perfect alignment!
Form patches computed, states tracked with care,
Storage utilities bundled, for data to share.
The admin-ui hops forward with grace.

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly and specifically describes the main objective of the changeset: introducing uniformity in cancel and back buttons across SCIM and Jans Lock configurations. The title directly relates to the core changes visible in the raw summary, which include replacing GluuCommitFooter with a new GluuFormFooter component and updating button behavior in both JansLockConfiguration and ScimConfiguration. The title is concise, specific, and accurately summarizes the primary change without being vague or overly broad.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 00b2d45 and b9dad66.

📒 Files selected for processing (1)
  • admin-ui/app/routes/Apps/Gluu/GluuFormFooter.tsx (1 hunks)

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

@mo-auto mo-auto added comp-admin-ui Component affected by issue or PR kind-feature Issue or PR is a new feature request labels Nov 3, 2025
Signed-off-by: Faisal Siddique <71010439+faisalsiddique4400@users.noreply.github.com>
@sonarqubecloud
Copy link

sonarqubecloud bot commented Nov 3, 2025

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
admin-ui/app/routes/Apps/Gluu/GluuTypeAhead.tsx (1)

81-93: Fix dependency array for handleChange callback.

The dependency formik?.setFieldValue is problematic in a dependency array. Optional chaining doesn't work as expected in React dependencies—React compares the expression reference, not the resolved value. If formik changes identity but setFieldValue remains the same, the callback may not update correctly.

Apply this diff:

   const handleChange = useCallback(
     (selected: Option[]) => {
       if (formik) {
         formik.setFieldValue(name, selected)
         if (onChange) {
           onChange(selected)
         }
       } else if (onChange) {
         onChange(selected)
       }
     },
-    [formik?.setFieldValue, name, onChange],
+    [formik, name, onChange],
   )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1c3cc6b and 00b2d45.

📒 Files selected for processing (17)
  • admin-ui/app/locales/en/translation.json (1 hunks)
  • admin-ui/app/locales/es/translation.json (1 hunks)
  • admin-ui/app/locales/fr/translation.json (1 hunks)
  • admin-ui/app/locales/pt/translation.json (1 hunks)
  • admin-ui/app/routes/Apps/Gluu/GluuProperties.tsx (1 hunks)
  • admin-ui/app/routes/Apps/Gluu/GluuTypeAhead.tsx (3 hunks)
  • admin-ui/app/routes/Apps/Gluu/Gluuformfooter.tsx (1 hunks)
  • admin-ui/app/utils/Util.ts (2 hunks)
  • admin-ui/app/utils/formUtils.ts (1 hunks)
  • admin-ui/app/utils/storageUtils.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptForm.tsx (2 hunks)
  • admin-ui/plugins/jans-lock/components/JansLock.tsx (1 hunks)
  • admin-ui/plugins/jans-lock/components/JansLockConfiguration.tsx (6 hunks)
  • admin-ui/plugins/jans-lock/helper/utils.ts (1 hunks)
  • admin-ui/plugins/scim/components/ScimConfiguration.tsx (4 hunks)
  • admin-ui/plugins/scim/helper/index.ts (1 hunks)
  • admin-ui/plugins/scim/helper/schema.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2404
File: admin-ui/app/routes/Apps/Gluu/Gluuformfooter.tsx:70-77
Timestamp: 2025-11-03T08:47:33.926Z
Learning: In the admin-ui forms (Gluuformfooter component), the Back button should always navigate to '/home/dashboard' rather than using history-based navigation (navigate(-1)), as clarified by faisalsiddique4400 in PR #2404.
📚 Learning: 2025-11-03T08:47:33.926Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2404
File: admin-ui/app/routes/Apps/Gluu/Gluuformfooter.tsx:70-77
Timestamp: 2025-11-03T08:47:33.926Z
Learning: In the admin-ui forms (Gluuformfooter component), the Back button should always navigate to '/home/dashboard' rather than using history-based navigation (navigate(-1)), as clarified by faisalsiddique4400 in PR #2404.

Applied to files:

  • admin-ui/app/routes/Apps/Gluu/Gluuformfooter.tsx
🧬 Code graph analysis (5)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptForm.tsx (3)
admin-ui/plugins/admin/redux/features/types/customScript.ts (2)
  • ModuleProperty (3-8)
  • ConfigurationProperty (10-16)
admin-ui/plugins/admin/components/CustomScripts/types/customScript.ts (2)
  • ModuleProperty (3-10)
  • ConfigurationProperty (12-18)
admin-ui/app/utils/Util.ts (1)
  • filterEmptyObjects (82-84)
admin-ui/plugins/jans-lock/components/JansLockConfiguration.tsx (4)
admin-ui/plugins/jans-lock/types/jans-lock-types.ts (2)
  • JansLockConfigFormValues (4-26)
  • PatchOperation (38-38)
admin-ui/app/utils/Util.ts (1)
  • trimObjectStrings (66-80)
admin-ui/plugins/jans-lock/helper/utils.ts (1)
  • createPatchOperations (62-126)
admin-ui/plugins/jans-lock/helper/validations.ts (1)
  • validationSchema (3-16)
admin-ui/app/routes/Apps/Gluu/Gluuformfooter.tsx (1)
admin-ui/plugins/user-management/types/CommonTypes.ts (1)
  • ThemeContext (13-17)
admin-ui/app/routes/Apps/Gluu/GluuProperties.tsx (1)
admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js (1)
  • properties (45-45)
admin-ui/plugins/scim/components/ScimConfiguration.tsx (3)
admin-ui/plugins/scim/helper/schema.ts (1)
  • scimConfigurationSchema (14-61)
admin-ui/plugins/scim/helper/utils.ts (1)
  • createJsonPatchFromDifferences (45-142)
admin-ui/plugins/scim/types/index.ts (1)
  • ScimFormValues (3-24)
🔇 Additional comments (9)
admin-ui/plugins/jans-lock/helper/utils.ts (1)

107-121: Good defensive guards against empty collections in new fields.

The logic correctly prevents adding patch operations when introducing new fields with empty array or empty object values. The implementation properly handles edge cases (null check at line 111, array check at line 112 before object inspection), and correctly preserves empty values in "replace" operations for existing fields where you may legitimately want to clear data.

However, no tests exist in the jans-lock plugin directory to validate this behavior, and there's no available backend API documentation specifying expectations for empty patch operations. While the code change is sound from a JSON Patch perspective, verify with your backend team that the API correctly handles patch operations that omit "add" operations for empty new fields.

admin-ui/app/locales/pt/translation.json (1)

132-132: ✓ Correct locale addition for Portuguese "Back" action.

The new actions.back entry with value "Voltar" is correctly placed, semantically accurate, and consistent with related Portuguese translations like "back_home". This mirrors the same addition across other locales (en, es, fr) as expected.

admin-ui/app/locales/fr/translation.json (1)

134-134: ✓ Correct locale addition for French "Back" action.

The new actions.back entry with value "Retour" is correctly positioned, semantically accurate, and consistent with related French translations like "back_home". This mirrors the same addition across other locales (pt, en, es) as expected.

admin-ui/app/routes/Apps/Gluu/GluuTypeAhead.tsx (2)

24-24: LGTM: Enhanced type flexibility.

The expanded type for labelKey appropriately supports both string keys and custom label extraction functions.


95-100: LGTM: Clean fallback logic.

The resolvedLabelKey memoization correctly handles function/string labelKey types and provides a sensible default.

admin-ui/plugins/jans-lock/components/JansLockConfiguration.tsx (4)

2-2: LGTM: Clean prop and import updates.

The addition of useMemo, GluuFormFooter import, and isSubmitting prop appropriately support the new form state management.

Also applies to: 8-8, 23-23, 26-30


74-76: LGTM: Accurate dirty state tracking.

Deriving dirty state from patch operations is more accurate than using Formik's built-in dirty property, as it accounts for trimming and type normalization.


85-102: LGTM: Clean submission flow.

Using precomputed patches ensures consistency and avoids recalculation. The silent no-op for unchanged forms is good UX.


432-443: Back button navigation verified as correct.

The GluuFormFooter component correctly implements the default navigation behavior. Since no onBack prop is provided, the Back button will navigate to /home/dashboard as expected, consistent with the established pattern.

Comment on lines +73 to +79
const selectedValue = useMemo(() => {
if (value !== undefined) {
return value
}
const fieldValue = formik?.values?.[name]
return Array.isArray(fieldValue) ? (fieldValue as Option[]) : []
}, [value, formik?.values?.[name], name])
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix dependency array to ensure proper memoization.

The dependency formik?.values?.[name] won't trigger re-computation correctly because React's dependency comparison doesn't evaluate the optional chain expression—it compares the reference to formik?.values?.[name] itself, not the value. When formik.values changes, this memo may return stale data.

Apply this diff:

   const selectedValue = useMemo(() => {
     if (value !== undefined) {
       return value
     }
     const fieldValue = formik?.values?.[name]
     return Array.isArray(fieldValue) ? (fieldValue as Option[]) : []
-  }, [value, formik?.values?.[name], name])
+  }, [value, formik?.values, name])
📝 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
const selectedValue = useMemo(() => {
if (value !== undefined) {
return value
}
const fieldValue = formik?.values?.[name]
return Array.isArray(fieldValue) ? (fieldValue as Option[]) : []
}, [value, formik?.values?.[name], name])
const selectedValue = useMemo(() => {
if (value !== undefined) {
return value
}
const fieldValue = formik?.values?.[name]
return Array.isArray(fieldValue) ? (fieldValue as Option[]) : []
}, [value, formik?.values, name])
🤖 Prompt for AI Agents
In admin-ui/app/routes/Apps/Gluu/GluuTypeAhead.tsx around lines 73–79, the
useMemo dependency list uses the optional-chained expression
formik?.values?.[name], which can miss updates; change the dependencies to
[value, formik?.values, name] (i.e., depend on the whole formik.values object
plus name and value) so the memo recalculates when form values change, and
ensure types remain correct when reading formik.values[name] inside the memo.

Comment on lines +62 to +72
const trimmedValuesAndPatches = useMemo(() => {
if (!lockConfig || !formik.values) {
return {
trimmedValues: null as JansLockConfigFormValues | null,
patches: [] as PatchOperation[],
}
}
const trimmedValues = trimObjectStrings(formik.values)
const patches = createPatchOperations(trimmedValues, lockConfig)
return { trimmedValues, patches }
}, [lockConfig, formik.values])
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider performance impact of computing patches on every change.

The trimmedValuesAndPatches memo recomputes on every formik.values change (i.e., every keystroke). For large forms, createPatchOperations iterates all fields and compares them with the original config, which may impact performance during typing.

If performance degrades, consider:

  • Debouncing the patch computation
  • Computing patches only when needed (e.g., on blur or submit)
  • Using Formik's built-in dirty state tracking

For small to medium forms, the current approach is acceptable and provides real-time dirty state tracking.

🤖 Prompt for AI Agents
In admin-ui/plugins/jans-lock/components/JansLockConfiguration.tsx around lines
62 to 72, the memoized trimmedValuesAndPatches recomputes patches on every
formik.values change (every keystroke), which can be expensive; change the
implementation to avoid computing createPatchOperations on every keypress by
either debouncing the patch computation (wrap patch creation in a debounced
effect and update patches state after a short delay), or compute patches only on
demand (on blur or on submit) and rely on Formik.dirty for immediate UI state,
ensuring the memo dependencies are updated to use the debounced value or the
on-demand trigger instead of raw formik.values.

Comment on lines +78 to +83
const isFormValid = useMemo(() => {
if (!formik.values) {
return false
}
return validationSchema.isValidSync(formik.values)
}, [formik.values])
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider using Formik's built-in validation state.

The manual isValidSync call duplicates Formik's built-in validation, which runs automatically when validateOnChange is enabled (the default). Formik already tracks validity in formik.isValid.

Consider replacing with:

- const isFormValid = useMemo(() => {
-   if (!formik.values) {
-     return false
-   }
-   return validationSchema.isValidSync(formik.values)
- }, [formik.values])
+ const isFormValid = formik.isValid

This eliminates redundant validation and improves performance. If you need synchronous validation for some reason, the current approach is fine.

🤖 Prompt for AI Agents
In admin-ui/plugins/jans-lock/components/JansLockConfiguration.tsx around lines
78 to 83, the code manually computes form validity with
validationSchema.isValidSync(formik.values), duplicating Formik's built-in
validation; replace this useMemo block with Formik's formik.isValid (or directly
reference formik.isValid where needed) so you rely on Formik's internal
validation lifecycle, remove the synchronous isValidSync call and its useMemo,
and ensure any consumers subscribe to formik.isValid (and formik.dirty/touched
if appropriate) instead.

formik.setFieldValue('tokenChannels', values)
}}
options={lockConfig?.tokenChannels || []}
options={(lockConfig?.tokenChannels as string[]) || []}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Type assertion assumes API contract.

The cast to string[] assumes lockConfig.tokenChannels is always a string array. If the API response could have a different shape, add a runtime check:

options={Array.isArray(lockConfig?.tokenChannels) ? (lockConfig.tokenChannels as string[]) : []}

If the API contract is guaranteed, the current code is fine.

🤖 Prompt for AI Agents
In admin-ui/plugins/jans-lock/components/JansLockConfiguration.tsx around line
132, the code casts lockConfig?.tokenChannels to string[] which assumes the API
always returns that shape; change to a runtime check that uses
Array.isArray(lockConfig?.tokenChannels) and only pass it as options when true,
otherwise pass an empty array, so you avoid unsafe type assertions and handle
unexpected API shapes safely.

Comment on lines +82 to +91
showBack={true}
showCancel={true}
showApply={true}
onApply={toggle}
onCancel={handleCancel}
disableBack={false}
disableCancel={!isFormDirty}
disableApply={!isFormValid || !isFormDirty}
applyButtonType="submit"
isLoading={isSubmitting}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Prevent Apply modal from immediately closing

onApply calls toggle() while the button is also type="submit". A click fires the click handler (opening the dialog) and then the form submit, which triggers formik.onSubmit (also toggle). The modal flips twice and ends up closed, so users can’t confirm changes. Please invoke formik.submitForm() from onApply and use a non-submit button to keep the dialog open exactly once.

-            onApply={toggle}
-            applyButtonType="submit"
+            onApply={formik.submitForm}
+            applyButtonType="button"
📝 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
showBack={true}
showCancel={true}
showApply={true}
onApply={toggle}
onCancel={handleCancel}
disableBack={false}
disableCancel={!isFormDirty}
disableApply={!isFormValid || !isFormDirty}
applyButtonType="submit"
isLoading={isSubmitting}
showBack={true}
showCancel={true}
showApply={true}
onApply={formik.submitForm}
onCancel={handleCancel}
disableBack={false}
disableCancel={!isFormDirty}
disableApply={!isFormValid || !isFormDirty}
applyButtonType="button"
isLoading={isSubmitting}
🤖 Prompt for AI Agents
In admin-ui/plugins/scim/components/ScimConfiguration.tsx around lines 82 to 91,
the Apply button is both type="submit" and calling toggle() via onApply which
causes the modal to flip twice; change onApply to call formik.submitForm()
instead of toggle(), and set applyButtonType to a non-submit value (e.g.
"button") so the click only triggers formik.submitForm() and the modal is closed
once by the formik onSubmit/toggle flow; ensure you do not remove the existing
isLoading/disableApply props and keep the actual toggle() call in the form
submit/confirmation handler rather than the button click.

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

Labels

comp-admin-ui Component affected by issue or PR kind-feature Issue or PR is a new feature request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants