Skip to content

Commit b4e6f5f

Browse files
Merge pull request #2278 from KelvinTegelaar/dev
Dev to release
2 parents f052bc9 + eb56d15 commit b4e6f5f

27 files changed

+1219
-166
lines changed

Tools/Update-Version.ps1

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Param($Version)
2+
Set-Location (Get-Item $PSScriptRoot).Parent.FullName
3+
$Files = @('version_latest.txt', 'public/version_latest.txt')
4+
foreach ($File in $Files) {
5+
Set-Content $File -Value $Version
6+
}
7+
8+
$Package = Get-Content package.json | ConvertFrom-Json
9+
$Package.version = $Version
10+
$Package | ConvertTo-Json -Depth 10 | Set-Content package.json

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cipp",
3-
"version": "5.3.2",
3+
"version": "5.4.0",
44
"description": "The CyberDrain Improved Partner Portal is a portal to help manage administration for Microsoft Partners.",
55
"homepage": "https://cipp.app/",
66
"bugs": {

public/version_latest.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5.3.2
1+
5.4.0

src/_nav.jsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,9 +481,19 @@ const _nav = [
481481
},
482482
{
483483
component: CNavItem,
484-
name: 'MEM Policies',
484+
name: 'Configuration Policies',
485485
to: '/endpoint/MEM/list-policies',
486486
},
487+
{
488+
component: CNavItem,
489+
name: 'Compliance Policies',
490+
to: '/endpoint/MEM/list-compliance-policies',
491+
},
492+
{
493+
component: CNavItem,
494+
name: 'Protection Policies',
495+
to: '/endpoint/MEM/list-appprotection-policies',
496+
},
487497
{
488498
component: CNavItem,
489499
name: 'Apply Policy',
@@ -612,6 +622,11 @@ const _nav = [
612622
name: 'Mailbox Restores',
613623
to: '/email/tools/mailbox-restores',
614624
},
625+
{
626+
component: CNavItem,
627+
name: 'Mail Test',
628+
to: '/email/tools/mail-test',
629+
},
615630
],
616631
},
617632
{

src/components/forms/RFFComponents.jsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import Select from 'react-select'
1414
import Creatable, { useCreatable } from 'react-select/creatable'
1515
import { Field } from 'react-final-form'
1616
import { FieldArray } from 'react-final-form-arrays'
17-
import React, { useState, useMemo, useRef } from 'react'
17+
import React, { useState, useMemo } from 'react'
1818
import PropTypes from 'prop-types'
1919
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
2020
import { debounce } from 'lodash-es'
@@ -37,6 +37,7 @@ const sharedPropTypes = {
3737
error: PropTypes.any,
3838
}),
3939
}),
40+
onClick: PropTypes.func,
4041
}
4142

4243
export const RFFCFormFeedback = ({ meta }) => {
@@ -54,7 +55,14 @@ RFFCFormFeedback.propTypes = {
5455
}),
5556
}
5657

