Skip to content

Commit 1218013

Browse files
Merge pull request #1243 from KelvinTegelaar/dev
Dev
2 parents 099a087 + ed922b4 commit 1218013

File tree

28 files changed

+1322
-167
lines changed

28 files changed

+1322
-167
lines changed

public/version_latest.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.17.0
1+
2.18.0

src/_nav.js

Lines changed: 56 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
faBus,
1818
faExclamationTriangle,
1919
faUserShield,
20+
faEnvelope,
2021
} from '@fortawesome/free-solid-svg-icons'
2122

2223
const _nav = [
@@ -133,35 +134,6 @@ const _nav = [
133134
},
134135
],
135136
},
136-
{
137-
component: CNavGroup,
138-
name: 'Reports',
139-
section: 'Reports',
140-
to: '/tenant/reports',
141-
icon: <FontAwesomeIcon icon={faChartBar} className="nav-icon" />,
142-
items: [
143-
{
144-
component: CNavItem,
145-
name: 'Graph Explorer',
146-
to: '/tenant/administration/graph-explorer',
147-
},
148-
{
149-
component: CNavItem,
150-
name: 'Licence Report',
151-
to: '/tenant/administration/list-licenses',
152-
},
153-
{
154-
component: CNavItem,
155-
name: 'Consented Applications',
156-
to: '/tenant/administration/application-consent',
157-
},
158-
{
159-
component: CNavItem,
160-
name: 'Service Health',
161-
to: '/tenant/administration/service-health',
162-
},
163-
],
164-
},
165137
{
166138
component: CNavGroup,
167139
name: 'Standards',
@@ -235,6 +207,35 @@ const _nav = [
235207
},
236208
],
237209
},
210+
{
211+
component: CNavGroup,
212+
name: 'Reports',
213+
section: 'Reports',
214+
to: '/tenant/reports',
215+
icon: <FontAwesomeIcon icon={faChartBar} className="nav-icon" />,
216+
items: [
217+
{
218+
component: CNavItem,
219+
name: 'Graph Explorer',
220+
to: '/tenant/administration/graph-explorer',
221+
},
222+
{
223+
component: CNavItem,
224+
name: 'Licence Report',
225+
to: '/tenant/administration/list-licenses',
226+
},
227+
{
228+
component: CNavItem,
229+
name: 'Consented Applications',
230+
to: '/tenant/administration/application-consent',
231+
},
232+
{
233+
component: CNavItem,
234+
name: 'Service Health',
235+
to: '/tenant/administration/service-health',
236+
},
237+
],
238+
},
238239
{
239240
component: CNavTitle,
240241
name: 'Security & Compliance',
@@ -333,7 +334,7 @@ const _nav = [
333334
},
334335
{
335336
component: CNavItem,
336-
name: 'Add WinGet or Store App',
337+
name: 'Add Store App',
337338
to: '/endpoint/applications/add-winget-app',
338339
},
339340
{
@@ -517,7 +518,7 @@ const _nav = [
517518
},
518519
{
519520
component: CNavGroup,
520-
name: 'Transport Rules',
521+
name: 'Transport',
521522
section: 'Transport Rules',
522523
to: '/tenant/administration',
523524
icon: <FontAwesomeIcon icon={faBus} className="nav-icon" />,
@@ -554,6 +555,30 @@ const _nav = [
554555
},
555556
],
556557
},
558+
{
559+
component: CNavGroup,
560+
name: 'Spamfilter',
561+
section: 'Spamfilter',
562+
to: '/tenant/administration',
563+
icon: <FontAwesomeIcon icon={faEnvelope} className="nav-icon" />,
564+
items: [
565+
{
566+
component: CNavItem,
567+
name: 'Spamfilter',
568+
to: '/email/spamfilter/list-spamfilter',
569+
},
570+
{
571+
component: CNavItem,
572+
name: 'Apply Spamfilter Template',
573+
to: '/email/spamfilter/deploy',
574+
},
575+
{
576+
component: CNavItem,
577+
name: 'Templates',
578+
to: '/email/spamfilter/list-templates',
579+
},
580+
],
581+
},
557582
{
558583
component: CNavGroup,
559584
name: 'Reports',

src/components/buttons/PdfButton.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import 'jspdf-autotable'
55
import PropTypes from 'prop-types'
66
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
77
import { faFilePdf } from '@fortawesome/free-solid-svg-icons'
8+
import { useSelector } from 'react-redux'
89

910
function ExportPDFButton(props) {
11+
const base64 = useSelector((state) => state.app.reportImage)
1012
const exportPDF = (pdfData, pdfHeaders, pdfSize = 'A4', reportName = 'report') => {
1113
const unit = 'pt'
1214
const size = pdfSize // Use A1, A2, A3 or A4
1315
const orientation = 'landscape' // portrait or landscape
14-
15-
const marginLeft = 40
1616
const doc = new jsPDF(orientation, unit, size)
1717

1818
doc.setFontSize(10)
@@ -24,16 +24,16 @@ function ExportPDFButton(props) {
2424
}
2525
})
2626

27-
const title = reportName
2827
let content = {
29-
startY: 50,
28+
startY: 100,
3029
columns: headerObj,
3130
body: pdfData,
32-
theme: 'grid',
31+
theme: 'striped',
3332
headStyles: { fillColor: [247, 127, 0] },
3433
}
35-
36-
doc.text(title, marginLeft, 40)
34+
if (base64) {
35+
doc.addImage(base64, 'png', 20, 20, 120, 100)
36+
}
3737
doc.autoTable(content)
3838
doc.save(reportName + '.pdf')
3939
}

src/components/forms/RFFComponents.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ import {
66
CFormSelect,
77
CFormSwitch,
88
CFormTextarea,
9+
CSpinner,
910
} from '@coreui/react'
1011
import Select from 'react-select'
12+
import AsyncSelect from 'react-select/async'
1113
import { Field } from 'react-final-form'
1214
import React from 'react'
1315
import PropTypes from 'prop-types'
16+
import { useRef } from 'react'
1417

1518
/*
1619
wrapper classes for React Final Form with CoreUI
@@ -312,7 +315,7 @@ export const RFFSelectSearch = ({
312315
className="react-select-container"
313316
classNamePrefix="react-select"
314317
{...input}
315-
isClearable={true}
318+
isClearable={false}
316319
name={name}
317320
id={name}
318321
disabled={disabled}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import React from 'react'
2+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
3+
import {
4+
faTimesCircle,
5+
faCheckCircle,
6+
faExclamationCircle,
7+
} from '@fortawesome/free-solid-svg-icons'
8+
import { CellBadge } from 'src/components/tables'
9+
import { CBadge, CTooltip } from '@coreui/react'
10+
11+
const IconWarning = () => <FontAwesomeIcon icon={faExclamationCircle} className="text-warning" />
12+
const IconError = () => <FontAwesomeIcon icon={faTimesCircle} className="text-danger" />
13+
const IconSuccess = () => <FontAwesomeIcon icon={faCheckCircle} className="text-success" />
14+
15+
function nocolour(iscolourless, content) {
16+
if (iscolourless) {
17+
return <span className="no-colour">{content}</span>
18+
}
19+
20+
return content
21+
}
22+
23+
export default function CellBoolean({
24+
cell,
25+
warning = false,
26+
reverse = false,
27+
colourless = false,
28+
noDataIsFalse = false,
29+
}) {
30+
let normalized = cell
31+
if (typeof cell === 'boolean') {
32+
normalized = cell
33+
} else if (typeof cell === 'string') {
34+
if (
35+
cell.toLowerCase() === 'success' ||
36+
cell.toLowerCase() === 'pass' ||
37+
cell.toLowerCase() === 'true'
38+
) {
39+
normalized = true
40+
} else if (cell.toLowerCase() === 'fail' || cell.toLowerCase() === 'false') {
41+
normalized = false
42+
}
43+
}
44+
45+
if (cell === '' && !noDataIsFalse) {
46+
return <CellBadge label="No Data" color="info" />
47+
} else if (colourless && warning && reverse) {
48+
return nocolour(colourless, normalized ? <IconWarning /> : <IconError />)
49+
} else if (!reverse && !warning) {
50+
return nocolour(colourless, normalized ? <IconSuccess /> : <IconError />)
51+
} else if (!reverse && warning) {
52+
return nocolour(colourless, normalized ? <IconSuccess /> : <IconWarning />)
53+
} else if (reverse && !warning) {
54+
return nocolour(colourless, normalized ? <IconError /> : <IconSuccess />)
55+
} else if (reverse && warning) {
56+
return nocolour(colourless, normalized ? <IconWarning /> : <IconSuccess />)
57+
}
58+
}
59+
60+
export function CellTip(cell, overflow = false) {
61+
return (
62+
<CTooltip content={String(cell)}>
63+
<div className="celltip-content-nowrap">{String(cell)}</div>
64+
</CTooltip>
65+
)
66+
}
67+
68+
export const cellGenericFormatter =
69+
({ warning = false, reverse = false, colourless = true, noDataIsFalse } = {}) =>
70+
(row, index, column, id) => {
71+
const cell = column.selector(row)
72+
if (cell === null || cell === undefined || cell.length === 0) {
73+
return <CBadge color="info">No Data</CBadge>
74+
}
75+
if (typeof cell === 'boolean') {
76+
return CellBoolean({ cell, warning, reverse, colourless, noDataIsFalse })
77+
}
78+
if (typeof cell === 'string') {
79+
console.log(cell)
80+
return CellTip(cell)
81+
}
82+
}

src/components/tables/CippTable.js

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ export default function CippTable({
9090
error,
9191
reportName,
9292
columns = [],
93+
dynamicColumns = true,
9394
filterlist,
9495
tableProps: {
9596
keyField = 'id',
@@ -186,48 +187,51 @@ export default function CippTable({
186187
}
187188

188189
if (!disablePDFExport) {
189-
const addColumn = (columnname) => {
190-
var index = columns.length - 1
191-
let alreadyInArray = columns.find((o) => o.exportSelector === columnname)
192-
if (!alreadyInArray) {
193-
columns.splice(index, 0, {
194-
name: columnname,
195-
selector: (row) => row[columnname],
196-
sortable: true,
197-
exportSelector: columnname,
198-
})
199-
} else {
200-
let indexOfExisting = columns.findIndex((o) => o.exportSelector === columnname)
201-
columns = columns.splice(indexOfExisting, 1)
190+
if (dynamicColumns === true) {
191+
const addColumn = (columnname) => {
192+
var index = columns.length - 1
193+
let alreadyInArray = columns.find((o) => o.exportSelector === columnname)
194+
if (!alreadyInArray) {
195+
columns.splice(index, 0, {
196+
name: columnname,
197+
selector: (row) => row[columnname],
198+
sortable: true,
199+
exportSelector: columnname,
200+
})
201+
} else {
202+
let indexOfExisting = columns.findIndex((o) => o.exportSelector === columnname)
203+
columns = columns.splice(indexOfExisting, 1)
204+
}
205+
setUpdatedColumns(Date())
202206
}
203-
setUpdatedColumns(Date())
207+
208+
defaultActions.push([
209+
<CDropdown className="me-2" variant="input-group">
210+
<CDropdownToggle
211+
className="btn btn-primary btn-sm m-1"
212+
size="sm"
213+
style={{
214+
backgroundColor: '#f88c1a',
215+
}}
216+
>
217+
<FontAwesomeIcon icon={faColumns} />
218+
</CDropdownToggle>
219+
<CDropdownMenu>
220+
{dataKeys() &&
221+
dataKeys().map((item, idx) => {
222+
return (
223+
<CDropdownItem key={idx} onClick={() => addColumn(item)}>
224+
{columns.find((o) => o.exportSelector === item) && (
225+
<FontAwesomeIcon icon={faCheck} />
226+
)}{' '}
227+
{item}
228+
</CDropdownItem>
229+
)
230+
})}
231+
</CDropdownMenu>
232+
</CDropdown>,
233+
])
204234
}
205-
defaultActions.push([
206-
<CDropdown className="me-2" variant="input-group">
207-
<CDropdownToggle
208-
className="btn btn-primary btn-sm m-1"
209-
size="sm"
210-
style={{
211-
backgroundColor: '#f88c1a',
212-
}}
213-
>
214-
<FontAwesomeIcon icon={faColumns} />
215-
</CDropdownToggle>
216-
<CDropdownMenu>
217-
{dataKeys() &&
218-
dataKeys().map((item, idx) => {
219-
return (
220-
<CDropdownItem key={idx} onClick={() => addColumn(item)}>
221-
{columns.find((o) => o.exportSelector === item) && (
222-
<FontAwesomeIcon icon={faCheck} />
223-
)}{' '}
224-
{item}
225-
</CDropdownItem>
226-
)
227-
})}
228-
</CDropdownMenu>
229-
</CDropdown>,
230-
])
231235
actions.forEach((action) => {
232236
defaultActions.push(action)
233237
})
@@ -288,7 +292,7 @@ export default function CippTable({
288292
{!isFetching && error && <span>Error loading data</span>}
289293
{!error && (
290294
<div>
291-
{columns.length === updatedColumns.length && (
295+
{(columns.length === updatedColumns.length || !dynamicColumns) && (
292296
<DataTable
293297
customStyles={customStyles}
294298
className="cipp-table"

0 commit comments

Comments
 (0)