Skip to content

Commit 5a6b29d

Browse files
Merge pull request #1834 from KelvinTegelaar/dev
Dev to release
2 parents d3d3401 + 34a8a1a commit 5a6b29d

File tree

25 files changed

+744
-238
lines changed

25 files changed

+744
-238
lines changed

public/version_latest.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4.4.0
1+
4.5.0

src/_nav.js

Lines changed: 41 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,45 @@ const _nav = [
246246
},
247247
],
248248
},
249+
{
250+
component: CNavGroup,
251+
name: 'GDAP Management',
252+
section: 'Settings',
253+
to: '/cipp/gdap',
254+
icon: <FontAwesomeIcon icon={faUserShield} className="nav-icon" />,
255+
items: [
256+
{
257+
component: CNavItem,
258+
name: 'Role Wizard',
259+
to: '/tenant/administration/gdap-role-wizard',
260+
},
261+
{
262+
component: CNavItem,
263+
name: 'GDAP Roles',
264+
to: '/tenant/administration/gdap-roles',
265+
},
266+
{
267+
component: CNavItem,
268+
name: 'Migration Wizard',
269+
to: '/tenant/administration/gdap',
270+
},
271+
{
272+
component: CNavItem,
273+
name: 'GDAP Migration Status',
274+
to: '/tenant/administration/gdap-status',
275+
},
276+
{
277+
component: CNavItem,
278+
name: 'Invite Wizard',
279+
to: '/tenant/administration/gdap-invite',
280+
},
281+
{
282+
component: CNavItem,
283+
name: 'GDAP Relationships',
284+
to: '/tenant/administration/gdap-relationships',
285+
},
286+
],
287+
},
249288
{
250289
component: CNavGroup,
251290
name: 'Reports',
@@ -293,15 +332,6 @@ const _nav = [
293332
},
294333
],
295334
},
296-
// Coming in another branch (heads up)
297-
//{
298-
//component: CNavGroup,
299-
//name: 'Vulnerabilities',
300-
//section: 'Security & Compliance',
301-
//to: '/security/vulnerabilities',
302-
//icon: <FontAwesomeIcon icon={faChessRook} className="nav-icon" />,
303-
//items: [],
304-
//},
305335
{
306336
component: CNavGroup,
307337
name: 'Defender',
@@ -678,56 +708,15 @@ const _nav = [
678708
name: 'Logbook',
679709
to: '/cipp/logs',
680710
},
681-
682711
{
683712
component: CNavItem,
684713
name: 'SAM Setup Wizard',
685714
to: '/cipp/setup',
686715
},
687-
],
688-
},
689-
{
690-
component: CNavGroup,
691-
name: 'GDAP Migration',
692-
section: 'Settings',
693-
to: '/cipp/gdap',
694-
icon: <FontAwesomeIcon icon={faUserShield} className="nav-icon" />,
695-
items: [
696-
{
697-
component: CNavItem,
698-
name: 'Role Wizard',
699-
to: '/tenant/administration/gdap-role-wizard',
700-
},
701-
{
702-
component: CNavItem,
703-
name: 'GDAP Roles',
704-
to: '/tenant/administration/gdap-roles',
705-
},
706-
{
707-
component: CNavItem,
708-
name: 'Migration Wizard',
709-
to: '/tenant/administration/gdap',
710-
},
711-
{
712-
component: CNavItem,
713-
name: 'GDAP Migration Status',
714-
to: '/tenant/administration/gdap-status',
715-
},
716-
{
717-
component: CNavItem,
718-
name: 'Invite Wizard',
719-
to: '/tenant/administration/gdap-invite',
720-
},
721-
{
722-
component: CNavItem,
723-
name: 'GDAP Relationships',
724-
to: '/tenant/administration/gdap-relationships',
725-
},
726716
{
727717
component: CNavItem,
728-
name: 'Documentation',
729-
href: 'https://cipp.app/docs/user/usingcipp/GDAP/migration',
730-
target: '_blank',
718+
name: 'Log Out',
719+
to: '/logout',
731720
},
732721
],
733722
},
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React from 'react'
2+
import { CButton } from '@coreui/react'
3+
import { ModalService } from '../utilities'
4+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
5+
import { faCheckCircle } from '@fortawesome/free-solid-svg-icons'
6+
import { cellGenericFormatter } from '../tables/CellGenericFormat'
7+
8+
export default function TableModalButton({ data, title, className }) {
9+
const handleTable = (data) => {
10+
const QueryColumns = []
11+
const columns = Object.keys(data[0]).map((key) => {
12+
QueryColumns.push({
13+
name: key,
14+
selector: (row) => row[key], // Accessing the property using the key
15+
sortable: true,
16+
exportSelector: key,
17+
cell: cellGenericFormatter(),
18+
})
19+
})
20+
ModalService.open({
21+
data: data,
22+
componentType: 'table',
23+
componentProps: {
24+
columns: QueryColumns,
25+
keyField: 'id',
26+
},
27+
title: title,
28+
size: 'lg',
29+
})
30+
}
31+
const buttonClass = 'btn ' + className
32+
33+
return (
34+
<CButton className={buttonClass} onClick={() => handleTable(data)}>
35+
<>
36+
{title} ({data.length})
37+
</>
38+
</CButton>
39+
)
40+
}

