Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions admin-ui/app/components/Sidebar/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { HealthServiceKey, HealthStatusResponse } from 'Redux/features/healthSlice'

// Sidebar-specific type definitions
export interface MenuItem {
icon?: string
Expand Down Expand Up @@ -26,9 +28,10 @@ export interface ThemeContextState {
}
}

// Visibility and styling types for sidebar
export interface VisibilityConditions {
readonly [key: string]: string
type HealthVisibilityPath = '/jans-lock' | '/fido/fidomanagement' | '/scim' | '/saml'

export type VisibilityConditions = {
readonly [P in HealthVisibilityPath]: HealthServiceKey
}

export interface IconStyles {
Expand All @@ -39,13 +42,6 @@ export interface MenuIconMap {
readonly [key: string]: React.ReactNode
}

// Sidebar state interface
export interface SidebarState {
health: Record<string, string>
logoutAuditInFlight: boolean
logoutAuditSucceeded: boolean | null
}

// Root state interface for sidebar selectors
export interface SidebarRootState {
authReducer: {
Expand All @@ -55,7 +51,7 @@ export interface SidebarRootState {
permissions?: string[]
}
healthReducer: {
health: Record<string, string>
health: HealthStatusResponse
}
logoutAuditReducer: {
logoutAuditInFlight: boolean
Expand Down
27 changes: 26 additions & 1 deletion admin-ui/app/redux/features/healthSlice.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,32 @@
import { createSlice } from '@reduxjs/toolkit'
import reducerRegistry from 'Redux/reducers/ReducerRegistry'

const initialState = {
type HealthStatus = 'Running' | 'Not present'

export type HealthServiceKey =
| 'jans-lock'
| 'jans-auth'
| 'jans-config-api'
| 'jans-casa'
| 'jans-fido2'
| 'jans-scim'
| 'jans-link'
| 'keycloak'

type KnownHealthServices = Partial<Record<HealthServiceKey, HealthStatus>>

export type HealthStatusResponse = KnownHealthServices & {
[serviceName: string]: HealthStatus
}

export interface HealthState {
serverStatus: HealthStatus | null
dbStatus: HealthStatus | null
health: HealthStatusResponse
loading: boolean
}

const initialState: HealthState = {
serverStatus: null,
dbStatus: null,
health: {},
Expand Down
7 changes: 5 additions & 2 deletions admin-ui/app/routes/Apps/Gluu/GluuAppSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const VISIBILITY_CONDITIONS: VisibilityConditions = {
'/jans-lock': 'jans-lock',
'/fido/fidomanagement': 'jans-fido2',
'/scim': 'jans-scim',
'/saml': 'keycloak',
} as const

const ICON_STYLES: IconStyles = {
Expand Down Expand Up @@ -74,7 +75,7 @@ const MENU_ICON_MAP: MenuIconMap = {
// Type definitions for local state
interface RootState extends SidebarRootState {}

const selectHealth = (state: RootState): Record<string, string> => state.healthReducer.health
const selectHealth = (state: RootState) => state.healthReducer.health
const selectLogoutAuditSucceeded = (state: RootState): boolean | null =>
state.logoutAuditReducer.logoutAuditSucceeded

Expand Down Expand Up @@ -156,7 +157,9 @@ function GluuAppSidebar(): JSX.Element {
}

return menus.filter((menu: PluginMenu): boolean => {
const healthKey = VISIBILITY_CONDITIONS[menu.path || '']
const healthKey = menu.path
? VISIBILITY_CONDITIONS[menu.path as keyof VisibilityConditions]
: undefined
return healthKey ? health?.[healthKey] === 'Running' : true
})
}, [health, fetchedServersLength])
Expand Down
13 changes: 10 additions & 3 deletions admin-ui/app/routes/Dashboards/DashboardPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import CheckIcon from 'Images/svg/check.svg'
import CrossIcon from 'Images/svg/cross.svg'
import SetTitle from 'Utils/SetTitle'
import styles from './styles'
import type { HealthState } from 'Redux/features/healthSlice'

import { formatDate } from 'Utils/Util'
import UsersIcon from '@/components/SVG/menu/Users'
import Administrator from '@/components/SVG/menu/Administrator'
Expand All @@ -29,6 +31,9 @@ import customColors from '@/customColors'
import { useCedarling } from '@/cedarling'
import { useAppNavigation, ROUTES } from '@/helpers/navigation'

interface DashboardHealthRootState {
healthReducer: HealthState
}
// Constants moved outside component for better performance
const FETCHING_LICENSE_DETAILS = 'Fetch license details'

Expand All @@ -54,9 +59,11 @@ function DashboardPage() {
const { isUserInfoFetched } = useSelector((state: any) => state.authReducer)
const totalClientsEntries = useSelector((state: any) => state.initReducer.totalClientsEntries)
const license = useSelector((state: any) => state.licenseDetailsReducer.item)
const serverStatus = useSelector((state: any) => state.healthReducer.serverStatus)
const serverHealth = useSelector((state: any) => state.healthReducer.health)
const dbStatus = useSelector((state: any) => state.healthReducer.dbStatus)
const serverStatus = useSelector(
(state: DashboardHealthRootState) => state.healthReducer.serverStatus,
)
const serverHealth = useSelector((state: DashboardHealthRootState) => state.healthReducer.health)
const dbStatus = useSelector((state: DashboardHealthRootState) => state.healthReducer.dbStatus)
const access_token = useSelector((state: any) => state.authReducer.token?.access_token)
const permissions = useSelector((state: any) => state.authReducer.permissions)

Expand Down
Loading