@@ -18,6 +18,11 @@ import CrossIcon from 'Images/svg/cross.svg'
1818import SetTitle from 'Utils/SetTitle'
1919import styles from './styles'
2020import type { HealthState } from 'Redux/features/healthSlice'
21+ import type { AuthState } from 'Redux/features/types/authTypes'
22+ import type { InitState } from 'Redux/features/initSlice'
23+ import type { LicenseDetailsState } from 'Redux/features/licenseDetailsSlice'
24+ import type { CedarPermissionsState } from '@/cedarling/types'
25+ import type { UserAction , ActionData } from 'Utils/PermChecker'
2126
2227import { formatDate } from 'Utils/Util'
2328import UsersIcon from '@/components/SVG/menu/Users'
@@ -34,43 +39,76 @@ import { useAppNavigation, ROUTES } from '@/helpers/navigation'
3439interface DashboardHealthRootState {
3540 healthReducer : HealthState
3641}
42+
43+ interface StatDataItem {
44+ month : number | string
45+ mau ?: number
46+ authz_code_access_token_count ?: number
47+ client_credentials_access_token_count ?: number
48+ }
49+
50+ interface LockDetailItem {
51+ monthly_active_users ?: number
52+ monthly_active_clients ?: number
53+ }
54+
55+ interface RootState {
56+ mauReducer : {
57+ stat : StatDataItem [ ]
58+ loading : boolean
59+ }
60+ initReducer : InitState
61+ lockReducer : {
62+ lockDetail : LockDetailItem [ ] | LockDetailItem
63+ loading : boolean
64+ }
65+ authReducer : AuthState
66+ licenseDetailsReducer : LicenseDetailsState
67+ healthReducer : HealthState
68+ cedarPermissions : CedarPermissionsState
69+ }
70+
3771// Constants moved outside component for better performance
3872const FETCHING_LICENSE_DETAILS = 'Fetch license details'
3973
4074function DashboardPage ( ) {
4175 const { t } = useTranslation ( )
4276 const dispatch = useDispatch ( )
43- const userAction = useMemo ( ( ) => ( { } ) , [ ] )
77+ const userAction = useMemo ( ( ) => ( { action_message : '' , action_data : null } ) as UserAction , [ ] )
4478 const options = useMemo ( ( ) => ( { } ) , [ ] )
4579 const isTabletOrMobile = useMediaQuery ( { query : '(max-width: 1224px)' } )
4680 const isMobile = useMediaQuery ( { maxWidth : 767 } )
4781 const { classes } = styles ( )
48- const [ mauCount , setMauCount ] = useState ( null )
49- const [ tokenCount , setTokenCount ] = useState ( null )
82+ const [ mauCount , setMauCount ] = useState < number | null > ( null )
83+ const [ tokenCount , setTokenCount ] = useState < number | null > ( null )
5084
5185 const [ requestStates , setRequestStates ] = useState ( {
5286 licenseRequested : false ,
5387 clientsRequested : false ,
5488 } )
55- const statData = useSelector ( ( state : any ) => state . mauReducer . stat )
56- const loading = useSelector ( ( state : any ) => state . mauReducer . loading )
57- const clients = useSelector ( ( state : any ) => state . initReducer . clients )
58- const lock = useSelector ( ( state : any ) => state . lockReducer . lockDetail )
59- const { isUserInfoFetched } = useSelector ( ( state : any ) => state . authReducer )
60- const totalClientsEntries = useSelector ( ( state : any ) => state . initReducer . totalClientsEntries )
61- const license = useSelector ( ( state : any ) => state . licenseDetailsReducer . item )
89+ const statData = useSelector ( ( state : RootState ) => state . mauReducer . stat )
90+ const loading = useSelector ( ( state : RootState ) => state . mauReducer . loading )
91+ const clients = useSelector ( ( state : RootState ) => state . initReducer . clients )
92+ const lock = useSelector ( ( state : RootState ) => state . lockReducer . lockDetail )
93+ const { isUserInfoFetched } = useSelector ( ( state : RootState ) => state . authReducer )
94+ const totalClientsEntries = useSelector (
95+ ( state : RootState ) => state . initReducer . totalClientsEntries ,
96+ )
97+ const license = useSelector ( ( state : RootState ) => state . licenseDetailsReducer . item )
6298 const serverStatus = useSelector (
6399 ( state : DashboardHealthRootState ) => state . healthReducer . serverStatus ,
64100 )
65101 const serverHealth = useSelector ( ( state : DashboardHealthRootState ) => state . healthReducer . health )
66102 const dbStatus = useSelector ( ( state : DashboardHealthRootState ) => state . healthReducer . dbStatus )
67- const access_token = useSelector ( ( state : any ) => state . authReducer . token ?. access_token )
68- const permissions = useSelector ( ( state : any ) => state . authReducer . permissions )
103+ const access_token = useSelector ( ( state : RootState ) => state . authReducer . token ?. access_token )
104+ const permissions = useSelector ( ( state : RootState ) => state . authReducer . permissions )
69105
70106 const { hasCedarReadPermission, authorizeHelper } = useCedarling ( )
71107 const { navigateToRoute } = useAppNavigation ( )
72- const cedarInitialized = useSelector ( ( state : any ) => state . cedarPermissions ?. initialized )
73- const cedarIsInitializing = useSelector ( ( state : any ) => state . cedarPermissions ?. isInitializing )
108+ const cedarInitialized = useSelector ( ( state : RootState ) => state . cedarPermissions ?. initialized )
109+ const cedarIsInitializing = useSelector (
110+ ( state : RootState ) => state . cedarPermissions ?. isInitializing ,
111+ )
74112
75113 const dashboardResourceId = useMemo ( ( ) => ADMIN_UI_RESOURCES . Dashboard , [ ] )
76114 const dashboardScopes = useMemo (
@@ -108,7 +146,9 @@ function DashboardPage() {
108146 const formattedMonth =
109147 currentMonth > 9 ? currentMonth . toString ( ) : '0' + currentMonth . toString ( )
110148 const yearMonth = currentYear . toString ( ) + formattedMonth
111- const currentMonthData = statData . find ( ( { month } : any ) => month . toString ( ) === yearMonth )
149+ const currentMonthData = statData . find (
150+ ( item : StatDataItem ) => item . month . toString ( ) === yearMonth ,
151+ )
112152
113153 const mau = currentMonthData ?. mau
114154 const token =
@@ -132,8 +172,8 @@ function DashboardPage() {
132172 ! requestStates . licenseRequested
133173 ) {
134174 setRequestStates ( ( prev ) => ( { ...prev , licenseRequested : true } ) )
135- buildPayload ( userAction as any , FETCHING_LICENSE_DETAILS , options as any )
136- dispatch ( getLicenseDetails ( { } as any ) )
175+ buildPayload ( userAction , FETCHING_LICENSE_DETAILS , options as ActionData )
176+ dispatch ( getLicenseDetails ( ) )
137177 }
138178 } , [
139179 access_token ,
@@ -155,8 +195,8 @@ function DashboardPage() {
155195 ! requestStates . clientsRequested
156196 ) {
157197 setRequestStates ( ( prev ) => ( { ...prev , clientsRequested : true } ) )
158- buildPayload ( userAction as any , 'Fetch openid connect clients' , { } as any )
159- dispatch ( getClients ( { action : userAction } as any ) )
198+ buildPayload ( userAction , 'Fetch openid connect clients' , { } as ActionData )
199+ dispatch ( getClients ( ) )
160200 }
161201 } , [
162202 access_token ,
@@ -167,11 +207,6 @@ function DashboardPage() {
167207 userAction ,
168208 ] )
169209
170- const isUp = useCallback ( ( status : any ) => {
171- if ( ! status ) return false
172- return status . toUpperCase ( ) === 'ONLINE' || status . toUpperCase ( ) === 'RUNNING'
173- } , [ ] )
174-
175210 const summaryData = useMemo ( ( ) => {
176211 const baseData = [
177212 {
@@ -191,16 +226,17 @@ function DashboardPage() {
191226 } ,
192227 ]
193228
194- if ( lock && lock . length > 0 ) {
229+ if ( lock && Array . isArray ( lock ) && lock . length > 0 ) {
230+ const lockItem = lock [ 0 ] as LockDetailItem
195231 baseData . push (
196232 {
197233 text : t ( 'dashboard.mau_users' ) ,
198- value : lock [ 0 ] ?. monthly_active_users ?? 0 ,
234+ value : lockItem ?. monthly_active_users ?? 0 ,
199235 icon : < JansLockUsers className = { classes . summaryIcon } style = { { top : '8px' } } /> ,
200236 } ,
201237 {
202238 text : t ( 'dashboard.mau_clients' ) ,
203- value : lock [ 0 ] ?. monthly_active_clients ?? 0 ,
239+ value : lockItem ?. monthly_active_clients ?? 0 ,
204240 icon : < JansLockClients className = { classes . summaryIcon } style = { { top : '8px' } } /> ,
205241 } ,
206242 )
@@ -276,25 +312,32 @@ function DashboardPage() {
276312 const getClassName = useCallback (
277313 ( key : string ) => {
278314 const value = getStatusValue ( key )
279- return isUp ( value ) ? classes . checkText : classes . crossText
315+ if ( ! value ) return classes . crossText
316+ const statusUpper = String ( value ) . toUpperCase ( )
317+ return statusUpper === 'RUNNING' || statusUpper === 'ONLINE'
318+ ? classes . checkText
319+ : classes . crossText
280320 } ,
281- [ getStatusValue , isUp , classes . checkText , classes . crossText ] ,
321+ [ getStatusValue , classes . checkText , classes . crossText ] ,
282322 )
283323
284324 const getStatusText = useCallback (
285325 ( key : string ) => {
286326 const value = getStatusValue ( key )
287- return isUp ( value ) ? 'Running' : 'Down'
327+ if ( ! value ) return 'Unknown'
328+ return value
288329 } ,
289- [ getStatusValue , isUp ] ,
330+ [ getStatusValue ] ,
290331 )
291332
292333 const getStatusIcon = useCallback (
293334 ( key : string ) => {
294335 const value = getStatusValue ( key )
295- return isUp ( value ) ? CheckIcon : CrossIcon
336+ if ( ! value ) return CrossIcon
337+ const statusUpper = String ( value ) . toUpperCase ( )
338+ return statusUpper === 'RUNNING' || statusUpper === 'ONLINE' ? CheckIcon : CrossIcon
296339 } ,
297- [ getStatusValue , isUp ] ,
340+ [ getStatusValue ] ,
298341 )
299342
300343 const StatusCard = useMemo (
@@ -351,7 +394,7 @@ function DashboardPage() {
351394 dispatch (
352395 auditLogoutLogs ( {
353396 message : 'Logging out due to insufficient permissions for Admin UI access.' ,
354- } as any ) ,
397+ } ) ,
355398 )
356399 } else {
357400 navigateToRoute ( ROUTES . LOGOUT )
0 commit comments