src/components/buttons/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import ExportCsvButton from 'src/components/buttons/CsvButton'
22
import ExportPDFButton from 'src/components/buttons/PdfButton'
33
import TitleButton from 'src/components/buttons/TitleButton'
4+
import TableModalButton from 'src/components/buttons/TableModalButton'
45

5-
export { ExportCsvButton, ExportPDFButton, TitleButton }
6+
export { ExportCsvButton, ExportPDFButton, TitleButton, TableModalButton }

src/components/tables/CellTable.js

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,22 @@ import { CButton } from '@coreui/react'
33
import { ModalService } from '../utilities'
44
import { CBadge } from '@coreui/react'
55
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
6-
import { faCheckCircle } from '@fortawesome/free-solid-svg-icons'
6+
import { faCheckCircle, faTimesCircle } from '@fortawesome/free-solid-svg-icons' // 1. Import the required FontAwesome icon
77
import { cellGenericFormatter } from './CellGenericFormat'
88

9-
export default function cellTable(row, column, propertyName) {
9+
export default function cellTable(
10+
row,
11+
column,
12+
propertyName,
13+
checkWhenZero = false,
14+
crossWhenZero = false,
15+
) {
1016
const handleTable = ({ row }) => {
1117
const QueryColumns = []
1218
const columns = Object.keys(row[propertyName][0]).map((key) => {
1319
QueryColumns.push({
1420
name: key,
15-
selector: (row) => row[key], // Accessing the property using the key
21+
selector: (row) => row[key],
1622
sortable: true,
1723
exportSelector: key,
1824
cell: cellGenericFormatter(),
@@ -29,8 +35,24 @@ export default function cellTable(row, column, propertyName) {
2935
size: 'lg',
3036
})
3137
}
38+
//if the row propertyName is a bool, then return a check or cross
39+
if (typeof row[propertyName] === 'boolean') {
40+
if (row[propertyName]) {
41+
return <FontAwesomeIcon icon={faCheckCircle} className="text-success" />
42+
}
43+
return <FontAwesomeIcon icon={faTimesCircle} className="text-danger" />
44+
}
3245

33-
if (!row[propertyName] || !Array.isArray(row[propertyName]) || row.length === 0) {
46+
if (!row[propertyName] || !Array.isArray(row[propertyName]) || row[propertyName].length === 0) {
47+
if (row[propertyName] === undefined) {
48+
return <FontAwesomeIcon icon={faCheckCircle} className="text-success" />
49+
}
50+
if (checkWhenZero) {
51+
return <FontAwesomeIcon icon={faCheckCircle} className="text-success" />
52+
}
53+
if (crossWhenZero) {
54+
return <FontAwesomeIcon icon={faTimesCircle} className="text-danger" />
55+
}
3456
return <FontAwesomeIcon icon={faCheckCircle} className="text-success" />
3557
}
3658

@@ -41,6 +63,8 @@ export default function cellTable(row, column, propertyName) {
4163
)
4264
}
4365

44-
export const cellTableFormatter = (propertyName) => (row, index, column, id) => {
45-
return cellTable(row, column, propertyName)
46-
}
66+
export const cellTableFormatter =
67+
(propertyName, checkWhenZero = false, crossWhenZero = false) =>
68+
(row, index, column, id) => {
69+
return cellTable(row, column, propertyName, checkWhenZero, crossWhenZero)
70+
}

src/components/tables/CippTable.js

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -79,27 +79,23 @@ FilterComponent.propTypes = {
7979
filterlist: PropTypes.arrayOf(PropTypes.object),
8080
onFilterPreset: PropTypes.func,
8181
}
82+
const compareValues = (a, b) => {
83+
if (a === null) return 1
84+
if (b === null) return -1
85+
if (typeof a === 'number' && typeof b === 'number') return a - b
86+
if (typeof a === 'boolean' && typeof b === 'boolean') return a === b ? 0 : a ? -1 : 1
87+
return String(a).localeCompare(String(b), 'en', { numeric: true })
88+
}
8289

8390
const customSort = (rows, selector, direction) => {
8491
return rows.sort((a, b) => {
85-
// use the selector to resolve your field names by passing the sort comparitors
86-
let aField
87-
let bField
88-
89-
aField = selector(a)
90-
bField = selector(b)
91-
92-
let comparison = 0
93-
94-
if (aField?.toString().localeCompare(bField, 'en', { numeric: true }) > 0) {
95-
comparison = 1
96-
} else if (aField?.toString().localeCompare(bField, 'en', { numeric: true }) < 0) {
97-
comparison = -1
98-
}
99-
92+
let aField = selector(a)
93+
let bField = selector(b)
94+
let comparison = compareValues(aField, bField)
10095
return direction === 'desc' ? comparison * -1 : comparison
10196
})
10297
}
98+
10399
export default function CippTable({
104100
data,
105101
isFetching = false,
@@ -115,6 +111,7 @@ export default function CippTable({
115111
isModal = false,
116112
exportFiltered = false,
117113
filterlist,
114+
showFilter = true,
118115
tableProps: {
119116
keyField = 'id',
120117
theme = 'cyberdrain',
@@ -472,6 +469,10 @@ export default function CippTable({
472469
])
473470
}
474471

472+
actions.forEach((action) => {
473+
defaultActions.push(action)
474+
})
475+
475476
if (!disablePDFExport || !disableCSVExport) {
476477
const keys = []
477478
const exportFormatter = {}
@@ -582,9 +583,7 @@ export default function CippTable({
582583
</CDropdown>,
583584
])
584585
}
585-
actions.forEach((action) => {
586-
defaultActions.push(action)
587-
})
586+
588587
defaultActions.push([
589588
<ExportPDFButton
590589
key="export-pdf-action"
@@ -631,15 +630,17 @@ export default function CippTable({
631630
return (
632631
<>
633632
<div className="w-100 d-flex justify-content-start">
634-
<FilterComponent
635-
onFilter={(e) => setFilterText(e.target.value)}
636-
onFilterPreset={(e) => {
637-
setFilterText(e)
638-
}}
639-
onClear={handleClear}
640-
filterText={filterText}
641-
filterlist={filterlist}
642-
/>
633+
{showFilter && (
634+
<FilterComponent
635+
onFilter={(e) => setFilterText(e.target.value)}
636+
onFilterPreset={(e) => {
637+
setFilterText(e)
638+
}}
639+
onClear={handleClear}
640+
filterText={filterText}
641+
filterlist={filterlist}
642+
/>
643+
)}
643644
{defaultActions}
644645
</div>
645646
</>

src/components/utilities/UniversalSearch.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const UniversalSearch = React.forwardRef(
1717

1818
const handleKeyDown = (event) => {
1919
if (event.key === 'Enter') {
20-
// on enter key, start the search
20+
// on enter key, start the searchs
2121
getSearchItems({ path: `/api/ExecUniversalSearch?name=${searchValue}` })
2222
}
2323
}
@@ -80,7 +80,9 @@ const ResultsRow = ({ match }) => {
8080

8181
const handleClick = () => {
8282
dispatch(hideSwitcher())
83-
navigate(`/identity/administration/users?customerId=${match._tenantId}`)
83+
navigate(
84+
`/identity/administration/users?customerId=${match._tenantId}&tableFilter=${match.userPrincipalName}`,
85+
)
8486
}
8587

8688
return (

src/data/standards.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,13 @@
267267
},
268268
"label": "Set Outbound Spam Alert e-mail"
269269
},
270+
{
271+
"name": "standards.SafeSendersDisable",
272+
"cat": "Exchange",
273+
"helpText": "",
274+
"addedComponent": null,
275+
"label": "Remove Safe Senders to prevent SPF bypass"
276+
},
270277
{
271278
"name": "standards.DisableSharedMailbox",
272279
"cat": "Exchange",
@@ -332,7 +339,7 @@
332339
},
333340
{
334341
"name": "standards.ActivityBasedTimeout",
335-
"cat": "SharePoint",
342+
"cat": "Global",
336343
"helpText": "",
337344
"addedComponent": null,
338345
"label": "Enable 1 hour Activity based Timeout"
@@ -415,6 +422,12 @@
415422
},
416423
"label": "Set inactive device retirement days"
417424
},
425+
{
426+
"name": "standards.intuneRequireMFA",
427+
"cat": "Intune",
428+
"helpText": "",
429+
"label": "Require Multifactor Authentication to register or join devices with Microsoft Entra"
430+
},
418431
{
419432
"name": "standards.sharingCapability.Enabled",
420433
"cat": "SharePoint",

0 commit comments

Comments
 (0)