Skip to content

Commit 81730c2

Browse files
Merge pull request #1908 from rvdwegen/dev
Add app consent requests page
2 parents 07921d9 + e6b9dc7 commit 81730c2

File tree

3 files changed

+174
-0
lines changed

3 files changed

+174
-0
lines changed

src/_nav.jsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ const _nav = [
137137
name: 'Enterprise Applications',
138138
to: '/tenant/administration/enterprise-apps',
139139
},
140+
{
141+
component: CNavItem,
142+
name: 'App Consent Requests',
143+
to: '/tenant/administration/app-consent-requests',
144+
},
140145
{
141146
component: CNavItem,
142147
name: 'Tenant Offboarding',

src/routes.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,9 @@ const ServiceHealth = React.lazy(() => import('src/views/tenant/administration/S
226226
const EnterpriseApplications = React.lazy(() =>
227227
import('src/views/tenant/administration/ListEnterpriseApps'),
228228
)
229+
const AppConsentRequests = React.lazy(() =>
230+
import('src/views/tenant/administration/ListAppConsentRequests'),
231+
)
229232
const MailboxRestoreWizard = React.lazy(() =>
230233
import('src/views/email-exchange/tools/MailboxRestoreWizard'),
231234
)
@@ -324,6 +327,11 @@ const routes = [
324327
name: 'Enterprise Applications',
325328
component: EnterpriseApplications,
326329
},
330+
{
331+
path: '/tenant/administration/app-consent-requests',
332+
name: 'App Consent Requests',
333+
component: AppConsentRequests,
334+
},
327335
{
328336
path: '/tenant/conditional/list-policies',
329337
name: 'Conditional Access',
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/* eslint-disable import/no-unresolved */
2+
import React, { useState, useEffect } from 'react'
3+
import { useSelector } from 'react-redux'
4+
import { CButton } from '@coreui/react'
5+
import { faEllipsisV } from '@fortawesome/free-solid-svg-icons'
6+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
7+
import { CippPageList } from 'src/components/layout'
8+
import { cellDateFormatter, cellNullTextFormatter } from 'src/components/tables'
9+
import { CippActionsOffcanvas } from 'src/components/utilities'
10+
import { CellTip } from 'src/components/tables/CellGenericFormat'
11+
12+
const AppConsentRequests = () => {
13+
const [tenantColumnSet, setTenantColumn] = useState(true)
14+
const tenant = useSelector((state) => state.app.currentTenant)
15+
useEffect(() => {
16+
if (tenant.defaultDomainName === 'AllTenants') {
17+
setTenantColumn(false)
18+
}
19+
if (tenant.defaultDomainName !== 'AllTenants') {
20+
setTenantColumn(true)
21+
}
22+
}, [tenant.defaultDomainName, tenantColumnSet])
23+
24+
const columns = [
25+
{
26+
name: 'Tenant',
27+
selector: (row) => row['Tenant'],
28+
sortable: true,
29+
cell: (row) => CellTip(row['Tenant']),
30+
exportSelector: 'Tenant',
31+
omit: tenantColumnSet,
32+
},
33+
{
34+
name: 'Retrieval Status',
35+
selector: (row) => row['CippStatus'],
36+
sortable: true,
37+
cell: (row) => CellTip(row['CippStatus']),
38+
exportSelector: 'CippStatus',
39+
omit: tenantColumnSet,
40+
},
41+
{
42+
name: 'Application Name',
43+
selector: (row) => row.appDisplayName,
44+
sortable: true,
45+
exportSelector: 'appDisplayName',
46+
},
47+
{
48+
name: 'Requester',
49+
selector: (row) => row.requestUser,
50+
sortable: true,
51+
exportSelector: 'requestUser',
52+
},
53+
{
54+
name: 'Reason',
55+
selector: (row) => row.requestReason,
56+
sortable: true,
57+
exportSelector: 'requestReason',
58+
},
59+
{
60+
name: 'Status',
61+
selector: (row) => row.requestStatus,
62+
sortable: true,
63+
exportSelector: 'requestStatus',
64+
},
65+
{
66+
name: 'Request Date',
67+
selector: (row) => row.requestDate,
68+
sortable: true,
69+
exportSelector: 'requestDate',
70+
cell: cellDateFormatter({ format: 'short' }),
71+
},
72+
{
73+
name: 'Actions',
74+
cell: Offcanvas,
75+
maxWidth: '80px',
76+
},
77+
]
78+
return (
79+
<div>
80+
<CippPageList
81+
capabilities={{ allTenants: true, helpContext: 'https://google.com' }}
82+
title="App Consent Requests"
83+
tenantSelector={false}
84+
datatable={{
85+
filterlist: [
86+
{
87+
filterName: 'Pending consent requests',
88+
filter: 'Complex: requestStatus eq InProgress',
89+
},
90+
{
91+
filterName: 'Expired consent requests',
92+
filter: 'Complex: requestStatus eq Expired',
93+
},
94+
{
95+
filterName: 'Completed consent requests',
96+
filter: 'Complex: requestStatus eq Completed',
97+
},
98+
],
99+
tableProps: {
100+
selectableRows: true,
101+
},
102+
keyField: 'id',
103+
columns,
104+
reportName: `App Consent Requests`,
105+
path: '/api/ListAppConsentRequests',
106+
params: {
107+
TenantFilter: tenant?.defaultDomainName,
108+
},
109+
}}
110+
/>
111+
</div>
112+
)
113+
}
114+
115+
export default AppConsentRequests
116+
117+
const Offcanvas = (row, rowIndex, formatExtraData) => {
118+
const tenant = useSelector((state) => state.app.currentTenant)
119+
const [ocVisible, setOCVisible] = useState(false)
120+
const entraLink = `https://entra.microsoft.com/${tenant.defaultDomainName}/#view/Microsoft_AAD_IAM/StartboardApplicationsMenuBlade/~/AccessRequests`
121+
122+
return (
123+
<>
124+
<CButton size="sm" color="link" onClick={() => setOCVisible(true)}>
125+
<FontAwesomeIcon icon={faEllipsisV} />
126+
</CButton>
127+
<CippActionsOffcanvas
128+
title="Request Information"
129+
extendedInfo={[
130+
{ label: 'Requester', value: `${row.requestUser ?? ' '}` },
131+
{ label: 'Application Name', value: `${row.appDisplayName ?? ' '}` },
132+
{ label: 'Application Id', value: `${row.appId ?? ' '}` },
133+
{ label: 'Reason', value: `${row.requestReason ?? ' '}` },
134+
{ label: 'Status', value: `${row.requestStatus ?? ' '}` },
135+
{ label: 'Reviewed by', value: `${row.reviewedBy ?? ' '}` },
136+
{ label: 'Reviewed reason', value: `${row.reviewedJustification ?? ' '}` },
137+
]}
138+
actions={[
139+
{
140+
label: 'Review in Entra',
141+
link: entraLink,
142+
color: 'info',
143+
target: '_blank',
144+
external: true,
145+
},
146+
{
147+
label: 'Approve in Entra',
148+
link: row.consentUrl,
149+
color: 'info',
150+
target: '_blank',
151+
external: true,
152+
},
153+
]}
154+
placement="end"
155+
visible={ocVisible}
156+
id={row.id}
157+
hideFunction={() => setOCVisible(false)}
158+
/>
159+
</>
160+
)
161+
}

0 commit comments

Comments
 (0)