Skip to content

Conversation

@faisalsiddique4400
Copy link
Contributor

@faisalsiddique4400 faisalsiddique4400 commented Nov 27, 2025

fix(admin-ui): resolve scope update issues, missing toasts, and disappearing action buttons (#2476)

Summary

The Scopes module is not functioning correctly after creating or editing a scope. Updated scopes are not reflected in the list, toast notifications are not shown, and action buttons disappear when returning to the Scope List page.

Issues Fixed

  • Scope list does not refresh after creating a new scope.
  • Scope list does not refresh after editing a scope.
  • Success toast is not displayed for create or edit actions.
  • Action buttons (Create, Edit, Delete) disappear when navigating back to the Scopes list from Create/Edit views.

Steps to Reproduce

  1. Navigate to Auth Server → Scopes.
  2. Create a new scope or edit an existing scope.
  3. Navigate back to the Scopes list.
  4. Observe:
    • Updated scopes are not shown.
    • No toast notification.
    • Action buttons are missing.

Expected Behavior

  • The Scopes list should automatically refresh after create or edit operations.
  • A success toast should appear for both actions.
  • All action buttons should consistently remain visible after navigating back.

Fix Summary

  • Added list refresh after successful create/edit requests.
  • Restored missing toast notification logic.
  • Corrected UI state handling when returning from detail views.
  • Ensured action buttons remain visible by reinitializing module-level state as needed.

Closes

Closes: #2476

Summary by CodeRabbit

  • New Features

    • Added default scope definitions and a scope-with-message type.
    • New change-detection utility for forms to enable smarter apply/cancel behavior.
  • Improvements

    • Improved create/update flows with toasts and in-form error alerts.
    • Faster, more consistent list/detail/edit pages: refined loading states, debounced search, pagination, themed styling, and targeted refreshes.
    • Enhanced form validation and attribute handling to preserve edits and reduce false positives.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 27, 2025

📝 Walkthrough

Walkthrough

Introduces typed scope defaults (INITIAL_SCOPE, DEFAULT_SCOPE_ATTRIBUTES, ScopeWithMessage), centralizes submit/update flows into memoized handlers using react-query QueryClient for targeted cache invalidation, adds deep-diff change detection (hasActualChanges), refactors list/detail rendering and theming, and adds toasts and audit logging across scope CRUD flows.

Changes

Cohort / File(s) Summary
Constants & types
admin-ui/plugins/auth-server/components/Scopes/constants.ts, admin-ui/plugins/auth-server/components/Scopes/types/*.ts
Add ScopeWithMessage, DEFAULT_SCOPE_ATTRIBUTES, and exported INITIAL_SCOPE; introduce ExtendedScope usage and related default values.
Create / Update pages
admin-ui/plugins/auth-server/components/Scopes/ScopeAddPage.tsx, admin-ui/plugins/auth-server/components/Scopes/ScopeEditPage.tsx
Replace inline submit logic with memoized handleSubmit (useCallback), parse/strip action_message, call mutateAsync, invalidate oauth-scope queries via getGetOauthScopesQueryKey/getOauthScopesByInum, dispatch updateToast, log audits, and navigate on success; add queryClient usage and improved query options.
Form & change detection
admin-ui/plugins/auth-server/components/Scopes/ScopeForm.tsx, admin-ui/plugins/auth-server/components/Scopes/helper/utils.ts
Use ExtendedScope for form state; add/export hasActualChanges for deep change detection (scalars, arrays, attributes); streamline attributes and creator handling; refine scopeType touch/validation and footer enablement logic.
List page & UI refactor
admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx
Major refactor: memoized query params/options, 500ms debounced search, theme-based styling, modular table/pagination/detail panel, memoized action handlers, loader wrapper, and targeted query invalidation with toasts.
Detail page rendering
admin-ui/plugins/auth-server/components/Scopes/ScopeDetailPage.tsx
Replace inline rendering with memoized values and useCallback row renderers; unified container styles and memoized badge/theme logic; no public signature change.
Hooks & minor cleanup
admin-ui/plugins/auth-server/components/Scopes/hooks/*, admin-ui/plugins/auth-server/components/Scopes/types/index.ts
Remove header/comments and minor cleanup; no runtime or export signature changes.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ScopeForm
    participant ScopePage
    participant API as ScopeAPI
    participant QueryClient
    participant Toast
    participant AuditLog

    User->>ScopeForm: submit(values)
    ScopeForm->>ScopePage: handleSubmit(values)

    rect `#e6f4ea`
      ScopePage->>ScopePage: parse JSON, extract action_message, clean payload
    end

    rect `#e7eefa`
      ScopePage->>API: mutateAsync(scopePayload)
      API-->>ScopePage: success / error
    end

    rect `#fff1d6`
      ScopePage->>QueryClient: invalidate queries (predicate getGetOauthScopesQueryKey / getOauthScopesByInum)
      ScopePage->>Toast: updateToast(success or error)
      ScopePage->>AuditLog: log action_message (if present)
      ScopePage->>User: navigate to scope list (on success)
    end
Loading
sequenceDiagram
    participant User
    participant ScopeList
    participant Query
    participant Table

    User->>ScopeList: open/list
    ScopeList->>Query: fetch(scopesQueryParams)
    Query-->>Table: rows

    User->>ScopeList: type in search
    ScopeList->>ScopeList: debounce 500ms
    ScopeList->>Query: refetch with updated params
    Query-->>Table: filtered rows
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Pay attention to:
    • Query invalidation predicates using getGetOauthScopesQueryKey and getOauthScopesByInum.
    • Correctness of hasActualChanges for arrays and attribute comparisons.
    • Formik touch/validation flow around scopeType updates in ScopeForm.
    • Async flows: toast dispatch ordering, audit logging, and navigation after mutation.

Possibly related PRs

Suggested reviewers

  • syntrydy
  • duttarnab

Poem

🐰 I nibbled through defaults and stitched a scope so neat,

Toasts now cheer, the cache clears quick on every feat,
Forms remember changes, lists return to play,
I hopped, I logged, I saved — then bounced away!

Pre-merge checks and finishing touches

✅ Passed checks (5 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 changes: fixing scope update issues, adding missing toast notifications, and resolving disappearing action buttons—all core issues addressed in the PR.
Linked Issues check ✅ Passed The PR addresses all coding requirements from #2476: list refresh via query invalidation after create/edit operations, toast notifications added via updateToast, and UI state handling through useQueryClient and improved component lifecycle management.
Out of Scope Changes check ✅ Passed All changes directly support the PR objectives: new utilities (hasActualChanges), memoization improvements, and refactored submission handling are integral to fixing scopes update, toasts, and action button visibility.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch admin-ui-issue-2476

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.

@mo-auto mo-auto added comp-admin-ui Component affected by issue or PR kind-bug Issue or PR is a bug in existing functionality labels Nov 27, 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: 9

Caution

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

⚠️ Outside diff range comments (1)
admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx (1)

329-342: Audit logging failure blocks modal closure.

If logScopeDeletion throws an error after successful deletion, the modal won't close (toggle() won't be called) even though the scope was actually deleted. This could confuse users.

Consider separating the audit logging from the critical path:

  const onDeletionConfirmed = useCallback(
    async (message: string) => {
      if (!item?.inum) return

      try {
        await deleteScope.mutateAsync({ inum: item.inum })
-       await logScopeDeletion(item, message)
        toggle()
+       // Fire-and-forget audit logging
+       logScopeDeletion(item, message).catch((err) =>
+         console.error('Failed to log scope deletion:', err)
+       )
      } catch (error) {
        console.error('Error deleting scope:', error)
      }
    },
    [item, deleteScope, logScopeDeletion, toggle],
  )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 604ddd2 and 07ba629.

📒 Files selected for processing (9)
  • admin-ui/plugins/auth-server/components/Scopes/ScopeAddPage.tsx (3 hunks)
  • admin-ui/plugins/auth-server/components/Scopes/ScopeDetailPage.tsx (2 hunks)
  • admin-ui/plugins/auth-server/components/Scopes/ScopeEditPage.tsx (3 hunks)
  • admin-ui/plugins/auth-server/components/Scopes/ScopeForm.tsx (7 hunks)
  • admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx (7 hunks)
  • admin-ui/plugins/auth-server/components/Scopes/helper/utils.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Scopes/hooks/index.ts (0 hunks)
  • admin-ui/plugins/auth-server/components/Scopes/hooks/useScopeActions.ts (0 hunks)
  • admin-ui/plugins/auth-server/components/Scopes/types/index.ts (0 hunks)
💤 Files with no reviewable changes (3)
  • admin-ui/plugins/auth-server/components/Scopes/hooks/index.ts
  • admin-ui/plugins/auth-server/components/Scopes/types/index.ts
  • admin-ui/plugins/auth-server/components/Scopes/hooks/useScopeActions.ts
🧰 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.943Z
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-07T12:55:26.241Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Scopes/ScopeEditPage.tsx
  • admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx
  • admin-ui/plugins/auth-server/components/Scopes/ScopeAddPage.tsx
🧬 Code graph analysis (4)
admin-ui/plugins/auth-server/components/Scopes/ScopeDetailPage.tsx (4)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)
admin-ui/plugins/auth-server/components/Scopes/types/index.ts (1)
  • ScopeDetailPageProps (28-28)
admin-ui/plugins/auth-server/components/Scopes/types/componentTypes.ts (1)
  • ScopeDetailPageProps (4-6)
admin-ui/plugins/user-management/types/CommonTypes.ts (1)
  • ThemeContext (13-17)
admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx (7)
admin-ui/plugins/auth-server/components/Scopes/types/index.ts (3)
  • ScopeTableRow (33-33)
  • Scope (2-2)
  • ScopeWithClients (11-11)
admin-ui/plugins/auth-server/components/Scopes/types/componentTypes.ts (1)
  • ScopeTableRow (24-28)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)
admin-ui/plugins/user-management/types/CommonTypes.ts (1)
  • ThemeContext (13-17)
admin-ui/plugins/auth-server/components/Scopes/hooks/useScopeActions.ts (1)
  • useScopeActions (26-106)
admin-ui/plugins/auth-server/components/Scopes/types/scopeTypes.ts (2)
  • Scope (11-11)
  • ScopeWithClients (40-40)
admin-ui/plugins/auth-server/components/Scopes/scopes.test.ts (1)
  • scopes (3-569)
admin-ui/plugins/auth-server/components/Scopes/ScopeForm.tsx (3)
admin-ui/plugins/auth-server/components/Scopes/types/scopeTypes.ts (1)
  • ExtendedScope (29-38)
admin-ui/plugins/auth-server/components/Scopes/types/formTypes.ts (1)
  • ScopeFormValues (3-15)
admin-ui/plugins/auth-server/components/Scopes/helper/utils.ts (1)
  • hasActualChanges (93-112)
admin-ui/plugins/auth-server/components/Scopes/helper/utils.ts (1)
admin-ui/plugins/auth-server/components/Scopes/types/formTypes.ts (1)
  • ScopeFormValues (3-15)
🔇 Additional comments (25)
admin-ui/plugins/auth-server/components/Scopes/helper/utils.ts (1)

93-112: LGTM!

The hasActualChanges function correctly compares all relevant ScopeFormValues fields, appropriately excluding action_message which is only used during submission. The use of helper functions for complex comparisons keeps the logic clean.

admin-ui/plugins/auth-server/components/Scopes/ScopeDetailPage.tsx (3)

10-10: LGTM!

Extracting CONTAINER_STYLES as a module-level constant prevents unnecessary object recreation on each render.


17-43: LGTM!

The memoization strategy is well-implemented with correct dependency arrays. The useCallback for renderAttributeRow appropriately prevents unnecessary re-renders when passed to map.


45-103: LGTM!

The JSX structure is clean and well-organized. The use of memoized values for badge colors and attribute rendering is appropriate.

admin-ui/plugins/auth-server/components/Scopes/ScopeEditPage.tsx (3)

166-183: LGTM with minor observation.

The conditional fetching logic prevents unnecessary API calls when data already exists. Note that if an API call fails and returns an empty result, this could lead to repeated fetch attempts. Consider adding error state tracking if this becomes an issue.


83-97: LGTM!

The extensibleScope memoization correctly handles both the case when scopeData exists and when it's undefined, providing sensible defaults.


135-142: Consider using the generated query key function for consistency, but verify availability first.

The hardcoded string 'getOauthScopesByInum' is used across four files (ScopeEditPage, ScopeAddPage, ScopeListPage) while getGetOauthScopesQueryKey() is properly imported. The useGetOauthScopesByInum hook is actively used and generates a query with this key. However, searching the codebase reveals no corresponding getGetOauthScopesByInumQueryKey function—despite the naming pattern used for other endpoints like getGetOauthScopesQueryKey. If the generated API includes this query key function, importing and using it would improve consistency and reduce brittleness. If not, consider whether the OpenAPI generator should be configured to export it.

admin-ui/plugins/auth-server/components/Scopes/ScopeForm.tsx (6)

32-38: LGTM!

Proper imports added for ExtendedScope type and hasActualChanges utility function.


97-97: LGTM!

The type change from Record<string, unknown> to Partial<ExtendedScope> improves type safety.


213-245: LGTM!

The scope type change handler correctly uses setValues and setTouched with validation disabled (second parameter false), then triggers validation via setTimeout to ensure state updates have propagated. This is the proper pattern for coordinated Formik state updates.


677-691: LGTM!

Using hasActualChanges instead of Formik's dirty state provides more accurate change detection, as it performs deep comparison of arrays and nested attributes. This correctly addresses the PR objective of ensuring action buttons remain properly enabled/disabled.


189-210: LGTM!

The onSubmit handler correctly merges form values with existing scope data, properly handles attributes, and sets creator information. The modal-based confirmation flow is preserved.


404-411: LGTM!

Adding the required attribute to the scope type label correctly indicates this field is mandatory in the UI.

admin-ui/plugins/auth-server/components/Scopes/ScopeAddPage.tsx (2)

114-131: LGTM!

The data fetching logic is consistent with ScopeEditPage.tsx and appropriately conditionally fetches only when needed.


143-164: LGTM!

The render structure is clean with proper loading state, error display, and form initialization using INITIAL_SCOPE.

admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx (10)

1-51: LGTM!

Imports are well-organized and the DetailPanelProps interface provides proper typing for the detail panel component.


53-79: LGTM!

Style constants are properly extracted outside the component to prevent recreation on each render. Using as const for type narrowing is a good practice.


144-169: LGTM!

Loading state correctly combines initial load and refetch states. Delete handlers properly dispatch toast notifications and invalidate relevant queries. Error handling includes a sensible fallback message.


436-485: LGTM!

Table actions are properly conditional based on Cedar permissions. The defensive array checks in click handlers are reasonable given MaterialTable's type signatures allow both single and array selections.


612-613: Verify intentional table remount on page size change.

Using limit as the key prop forces a complete remount of the MaterialTable component whenever limit changes. This will reset any internal table state (expanded detail panels, column visibility toggles, etc.).

If this is intentional to ensure clean state on page size change, consider adding a comment. If not, remove the key or use a stable identifier.


269-277: LGTM!

handleClearFilters comprehensively resets all filter state including the new searchInput field, ensuring a clean slate when users click the clear button.


290-308: LGTM!

Column render functions are properly memoized with correct dependencies. The clients column gracefully handles missing data and provides useful navigation to filtered clients.


513-638: LGTM!

The JSX structure is well-organized with proper accessibility attributes (aria-label, title), conditional rendering for permissions, and a clean separation between the filter UI and data table. The GluuLoader wrapper ensures users see feedback during data loading.


421-425: Verify field: 'dn' for clients column is intentional.

The clients column uses field: 'dn' but renders client count. If MaterialTable's built-in sorting/filtering is enabled for this column, it would operate on the dn field rather than the actual clients count. This may be intentional (to disable sorting on this column) or an oversight.

If sorting by client count is desired, consider using a computed field or disabling sorting for this column explicitly with sorting: false.


497-499: authorizeHelper is properly memoized and the dependency is correct.

The useCedarling hook wraps authorizeHelper with useCallback (lines 186-241 in useCedarling.ts), ensuring it has a stable reference. While authorizeHelper will be recreated when its dependencies change (when authorization state or tokens change), this is expected behavior and consistent with the pattern used in other pages like UserList.tsx. The effect will not run on every render.

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 07ba629 and 2437999.

📒 Files selected for processing (5)
  • admin-ui/plugins/auth-server/components/Scopes/ScopeAddPage.tsx (3 hunks)
  • admin-ui/plugins/auth-server/components/Scopes/ScopeEditPage.tsx (3 hunks)
  • admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx (7 hunks)
  • admin-ui/plugins/auth-server/components/Scopes/constants.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Scopes/helper/utils.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.943Z
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-07T12:55:26.241Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx
  • admin-ui/plugins/auth-server/components/Scopes/helper/utils.ts
  • admin-ui/plugins/auth-server/components/Scopes/ScopeEditPage.tsx
  • admin-ui/plugins/auth-server/components/Scopes/ScopeAddPage.tsx
🧬 Code graph analysis (3)
admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx (5)
admin-ui/plugins/auth-server/components/Scopes/types/index.ts (3)
  • ScopeTableRow (33-33)
  • Scope (2-2)
  • ScopeWithClients (11-11)
admin-ui/plugins/auth-server/components/Scopes/types/componentTypes.ts (1)
  • ScopeTableRow (24-28)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)
admin-ui/plugins/user-management/types/CommonTypes.ts (1)
  • ThemeContext (13-17)
admin-ui/plugins/auth-server/components/Scopes/hooks/useScopeActions.ts (1)
  • useScopeActions (26-106)
admin-ui/plugins/auth-server/components/Scopes/ScopeEditPage.tsx (3)
admin-ui/plugins/auth-server/components/Scopes/hooks/useScopeActions.ts (1)
  • useScopeActions (26-106)
admin-ui/plugins/auth-server/components/Scopes/types/scopeTypes.ts (4)
  • ExtendedScope (29-38)
  • ScopeClient (23-27)
  • EMPTY_SCOPE (69-78)
  • Scope (11-11)
admin-ui/app/utils/PermChecker.ts (1)
  • buildPayload (153-160)
admin-ui/plugins/auth-server/components/Scopes/ScopeAddPage.tsx (3)
admin-ui/plugins/auth-server/components/Scopes/hooks/useScopeActions.ts (1)
  • useScopeActions (26-106)
admin-ui/plugins/auth-server/components/Scopes/types/index.ts (2)
  • ModifiedFields (22-22)
  • Scope (2-2)
admin-ui/plugins/auth-server/components/Scopes/constants.ts (2)
  • ScopeWithMessage (4-6)
  • INITIAL_SCOPE (12-22)
🔇 Additional comments (12)
admin-ui/plugins/auth-server/components/Scopes/helper/utils.ts (3)

74-81: LGTM! compareArrays implementation is correct for string arrays.

The function properly handles null/undefined cases and performs order-insensitive comparison. The explicit string[] typing addresses the previous concern about object array limitations.


83-94: LGTM! compareAttributes now includes all relevant fields.

The spontaneousClientId comparison (line 91) has been added as previously suggested.


96-115: LGTM! Comprehensive change detection logic.

The hasActualChanges function correctly compares all scalar fields directly and delegates array/object comparisons to the appropriate helper functions.

admin-ui/plugins/auth-server/components/Scopes/constants.ts (1)

1-22: LGTM! Good extraction of shared constants.

This addresses the previous review suggestion to extract ScopeWithMessage, DEFAULT_SCOPE_ATTRIBUTES, and INITIAL_SCOPE to a shared location, eliminating duplication between ScopeAddPage.tsx and ScopeEditPage.tsx.

admin-ui/plugins/auth-server/components/Scopes/ScopeEditPage.tsx (2)

105-155: LGTM! Well-structured submit handler with proper error handling.

The implementation correctly:

  • Parses JSON data with error handling
  • Extracts and removes action_message before mutation
  • Invalidates related queries after successful update
  • Dispatches toast notification
  • Logs audit (non-blocking)
  • Includes dispatch in the dependency array (addressing the past review comment)

157-174: Consider adding dependency tracking for initial fetch.

The useEffect fetches attributes and scripts when their lengths are 0, but includes attributes.length and scripts.length in the dependency array. This works but could refetch if these arrays are emptied and repopulated during the component lifecycle.

Verify this is the intended behavior. If not, consider using a ref to track whether the initial fetch has occurred:

+ const hasFetchedRef = useRef(false)

  useEffect(() => {
+   if (hasFetchedRef.current) return
+   hasFetchedRef.current = true
+
    if (attributes.length === 0) {
      // ... fetch attributes
    }
    if (scripts.length === 0) {
      // ... fetch scripts
    }
- }, [dispatch, attributes.length, scripts.length])
+ }, [dispatch, attributes.length, scripts.length])
admin-ui/plugins/auth-server/components/Scopes/ScopeAddPage.tsx (2)

44-94: LGTM! Well-structured submit handler matching the edit page pattern.

The implementation correctly:

  • Parses JSON data with error handling
  • Extracts and removes action_message before mutation
  • Invalidates related queries after successful creation
  • Dispatches toast notification with scope name/id
  • Logs audit (non-blocking)
  • Includes dispatch in the dependency array (addressing the past review comment)

135-135: Good use of the shared INITIAL_SCOPE constant.

This addresses the past review suggestion to use a centralized constant instead of constructing the scope object inline.

admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx (4)

126-136: Good cache settings addressing past review feedback.

The staleTime: 30000 (30 seconds) is a reasonable choice that balances freshness with reduced API calls, addressing the previous concern about excessive refetching.


240-253: Good fix for the debounce race condition.

Clearing the debounce timer when Enter is pressed (lines 243-246) prevents the race condition between the debounced search and the immediate Enter key handler that was flagged in the past review.


381-381: Good simplification of DeleteIcon.

Removing the unnecessary useCallback wrapper addresses the past review comment about overhead for a static component.


505-521: Good implementation of debounced search with cleanup.

The debounce effect properly:

  • Uses a ref to track the timer
  • Clears the timer reference after execution (line 512)
  • Cleans up on unmount/re-run

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

♻️ Duplicate comments (2)
admin-ui/plugins/auth-server/components/Scopes/ScopeEditPage.tsx (1)

52-64: Aggressive cache settings may cause excessive API calls.

The query options still use staleTime: 0 and gcTime: 0 with refetchOnWindowFocus: true, which was flagged in a previous review. This causes data to always be considered stale and garbage collected immediately, potentially triggering API calls on every tab switch.

admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx (1)

409-420: PaginationComponent pattern unchanged from past review.

The PaginationComponent still uses the useCallback wrapper pattern that was flagged in a previous review. Consider the suggested refactor to use useMemo for pagination props instead.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2437999 and e87ebde.

📒 Files selected for processing (3)
  • admin-ui/plugins/auth-server/components/Scopes/ScopeAddPage.tsx (3 hunks)
  • admin-ui/plugins/auth-server/components/Scopes/ScopeEditPage.tsx (3 hunks)
  • admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx (7 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.943Z
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-07T12:55:26.241Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Scopes/ScopeAddPage.tsx
🧬 Code graph analysis (2)
admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx (7)
admin-ui/plugins/auth-server/components/Scopes/types/index.ts (3)
  • ScopeTableRow (33-33)
  • Scope (2-2)
  • ScopeWithClients (11-11)
admin-ui/plugins/auth-server/components/Scopes/types/componentTypes.ts (1)
  • ScopeTableRow (24-28)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)
admin-ui/plugins/user-management/types/CommonTypes.ts (1)
  • ThemeContext (13-17)
admin-ui/plugins/auth-server/components/Scopes/hooks/useScopeActions.ts (1)
  • useScopeActions (26-106)
admin-ui/plugins/auth-server/components/Scopes/types/scopeTypes.ts (2)
  • Scope (11-11)
  • ScopeWithClients (40-40)
admin-ui/app/components/Card/Card.tsx (1)
  • Card (27-27)
admin-ui/plugins/auth-server/components/Scopes/ScopeAddPage.tsx (3)
admin-ui/plugins/auth-server/components/Scopes/hooks/useScopeActions.ts (1)
  • useScopeActions (26-106)
admin-ui/plugins/auth-server/components/Scopes/types/formTypes.ts (1)
  • ModifiedFields (17-19)
admin-ui/plugins/auth-server/components/Scopes/constants.ts (2)
  • ScopeWithMessage (4-6)
  • INITIAL_SCOPE (12-22)
🔇 Additional comments (17)
admin-ui/plugins/auth-server/components/Scopes/ScopeEditPage.tsx (4)

1-23: LGTM! Imports and module setup are well-organized.

The imports are properly structured, bringing in necessary hooks from React, React Query, and the API layer. The constants are now imported from a shared ./constants module, which addresses the duplication concern from previous reviews.


74-93: LGTM! Data handling and loading state are well-implemented.

The extensibleScope memo correctly handles the case when scopeData is undefined by falling back to EMPTY_SCOPE with proper defaults. The loading state properly combines both the mutation pending state and the query loading state.


105-155: Well-structured submit handler with comprehensive error handling.

The handleSubmit callback correctly:

  1. Parses and validates input data with proper error handling
  2. Extracts and removes action_message before the API call
  3. Invalidates relevant queries to ensure fresh data in the list
  4. Shows a contextual success toast
  5. Logs audit information with isolated error handling
  6. Navigates back to the list on success

The dependency array now correctly includes dispatch, addressing the previous review comment.


157-174: LGTM! Lazy loading of attributes and scripts.

The effect correctly fetches attributes and scripts only when they haven't been loaded yet, preventing redundant API calls.

admin-ui/plugins/auth-server/components/Scopes/ScopeAddPage.tsx (4)

1-17: LGTM! Clean imports using shared constants.

The file properly imports ScopeWithMessage and INITIAL_SCOPE from the shared ./constants module, addressing the duplication concern from previous reviews.


44-94: Well-implemented submit handler that addresses the PR objectives.

The handleSubmit callback correctly:

  1. Parses input with proper JSON error handling
  2. Creates the scope via mutateAsync
  3. Invalidates queries to refresh the list (fixes the "list not updating" issue)
  4. Shows success toast (restores missing toast notification)
  5. Logs audit information with isolated error handling
  6. Navigates back to the list

The dependency array now correctly includes dispatch, addressing the previous review comment.


96-123: LGTM! Consistent data loading and search handling.

The effect for loading attributes and scripts, and the search handler, follow the same pattern as ScopeEditPage, maintaining consistency across the module.


125-146: LGTM! Clean render implementation.

The component correctly uses createScope.isPending for the loading state and passes the shared INITIAL_SCOPE constant to the form, ensuring consistent initial values.

admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx (9)

1-47: LGTM! Well-organized imports and type definitions.

The imports are properly structured with clear separation between React utilities, UI components, routing, state management, and API hooks. The type imports from @material-table/core enable proper typing for columns and actions.


49-79: LGTM! Style constants properly extracted.

Defining style constants outside the component as frozen objects (as const) prevents recreation on each render and provides clear documentation of the UI structure.


113-136: Cache settings improved from previous review.

The query options now use staleTime: 30000 (30 seconds) and refetchOnWindowFocus: false, addressing the previous review concern about excessive API calls. This is a good balance between data freshness and performance.


173-210: LGTM! Proper memoization of derived state.

Theme colors, permission checks, and data extraction are appropriately memoized to prevent unnecessary recalculations. The permission checks integrate correctly with the Cedar permission system.


240-253: Debounce race condition addressed.

The handlePatternKeyDown now properly clears the debounce timer when Enter is pressed, preventing the race condition between debounced search and immediate Enter key submission that was flagged in a previous review.


381-388: DeleteIcon simplified as suggested.

DeleteIcon is now a plain function instead of being wrapped in useCallback, and it's correctly excluded from the myActions dependency array. This addresses the previous review comments.


440-496: LGTM! Actions and table components properly memoized.

The myActions array correctly excludes DeleteIcon from its dependency array as suggested in previous reviews. The actions are conditionally added based on permissions, and the table components are properly memoized.


504-520: LGTM! Debounce effect properly implemented.

The debounce effect correctly:

  1. Uses a ref to track the timer
  2. Sets the timer reference to null after execution
  3. Properly cleans up the timer on unmount or when dependencies change

This addresses the race condition concern from previous reviews.


522-647: LGTM! Well-structured UI implementation.

The render section properly:

  1. Wraps content with GluuLoader for loading states
  2. Implements accessible filter controls with proper aria-label attributes
  3. Uses GluuViewWrapper for permission-based rendering
  4. Configures MaterialTable with memoized components, columns, and actions
  5. Conditionally renders the delete confirmation dialog

The improved state management ensures action buttons remain visible after navigation, addressing the PR objective.

@sonarqubecloud
Copy link

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

♻️ Duplicate comments (1)
admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx (1)

146-154: Use translation for the success message.

The success message "Scope deleted successfully" is hardcoded in English. For consistency with the rest of the codebase and i18n support, use the translation function.

  const handleDeleteSuccess = useCallback(() => {
-   dispatch(updateToast(true, 'success', 'Scope deleted successfully'))
+   dispatch(updateToast(true, 'success', t('messages.scope_deleted_successfully')))
    queryClient.invalidateQueries({

Note: Ensure the translation key messages.scope_deleted_successfully exists in your i18n resources.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e87ebde and 584b1e1.

📒 Files selected for processing (1)
  • admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx (7 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.943Z
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-07T12:55:26.241Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx
🧬 Code graph analysis (1)
admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx (4)
admin-ui/plugins/auth-server/components/Scopes/types/index.ts (3)
  • ScopeTableRow (33-33)
  • Scope (2-2)
  • ScopeWithClients (11-11)
admin-ui/plugins/auth-server/components/Scopes/types/componentTypes.ts (1)
  • ScopeTableRow (24-28)
admin-ui/plugins/user-management/types/CommonTypes.ts (1)
  • ThemeContext (13-17)
admin-ui/plugins/auth-server/components/Scopes/hooks/useScopeActions.ts (1)
  • useScopeActions (26-106)
🔇 Additional comments (7)
admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx (7)

49-79: Well-structured style constants and type definitions.

The extraction of style constants with as const assertions and the DetailPanelProps interface improves type safety and maintainability. This is a good pattern for keeping styles DRY.


126-136: Cache settings have been improved.

The staleTime: 30000 addresses the previous concern about aggressive cache settings. This provides a reasonable balance between data freshness and avoiding excessive API calls.


202-210: LGTM!

The memoized derivations for scopes and totalItems are correctly implemented with proper dependency arrays and safe fallbacks for undefined values.


240-253: Debounce race condition has been addressed.

The handlePatternKeyDown now properly clears the debounce timer when Enter is pressed, preventing the race condition mentioned in past reviews. Good implementation.


440-488: Actions array is well-structured.

The myActions memoization correctly excludes DeleteIcon from dependencies (addressing the past review comment). The conditional action building based on permissions is clean.


621-631: MaterialTable key may cause unnecessary remounts.

Using key={limit || 0} forces a full remount of MaterialTable when limit changes. While this might be intentional to reset table state, it could cause performance issues and loss of UI state (like expanded detail panels).

Consider whether this behavior is intentional. If the goal is to reset pagination state, this is already handled by the handlers. If full remount is not needed:

- <MaterialTable
-   key={limit || 0}
+ <MaterialTable

522-646: Implementation correctly addresses PR objectives.

The changes properly implement:

  • List refresh after create/edit via queryClient.invalidateQueries()
  • Success toast notifications via updateToast() dispatch
  • Action buttons remain visible through proper state management and memoization

Copy link
Contributor

@syntrydy syntrydy left a comment

Choose a reason for hiding this comment

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

I have fetch the branch and test.
The cache invalidation is working as expected and the toast notifications also

@moabu moabu merged commit dae647a into main Nov 27, 2025
9 checks passed
@moabu moabu deleted the admin-ui-issue-2476 branch November 27, 2025 16:46
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-bug Issue or PR is a bug in existing functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(admin-ui): Scope update issues, missing toasts, and disappearing action buttons

5 participants