57-
export const RFFCFormCheck = ({ name, label, className = 'mb-3', validate, disabled = false }) => {
58+
export const RFFCFormCheck = ({
59+
name,
60+
label,
61+
className = 'mb-3',
62+
validate,
63+
disabled = false,
64+
onClick,
65+
}) => {
5866
return (
5967
<Field name={name} type="checkbox" validate={validate}>
6068
{({ input, meta }) => (
@@ -67,6 +75,7 @@ export const RFFCFormCheck = ({ name, label, className = 'mb-3', validate, disab
6775
disabled={disabled}
6876
id={name}
6977
label={label}
78+
onClick={onClick}
7079
/>
7180
<RFFCFormFeedback meta={meta} />
7281
</div>
@@ -92,6 +101,7 @@ export const RFFCFormSwitch = ({
92101
validate,
93102
disabled = false,
94103
initialValue,
104+
onClick,
95105
}) => {
96106
return (
97107
<Field initialValue={initialValue} name={name} type="checkbox" validate={validate}>
@@ -113,6 +123,7 @@ export const RFFCFormSwitch = ({
113123
disabled={disabled}
114124
id={name}
115125
label={label}
126+
onClick={onClick}
116127
/>
117128
{input.value && <RFFCFormFeedback meta={meta} />}
118129
<sub>{sublabel}</sub>
@@ -239,6 +250,7 @@ export const RFFCFormRadio = ({
239250
className = 'mb-3',
240251
validate,
241252
disabled = false,
253+
onClick,
242254
}) => {
243255
return (
244256
<Field name={name} type="radio" value={value} validate={validate}>
@@ -252,6 +264,7 @@ export const RFFCFormRadio = ({
252264
type="radio"
253265
name={name}
254266
label={label}
267+
onClick={onClick}
255268
/>
256269
<RFFCFormFeedback meta={meta} />
257270
</div>

src/components/tables/CellTable.jsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ export default function cellTable(
2121
}
2222

2323
if (!Array.isArray(columnProp) && typeof columnProp === 'object') {
24-
columnProp = [columnProp]
24+
columnProp = Object.keys(columnProp).map((key) => {
25+
return {
26+
[key]: columnProp[key],
27+
}
28+
})
2529
}
2630

2731
if (Array.isArray(columnProp) && typeof columnProp[0] !== 'object') {

src/components/tables/CippTable.jsx

Lines changed: 69 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ import {
3333
import { cellGenericFormatter } from './CellGenericFormat'
3434
import { ModalService } from '../utilities'
3535
import { useLazyGenericGetRequestQuery, useLazyGenericPostRequestQuery } from 'src/store/api/app'
36-
import { debounce, update } from 'lodash-es'
36+
import { debounce } from 'lodash-es'
3737
import { useSearchParams } from 'react-router-dom'
3838
import CopyToClipboard from 'react-copy-to-clipboard'
3939
import { setDefaultColumns } from 'src/store/features/app'
40-
import { end } from '@popperjs/core'
40+
import M365Licenses from 'src/data/M365Licenses'
4141

4242
const FilterComponent = ({ filterText, onFilter, onClear, filterlist, onFilterPreset }) => (
4343
<>
@@ -277,28 +277,29 @@ export default function CippTable({
277277
debounceSetGraphFilter(query)
278278
return data
279279
} else if (filterText.startsWith('Complex:')) {
280-
const conditions = filterText.slice(9).split(';')
280+
// Split conditions by ';' and 'or', and trim spaces
281+
const conditions = filterText
282+
.slice(9)
283+
.split(/\s*or\s*|\s*;\s*/i) // Split by 'or' or ';', case insensitive, with optional spaces
284+
.map((condition) => condition.trim())
281285

282-
return conditions.reduce((filteredData, condition) => {
283-
const match = condition.trim().match(/(\w+)\s*(eq|ne|like|notlike|gt|lt)\s*(.+)/)
286+
return data.filter((item) => {
287+
// Check if any condition is met for the item
288+
return conditions.some((condition) => {
289+
const match = condition.match(/(\w+)\s*(eq|ne|like|notlike|gt|lt)\s*(.+)/)
284290

285-
if (!match) {
286-
return filteredData // Keep the current filtered data as is
287-
}
291+
if (!match) return false
288292

289-
let [property, operator, value] = match.slice(1)
290-
value = escapeRegExp(value) // Escape special characters
293+
let [property, operator, value] = match.slice(1)
294+
value = escapeRegExp(value) // Escape special characters
291295

292-
return filteredData.filter((item) => {
293-
// Find the actual key in the item that matches the property (case insensitive)
294296
const actualKey = Object.keys(item).find(
295297
(key) => key.toLowerCase() === property.toLowerCase(),
296298
)
297299

298300
if (!actualKey) {
299-
//set the error message so the user understands the key is not found.
300301
console.error(`FilterError: Property "${property}" not found.`)
301-
return false // Keep the item if the property is not found
302+
return false
302303
}
303304

304305
switch (operator) {
@@ -315,17 +316,19 @@ export default function CippTable({
315316
case 'lt':
316317
return parseFloat(item[actualKey]) < parseFloat(value)
317318
default:
318-
return true
319+
return false // Should not reach here normally
319320
}
320321
})
321-
}, data)
322+
})
322323
} else {
323324
return data.filter(
324325
(item) => JSON.stringify(item).toLowerCase().indexOf(filterText.toLowerCase()) !== -1,
325326
)
326327
}
327328
}
328329

330+
// Helper functions like `debounce` and `escapeRegExp` should be defined somewhere in your code
331+
// For example, a simple escapeRegExp function could be:
329332
const filteredItems = Array.isArray(data) ? filterData(data, filterText) : []
330333

331334
const applyFilter = (e) => {
@@ -630,74 +633,64 @@ export default function CippTable({
630633
return null
631634
})
632635

633-
var exportData = filteredItems
634-
635-
var filtered =
636-
Array.isArray(exportData) && exportData.length > 0
637-
? exportData.map((obj) =>
638-
// eslint-disable-next-line no-sequences
639-
/* keys.reduce((acc, curr) => ((acc[curr] = obj[curr]), acc), {}),*/
640-
keys.reduce((acc, curr) => {
641-
const key = curr.split('/')
642-
if (key.length > 1) {
643-
let property = obj
644-
for (let x = 0; x < key.length; x++) {
645-
if (
646-
Object.prototype.hasOwnProperty.call(property, key[x]) &&
647-
property[key[x]] !== null
648-
) {
649-
property = property[key[x]]
650-
} else {
651-
property = 'n/a'
652-
break
653-
}
654-
}
655-
acc[curr] = property
656-
} else {
657-
if (typeof exportFormatter[curr] === 'function') {
658-
acc[curr] = exportFormatter[curr]({ cell: obj[curr] })
659-
} else {
660-
acc[curr] = obj[curr]
661-
}
662-
}
663-
return acc
664-
}, {}),
665-
)
666-
: []
636+
// Define the flatten function
637+
const flatten = (obj, prefix = '') => {
638+
return Object.keys(obj).reduce((output, key) => {
639+
const newKey = prefix ? `${prefix}.${key}` : key
640+
const value = obj[key] === null ? '' : obj[key]
667641

668-
const flatten = (obj, prefix) => {
669-
let output = {}
670-
for (let k in obj) {
671-
let val = obj[k]
672-
if (val === null) {
673-
val = ''
674-
}
675-
const newKey = prefix ? prefix + '.' + k : k
676-
if (typeof val === 'object') {
677-
if (Array.isArray(val)) {
678-
const { ...arrToObj } = val
679-
const newObj = flatten(arrToObj, newKey)
680-
output = { ...output, ...newObj }
681-
} else {
682-
const newObj = flatten(val, newKey)
683-
output = { ...output, ...newObj }
684-
}
642+
if (typeof value === 'object' && !Array.isArray(value)) {
643+
Object.assign(output, flatten(value, newKey))
685644
} else {
686-
output = { ...output, [newKey]: val }
645+
output[newKey] = value
687646
}
688-
}
689-
return output
647+
return output
648+
}, {})
690649
}
691-
filtered = filtered.map((item) => flatten(item))
692650

693-
let dataFlat
651+
// Define the applyFormatter function
652+
const applyFormatter = (obj) => {
653+
return Object.keys(obj).reduce((acc, key) => {
654+
const formatter = exportFormatter[key]
655+
// Since the keys after flattening will be dot-separated, we need to adjust this to support nested keys if necessary.
656+
const keyParts = key.split('.')
657+
const finalKeyPart = keyParts[keyParts.length - 1]
658+
const formattedValue =
659+
typeof formatter === 'function' ? formatter({ cell: obj[key] }) : obj[key]
660+
acc[key] = formattedValue
661+
return acc
662+
}, {})
663+
}
694664

695-
if (Array.isArray(data)) {
696-
dataFlat = data.map((item) => flatten(item))
697-
} else {
698-
dataFlat = []
665+
// Process exportData function
666+
const processExportData = (exportData, selectedColumns) => {
667+
//filter out the columns that are not selected via selectedColumns
668+
exportData = exportData.map((item) => {
669+
return Object.keys(item)
670+
.filter((key) => selectedColumns.find((o) => o.exportSelector === key))
671+
.reduce((obj, key) => {
672+
obj[key] = item[key]
673+
return obj
674+
}, {})
675+
})
676+
return Array.isArray(exportData) && exportData.length > 0
677+
? exportData.map((obj) => {
678+
const flattenedObj = flatten(obj)
679+
return applyFormatter(flattenedObj)
680+
})
681+
: []
699682
}
700683

684+
// Applying the processExportData function to both filteredItems and data
685+
var filtered = processExportData(filteredItems, updatedColumns)
686+
687+
// Adjusted dataFlat processing to include formatting
688+
let dataFlat = Array.isArray(data)
689+
? data.map((item) => {
690+
const flattenedItem = flatten(item)
691+
return applyFormatter(flattenedItem)
692+
})
693+
: []
701694
if (!disablePDFExport) {
702695
if (dynamicColumns === true) {
703696
defaultActions.push([

src/components/tables/WizardTableField.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export default class WizardTableField extends React.Component {
7373
selectableRows: true,
7474
onSelectedRowsChange: this.handleSelect,
7575
}}
76+
dynamicColumns={false}
7677
{...props}
7778
/>
7879
)

0 commit comments

Comments
 (0)