@@ -8,6 +8,10 @@ import {
88 CardContent ,
99 CardHeader ,
1010 Chip ,
11+ Dialog ,
12+ DialogActions ,
13+ DialogContent ,
14+ DialogTitle ,
1115 Divider ,
1216 Stack ,
1317 Table ,
@@ -19,7 +23,7 @@ import {
1923 Typography ,
2024 Avatar ,
2125} from '@wso2/oxygen-ui'
22- import { ChevronRight , CheckCircle , XCircle } from '@wso2/oxygen-ui-icons-react'
26+ import { ChevronRight , CheckCircle , Eye , XCircle } from '@wso2/oxygen-ui-icons-react'
2327import { useState } from 'react'
2428import { useTranslation } from 'react-i18next'
2529import { useParams , useNavigate } from 'react-router-dom'
@@ -55,6 +59,26 @@ function formatDuration(durationInSeconds: number | undefined): string {
5559 return `${ hours } h`
5660}
5761
62+ function formatResourcesForModal ( resources : unknown ) : string {
63+ if ( ! resources ) {
64+ return '-'
65+ }
66+
67+ if ( typeof resources === 'string' ) {
68+ try {
69+ return JSON . stringify ( JSON . parse ( resources ) , null , 2 )
70+ } catch {
71+ return resources
72+ }
73+ }
74+
75+ try {
76+ return JSON . stringify ( resources , null , 2 )
77+ } catch {
78+ return String ( resources )
79+ }
80+ }
81+
5882function ConsentDetailsPage ( ) : React . JSX . Element {
5983 const { t } = useTranslation ( 'common' )
6084 const { id } = useParams < { id : string } > ( )
@@ -64,6 +88,8 @@ function ConsentDetailsPage(): React.JSX.Element {
6488 const revokeMutation = useRevokeConsentMutation ( )
6589 const [ approvalDialogOpen , setApprovalDialogOpen ] = useState < boolean > ( false )
6690 const [ revocationDialogOpen , setRevocationDialogOpen ] = useState < boolean > ( false )
91+ const [ resourcesModalOpen , setResourcesModalOpen ] = useState < boolean > ( false )
92+ const [ selectedResourcesJson , setSelectedResourcesJson ] = useState < string > ( '' )
6793
6894 if ( ! id ) {
6995 return (
@@ -454,9 +480,19 @@ function ConsentDetailsPage(): React.JSX.Element {
454480 </ Typography >
455481 </ TableCell >
456482 < TableCell >
457- < Typography variant = "body2" >
458- { authorization . resources ? JSON . stringify ( authorization . resources ) : '-' }
459- </ Typography >
483+ < Button
484+ size = "small"
485+ variant = "contained"
486+ color = "secondary"
487+ startIcon = { < Eye size = { 14 } /> }
488+ disabled = { ! authorization . resources }
489+ onClick = { ( ) => {
490+ setSelectedResourcesJson ( formatResourcesForModal ( authorization . resources ) )
491+ setResourcesModalOpen ( true )
492+ } }
493+ >
494+ { t ( 'consentRegistry.details.actions.viewResources' , 'View Resources' ) }
495+ </ Button >
460496 </ TableCell >
461497 </ TableRow >
462498 ) ) }
@@ -465,6 +501,50 @@ function ConsentDetailsPage(): React.JSX.Element {
465501 </ TableContainer >
466502 </ Card >
467503
504+ < Dialog
505+ open = { resourcesModalOpen }
506+ onClose = { ( ) => {
507+ setResourcesModalOpen ( false )
508+ } }
509+ maxWidth = "md"
510+ fullWidth
511+ >
512+ < DialogTitle sx = { { borderBottom : 1 , borderColor : 'divider' } } >
513+ { t ( 'consentRegistry.details.resourcesModal.title' , 'Authorization Resources' ) }
514+ </ DialogTitle >
515+ < DialogContent sx = { { pt : 2.5 , pb : 2 } } >
516+ < Box
517+ component = "pre"
518+ sx = { {
519+ mb : 0 ,
520+ p : 2 ,
521+ border : 1 ,
522+ borderColor : 'divider' ,
523+ borderRadius : 1 ,
524+ bgcolor : 'background.default' ,
525+ color : 'text.primary' ,
526+ fontSize : '0.8125rem' ,
527+ fontFamily : 'monospace' ,
528+ whiteSpace : 'pre' ,
529+ overflow : 'auto' ,
530+ maxHeight : '60vh' ,
531+ } }
532+ >
533+ { selectedResourcesJson }
534+ </ Box >
535+ </ DialogContent >
536+ < DialogActions sx = { { px : 3 , pb : 3 } } >
537+ < Button
538+ variant = "outlined"
539+ onClick = { ( ) => {
540+ setResourcesModalOpen ( false )
541+ } }
542+ >
543+ { t ( 'consentRegistry.details.resourcesModal.close' , 'Close' ) }
544+ </ Button >
545+ </ DialogActions >
546+ </ Dialog >
547+
468548 { /* Consent Lifecycle Section intentionally have mock data until backend API
469549 provides lifecycle timeline fields. */ }
470550
0 commit comments