Skip to content

Conversation

@faisalsiddique4400
Copy link
Contributor

@faisalsiddique4400 faisalsiddique4400 commented Dec 8, 2025

fix(admin-ui): service status shows accurate values on dashboard instead of marking Not present as Down (#2500)

Summary

The dashboard was incorrectly marking services with "Not present" status as "Down", which created confusion and did not reflect the actual response returned by /jans-config-api/api/v1/health/service-status?service=all.

Fix Summary

  • Updated service status mapping to correctly handle "Not present" state.
  • Displayed exact service state as returned from backend instead of force-mapping to "Down".
  • Improved UI status handling to make dashboard representation reliable and consistent.
  • Verified against API sample response to ensure accurate rendering.

Result

Dashboard now displays real service state including "Running", "Down" and "Not present" without misinterpretation.

🔗 Ticket

Closes: #2500

Summary by CodeRabbit

  • New Features

    • Health status gains a 'Down' state for clearer service visibility
  • Bug Fixes

    • Safer health-state updates to avoid invalid assignments
    • More robust initialization data handling to prevent runtime issues
  • Other

    • Stronger, more explicit typing across initialization, permission, and dashboard flows
    • Initialization no longer exposes a loading flag in its public state

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 8, 2025

📝 Walkthrough

Walkthrough

Adds and tightens TypeScript types across Redux slices and UI components, introduces explicit payload interfaces, updates reducer action typings, and makes health-status reducer assignments conditional to avoid misreporting service statuses.

Changes

Cohort / File(s) Summary
Health Redux
admin-ui/app/redux/features/healthSlice.ts
Import PayloadAction; extend HealthStatus to include 'Down'; add HealthStatusResponsePayload and HealthServerStatusResponsePayload interfaces; change reducer action signatures to PayloadAction<...>; guard updates in getHealthStatusResponse so serverStatus/dbStatus are only set when present; adjust getHealthServerStatusResponse to use typed payload.
Init Redux
admin-ui/app/redux/features/initSlice.ts
Add GenericItem and exported InitState; add payload interfaces (ActionDataPayload, ScriptsResponsePayload, ClientsResponsePayload, ScopesResponsePayload, AttributesResponsePayload, ApiTimeoutPayload); remove isLoading from state/initialState; update reducer typings and handling to use typed data / data.entries and strongly-typed ApiTimeoutPayload.
Dashboard UI
admin-ui/app/routes/Dashboards/DashboardPage.tsx
Add local types (StatDataItem, LockDetailItem, RootState); switch selectors from any to RootState; initialize userAction with typed shape; tighten useState types; replace isUp helper with inline status checks and safer lock array access; update dispatch/buildPayload usage to typed payloads.
Permission Utilities
admin-ui/app/utils/PermChecker.ts
Export and tighten UserAction (required action_message, `action_data: ActionData

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Pay attention to admin-ui/app/redux/features/initSlice.ts for removed isLoading and how callers expect that flag.
  • Verify PermChecker.ts tighter ActionData/UserAction types do not break call sites that previously passed looser shapes.
  • Confirm healthSlice guarded assignments resolve the linked issue (#2500) and don't introduce undefined-state regressions in other consumers.
  • Check Dashboard selectors against actual store RootState shape.

Possibly related PRs

Suggested reviewers

  • syntrydy
  • duttarnab

Poem

🐰 I hopped through types and tightened each thread,
Guarded statuses so none show as misread.
'Running', 'Down', 'Not present' now true,
Redux and dashboard hum — a clear skies view. 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 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 fix: correcting service status display from incorrectly showing 'Down' for 'Not present' services.
Linked Issues check ✅ Passed The PR successfully implements all objectives from issue #2500: extends HealthStatus to include 'Down', updates reducer logic to safely handle 'Not present' status, replaces loose typing with explicit payload interfaces, and refactors dashboard status rendering to display exact API values.
Out of Scope Changes check ✅ Passed All changes directly support the primary objective of fixing service status display. Type safety improvements and UI refactoring are necessary to achieve accurate status representation, though some changes extend beyond minimal scope.
✨ 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-2500

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 Dec 8, 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: 4

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1629fc8 and 4876bc1.

📒 Files selected for processing (4)
  • admin-ui/app/redux/features/healthSlice.ts (3 hunks)
  • admin-ui/app/redux/features/initSlice.ts (2 hunks)
  • admin-ui/app/routes/Dashboards/DashboardPage.tsx (8 hunks)
  • admin-ui/app/utils/PermChecker.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-11-06T08:23:20.948Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2418
File: admin-ui/plugins/user-management/components/UserForm.tsx:290-297
Timestamp: 2025-11-06T08:23:20.948Z
Learning: In the UserForm component (admin-ui/plugins/user-management/components/UserForm.tsx), the Back button should fall back to '/user/usersmanagement' when browser history is unavailable, not '/home/dashboard', as this keeps users in the user management context. This aligns with the new requirement that users should be redirected to the respective listing screen of the component rather than the dashboard.

Applied to files:

  • admin-ui/app/routes/Dashboards/DashboardPage.tsx
📚 Learning: 2025-12-05T18:24:41.681Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2498
File: admin-ui/plugins/saml/components/SamlConfigurationForm.tsx:30-30
Timestamp: 2025-12-05T18:24:41.681Z
Learning: In the GluuFederation/flex admin-ui codebase, `SetTitle` (imported from 'Utils/SetTitle') is a custom React hook that should be called at the component's top level, not inside `useEffect` or other hooks, because it internally manages side effects for setting page titles.

Applied to files:

  • admin-ui/app/routes/Dashboards/DashboardPage.tsx
🧬 Code graph analysis (2)
admin-ui/app/redux/features/initSlice.ts (1)
admin-ui/plugins/admin/redux/sagas/types/userAction.ts (1)
  • ActionPayload (7-9)
admin-ui/app/routes/Dashboards/DashboardPage.tsx (7)
admin-ui/app/cedarling/types/index.ts (2)
  • RootState (128-135)
  • CedarPermissionsState (72-80)
admin-ui/app/redux/features/initSlice.ts (1)
  • InitState (8-17)
admin-ui/app/redux/features/types/authTypes.ts (1)
  • AuthState (25-45)
admin-ui/app/redux/features/licenseDetailsSlice.ts (1)
  • LicenseDetailsState (21-24)
admin-ui/app/redux/features/healthSlice.ts (1)
  • HealthState (22-27)
admin-ui/app/utils/PermChecker.ts (3)
  • UserAction (138-142)
  • buildPayload (154-161)
  • ActionData (145-152)
admin-ui/app/helpers/navigation.ts (1)
  • useAppNavigation (75-104)
🔇 Additional comments (6)
admin-ui/app/redux/features/healthSlice.ts (1)

36-76: LGTM! Payload interfaces and typed reducers are well-structured.

The conditional updates in getHealthStatusResponse (lines 60-65) correctly prevent overwriting existing state when fields are missing from the response. The explicit PayloadAction typing improves type safety.

admin-ui/app/redux/features/initSlice.ts (1)

68-91: LGTM!

The response handlers use appropriate defensive patterns with optional chaining and fallback values. The typed PayloadAction parameters improve type safety.

admin-ui/app/routes/Dashboards/DashboardPage.tsx (3)

317-346: LGTM! Status display logic correctly handles all backend states.

The implementation now accurately displays the exact service status returned by the backend:

  • 'Running' and 'Online' show as healthy (check icon, green styling)
  • 'Not present', 'Down', and other states show their actual values with cross styling
  • 'Unknown' is only shown when the value is null/undefined

This correctly addresses the PR objective of displaying "Not present" as-is instead of mapping it to "Down".


234-248: LGTM!

The defensive Array.isArray(lock) check before accessing lock[0] correctly handles the union type LockDetailItem[] | LockDetail. The type assertion is safe given this guard.


60-74: Remove the suggestion to centralize RootState — this is a component-specific definition, not a duplicate.

The RootState in admin-ui/app/cedarling/types/index.ts contains only authReducer, cedarPermissions, and apiPermissionReducer. The RootState in DashboardPage.tsx includes those plus five additional reducers (mauReducer, initReducer, lockReducer, licenseDetailsReducer, healthReducer) required specifically for this component. This is an appropriate local type definition matching the component's actual Redux dependencies, not a duplicate causing maintenance drift.

Likely an incorrect or invalid review comment.

admin-ui/app/utils/PermChecker.ts (1)

138-152: LGTM!

The exported UserAction interface and ActionData type provide clear contracts for action payloads. The union type for ActionData appropriately covers the various payload shapes used across the codebase.

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

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/Dashboards/DashboardPage.tsx (1)

180-204: Pass userAction to dispatch(getClients()) on line 204.

The buildPayload call on line 203 populates userAction with tracking data, but dispatch(getClients()) doesn't pass it. The getClients saga expects the action via payload to track user activity. Use dispatch(getClients({ action: userAction })) to match the pattern in Reports.tsx (line 68).

Note: dispatch(getLicenseDetails()) on line 181 is correct since the corresponding saga doesn't use the action payload.

♻️ Duplicate comments (2)
admin-ui/app/redux/features/initSlice.ts (2)

4-21: Consolidate duplicate interface definitions.

GenericItem (lines 4-6) and ActionDataPayload (lines 19-21) have identical structures. Consider using a single type to avoid duplication.

Additionally, as noted in a previous review, ActionPayload is already defined in admin-ui/plugins/admin/redux/sagas/types/userAction.ts. Consider importing from there instead.

+import type { ActionPayload } from 'Plugins/admin/redux/sagas/types/userAction'
+
+type GenericItem = ActionPayload
+
-interface GenericItem {
-  [key: string]: string | number | boolean | string[] | number[] | boolean[] | null
-}
-
 export interface InitState {
   scripts: GenericItem[]
   // ...
 }

-interface ActionDataPayload {
-  [key: string]: string | number | boolean | string[] | number[] | boolean[] | null
-}
+type ActionDataPayload = ActionPayload

93-96: isLoading is never set to true.

As noted in a previous review, isLoading is only set to false here, but no reducer sets it to true. This makes the loading state ineffective. Consider adding state.isLoading = true in an appropriate action like getScripts, getClients, getScopes, or getAttributes.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4876bc1 and 129cba7.

📒 Files selected for processing (2)
  • admin-ui/app/redux/features/initSlice.ts (2 hunks)
  • admin-ui/app/routes/Dashboards/DashboardPage.tsx (8 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-05T18:24:41.681Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2498
File: admin-ui/plugins/saml/components/SamlConfigurationForm.tsx:30-30
Timestamp: 2025-12-05T18:24:41.681Z
Learning: In the GluuFederation/flex admin-ui codebase, `SetTitle` (imported from 'Utils/SetTitle') is a custom React hook that should be called at the component's top level, not inside `useEffect` or other hooks, because it internally manages side effects for setting page titles.

Applied to files:

  • admin-ui/app/routes/Dashboards/DashboardPage.tsx
🧬 Code graph analysis (1)
admin-ui/app/routes/Dashboards/DashboardPage.tsx (6)
admin-ui/app/cedarling/types/index.ts (2)
  • RootState (128-135)
  • CedarPermissionsState (72-80)
admin-ui/app/redux/features/initSlice.ts (1)
  • InitState (8-17)
admin-ui/app/redux/features/types/authTypes.ts (1)
  • AuthState (25-45)
admin-ui/app/redux/features/licenseDetailsSlice.ts (1)
  • LicenseDetailsState (21-24)
admin-ui/app/utils/PermChecker.ts (3)
  • UserAction (138-142)
  • buildPayload (154-161)
  • ActionData (145-152)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (16-268)
🔇 Additional comments (4)
admin-ui/app/redux/features/initSlice.ts (1)

61-98: LGTM on reducer implementations.

The typed PayloadAction usages are well-structured. Optional chaining and fallback values (|| [], || 0) correctly guard against undefined data, ensuring state consistency.

admin-ui/app/routes/Dashboards/DashboardPage.tsx (3)

317-346: Status handling correctly displays actual API values.

The updated logic properly displays the exact service state from the backend:

  • getStatusText returns the raw value (e.g., "Running", "Down", "Not present")
  • getClassName and getStatusIcon use visual indicators for "Running"/"Online" vs other states

This directly addresses the PR objective of showing accurate service statuses instead of force-mapping "Not present" to "Down".


234-248: Good defensive guards on lock data access.

The runtime check Array.isArray(lock) && lock.length > 0 before accessing lock[0] prevents potential runtime errors. The optional chaining (lockItem?.monthly_active_users) provides additional safety.


82-116: LGTM on typed selectors and state.

The typed useSelector calls with RootState and explicit state types (number | null) improve type safety and IDE support. The typing is consistent with the imported state interfaces.

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

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/Dashboards/DashboardPage.tsx (1)

178-188: Module-level constant in dependency array.

FETCHING_LICENSE_DETAILS is a constant defined outside the component (line 72) and will never change. Including it in the dependency array is harmless but unnecessary.

   }, [
     access_token,
     hasViewPermissions,
     license,
     loading,
     requestStates.licenseRequested,
     dispatch,
     userAction,
     options,
-    FETCHING_LICENSE_DETAILS,
   ])
♻️ Duplicate comments (2)
admin-ui/app/routes/Dashboards/DashboardPage.tsx (1)

50-69: Duplicate interfaces flagged in past reviews still present.

LockDetailItem (lines 50-53) is structurally identical to what was previously called LockDetail. Additionally, the local RootState interface (lines 55-69) duplicates the one in admin-ui/app/cedarling/types/index.ts. Consider consolidating these to a single source of truth.

admin-ui/app/redux/features/initSlice.ts (1)

18-20: ActionDataPayload duplicates GenericItem structure.

Both ActionDataPayload and GenericItem have identical shapes. Additionally, per the past review, ActionPayload may already exist in admin-ui/plugins/admin/redux/sagas/types/userAction.ts. Consider consolidating to a single type.

-interface ActionDataPayload {
-  [key: string]: string | number | boolean | string[] | number[] | boolean[] | null
-}
+type ActionDataPayload = GenericItem
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 129cba7 and fb049d9.

📒 Files selected for processing (2)
  • admin-ui/app/redux/features/initSlice.ts (2 hunks)
  • admin-ui/app/routes/Dashboards/DashboardPage.tsx (8 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-05T18:24:41.681Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2498
File: admin-ui/plugins/saml/components/SamlConfigurationForm.tsx:30-30
Timestamp: 2025-12-05T18:24:41.681Z
Learning: In the GluuFederation/flex admin-ui codebase, `SetTitle` (imported from 'Utils/SetTitle') is a custom React hook that should be called at the component's top level, not inside `useEffect` or other hooks, because it internally manages side effects for setting page titles.

Applied to files:

  • admin-ui/app/routes/Dashboards/DashboardPage.tsx
🧬 Code graph analysis (1)
admin-ui/app/routes/Dashboards/DashboardPage.tsx (6)
admin-ui/app/cedarling/types/index.ts (2)
  • RootState (128-135)
  • CedarPermissionsState (72-80)
admin-ui/plugins/auth-server/components/Sessions/types/index.ts (1)
  • RootState (10-10)
admin-ui/app/redux/features/initSlice.ts (1)
  • InitState (8-16)
admin-ui/app/redux/features/healthSlice.ts (1)
  • HealthState (22-27)
admin-ui/app/utils/PermChecker.ts (2)
  • UserAction (138-142)
  • ActionData (145-152)
admin-ui/app/helpers/navigation.ts (1)
  • useAppNavigation (75-104)
🔇 Additional comments (7)
admin-ui/app/routes/Dashboards/DashboardPage.tsx (4)

77-78: Good initialization pattern for typed user action.

The explicit shape { action_message: '', action_data: null } ensures userAction conforms to the UserAction interface from the start.


312-341: Status handling correctly addresses the PR objective.

The refactored getClassName, getStatusText, and getStatusIcon functions now:

  • Display the exact backend status value (e.g., "Running", "Down", "Not present") via getStatusText
  • Apply appropriate styling only for known "up" states (RUNNING/ONLINE)
  • Return "Unknown" as a sensible fallback for missing values

This aligns with the fix to prevent "Not present" from being incorrectly mapped to "Down".


229-243: Defensive array handling for lock data is appropriate.

The guard Array.isArray(lock) && lock.length > 0 correctly handles the union type LockDetailItem[] | LockDetailItem defined in RootState. The optional chaining on lockItem (lines 234, 239) is slightly redundant after the length check but adds resilience.


297-297: Hardcoded status: false for SCIM is unused.

The status field in statusDetails is only used for dbStatus and serverStatus lookups. For SCIM (key 'jans-scim'), getStatusValue returns serverHealth['jans-scim'], ignoring the hardcoded false. Consider removing the unused status field from this entry or aligning the data structure.

admin-ui/app/redux/features/initSlice.ts (3)

8-16: InitState export provides proper typing for consumers.

The interface correctly types the slice's state shape and is properly exported for use in DashboardPage.tsx and other consumers. The removal of the unused isLoading field (noted in past reviews) has been addressed.


63-93: Reducer typing and null-safety improvements look correct.

The reducers now use explicit payload types with proper optional chaining guards. The handleApiTimeout reducer directly assigns from the payload (line 92), addressing the prior concern about isTimeout never being set to true.


80-83: Scopes response structure differs from other endpoints.

getScopesResponse assigns action.payload.data directly (an array), while other handlers extract from data.entries. This is correctly reflected in the distinct ScopesResponsePayload interface (lines 35-37).

@faisalsiddique4400
Copy link
Contributor Author

The service status shows accurate values on dashboard instead of marking Not present as Down.
image

@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 8, 2025

@moabu moabu merged commit 4bc7864 into main Dec 8, 2025
8 checks passed
@moabu moabu deleted the admin-ui-issue-2500 branch December 8, 2025 10:12
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): the exact status of services should be displayed on dashboard

4 participants