Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] dev from KelvinTegelaar:dev #9

Merged
merged 20 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion public/version_latest.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.1.1
5.2.0
10 changes: 10 additions & 0 deletions src/_nav.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ const _nav = [
name: 'Groups',
to: '/identity/administration/groups',
},
{
component: CNavItem,
name: 'Devices',
to: '/identity/administration/devices',
},
{
component: CNavItem,
name: 'Deploy Group Template',
Expand Down Expand Up @@ -737,6 +742,11 @@ const _nav = [
name: 'Logbook',
to: '/cipp/logs',
},
{
component: CNavItem,
name: 'Statistics',
to: '/cipp/statistics',
},
{
component: CNavItem,
name: 'SAM Setup Wizard',
Expand Down
34 changes: 32 additions & 2 deletions src/components/tables/CippTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -389,14 +389,43 @@ export default function CippTable({
}
const newModalBody = {}
for (let [objName, objValue] of Object.entries(modalBody)) {
if (objValue.toString().startsWith('!')) {
if (typeof objValue === 'object' && objValue !== null) {
newModalBody[objName] = {}
for (let [nestedObjName, nestedObjValue] of Object.entries(objValue)) {
if (typeof nestedObjValue === 'string' && nestedObjValue.startsWith('!')) {
newModalBody[objName][nestedObjName] = row[nestedObjValue.replace('!', '')]
} else {
newModalBody[objName][nestedObjName] = nestedObjValue
}
}
} else if (typeof objValue === 'string' && objValue.startsWith('!')) {
newModalBody[objName] = row[objValue.replace('!', '')]
} else {
newModalBody[objName] = objValue
}
}
const NewModalUrl = `${modalUrl.split('?')[0]}?${urlParams.toString()}`
const selectedValue = inputRef.current.value
let additionalFields = {}
if (inputRef.current.nodeName === 'SELECT') {
const selectedItem = dropDownInfo.data.find(
(item) => item[modalDropdown.valueField] === selectedValue,
)
if (selectedItem && modalDropdown.addedField) {
Object.keys(modalDropdown.addedField).forEach((key) => {
additionalFields[key] = selectedItem[modalDropdown.addedField[key]]
})
}
}

const results = await genericPostRequest({
path: NewModalUrl,
values: { ...modalBody, ...newModalBody, ...{ input: inputRef.current.value } },
values: {
...modalBody,
...newModalBody,
...additionalFields,
...{ input: inputRef.current.value },
},
})
resultsarr.push(results)
setMassResults(resultsarr)
Expand Down Expand Up @@ -466,6 +495,7 @@ export default function CippTable({
}

const executeselectedAction = (item) => {
console.log(item)
setModalContent({
item,
})
Expand Down
49 changes: 36 additions & 13 deletions src/components/utilities/CippCodeOffcanvas.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React, { useState } from 'react'
import React, { useState, useEffect } from 'react'
import { CButton, CCallout, CCol, CRow, CSpinner } from '@coreui/react'
import { CippOffcanvas } from 'src/components/utilities'
import { useLazyGenericGetRequestQuery, useLazyGenericPostRequestQuery } from 'src/store/api/app'

import { Editor } from '@monaco-editor/react'
import { useSelector } from 'react-redux'
import PropTypes from 'prop-types'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import CopyToClipboard from 'react-copy-to-clipboard'

function CippCodeOffCanvas({
row,
Expand All @@ -14,11 +16,13 @@ function CippCodeOffCanvas({
type,
title = 'Template JSON',
hideButton = false,
path = `/api/ExecEditTemplate?type=${type}`,
}) {
const [SaveTemplate, templateDetails] = useLazyGenericPostRequestQuery()
const currentTheme = useSelector((state) => state.app.currentTheme)
const [templateData, setFormData] = useState(row)
const [invalidJSON, setInvalid] = useState(false)
const [copied, setCopied] = useState(false)

function handleEditorChange(value, event) {
try {
Expand All @@ -29,6 +33,10 @@ function CippCodeOffCanvas({
}
}

useEffect(() => {
setCopied(false)
}, [setCopied, templateData])

return (
<>
<CippOffcanvas
Expand All @@ -53,18 +61,32 @@ function CippCodeOffCanvas({
<CRow className="mb-3">
<CCol>
{!hideButton && (
<CButton
disabled={invalidJSON}
onClick={() =>
SaveTemplate({
path: `/api/ExecEditTemplate?type=${type}`,
method: 'POST',
values: templateData,
})
}
>
Save changes {templateDetails.isFetching && <CSpinner size="sm" />}
</CButton>
<>
<CButton
disabled={invalidJSON}
onClick={() =>
SaveTemplate({
path: path,
method: 'POST',
values: templateData,
})
}
className="me-2"
>
{templateDetails.isFetching ? (
<CSpinner size="sm" className="me-2" />
) : (
<FontAwesomeIcon icon="save" className="me-2" />
)}
Save changes
</CButton>
<CopyToClipboard text={JSON.stringify(row, null, 2)} onCopy={() => setCopied(true)}>
<CButton disabled={invalidJSON}>
<FontAwesomeIcon icon={copied ? 'check' : 'clipboard'} className="me-2" /> Copy
to Clipboard
</CButton>
</CopyToClipboard>
</>
)}
</CCol>
</CRow>
Expand All @@ -83,6 +105,7 @@ CippCodeOffCanvas.propTypes = {
type: PropTypes.string,
title: PropTypes.string,
hideButton: PropTypes.bool,
path: PropTypes.string,
}

export default CippCodeOffCanvas
2 changes: 1 addition & 1 deletion src/components/utilities/SharedModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function mapBodyComponent({ componentType, data, componentProps }) {
}

const sharedProps = {
componentType: PropTypes.oneOf(['table', 'list', 'text', 'confirm']),
componentType: PropTypes.oneOf(['table', 'list', 'text', 'confirm', 'codeblock']),
componentProps: PropTypes.object,
body: PropTypes.oneOfType([PropTypes.node, PropTypes.element]),
data: PropTypes.any,
Expand Down
10 changes: 10 additions & 0 deletions src/data/standards.json
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,16 @@
"impact": "Low Impact",
"impactColour": "info"
},
{
"name": "standards.MessageExpiration",
"cat": "Exchange Standards",
"tag": ["lowimpact"],
"helpText": "Sets the transport message configuration to timeout a message at 12 hours.",
"addedComponent": [],
"label": "Lower Transport Message Expiration to 12 hours",
"impact": "Low Impact",
"impactColour": "info"
},
{
"name": "standards.AutoExpandArchive",
"cat": "Exchange Standards",
Expand Down
7 changes: 6 additions & 1 deletion src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React from 'react'
const Home = React.lazy(() => import('src/views/home/Home'))
const Logs = React.lazy(() => import('src/views/cipp/Logs'))
const Scheduler = React.lazy(() => import('src/views/cipp/Scheduler'))
const Statistics = React.lazy(() => import('src/views/cipp/Statistics'))
const Users = React.lazy(() => import('src/views/identity/administration/Users'))
const DeletedItems = React.lazy(() => import('src/views/identity/administration/Deleted'))
const ViewBEC = React.lazy(() => import('src/views/identity/administration/ViewBEC'))
Expand Down Expand Up @@ -30,6 +31,8 @@ const EditGroup = React.lazy(() => import('src/views/identity/administration/Edi
const ViewGroup = React.lazy(() => import('src/views/identity/administration/ViewGroup'))
const Roles = React.lazy(() => import('src/views/identity/administration/Roles'))
const Devices = React.lazy(() => import('src/views/endpoint/intune/Devices'))
const allDevices = React.lazy(() => import('src/views/identity/administration/Devices'))

const PageLogOut = React.lazy(() => import('src/views/pages/LogoutRedirect/PageLogOut'))

const Page404 = React.lazy(() => import('src/views/pages/page404/Page404'))
Expand Down Expand Up @@ -242,7 +245,7 @@ const routes = [
{ path: '/home', name: 'Home', component: Home },
{ path: '/cipp/logs', name: 'Logs', component: Logs },
{ path: '/cipp/scheduler', name: 'Scheduler', component: Scheduler },

{ path: '/cipp/statistics', name: 'Statistics', component: Statistics },
{ path: '/cipp/404', name: 'Error', component: Page404 },
{ path: '/cipp/403', name: 'Error', component: Page403 },
{ path: '/cipp/500', name: 'Error', component: Page500 },
Expand All @@ -258,6 +261,8 @@ const routes = [
{ path: '/identity/administration/ViewBec', name: 'View BEC', component: ViewBEC },
{ path: '/identity/administration', name: 'Administration' },
{ path: '/identity/administration/users', name: 'Users', component: Users },
{ path: '/identity/administration/devices', name: 'Devices', component: allDevices },

{ path: '/identity/administration/groups/add', name: 'Add Group', component: AddGroup },
{
path: '/identity/administration/group-templates',
Expand Down
153 changes: 153 additions & 0 deletions src/views/cipp/Statistics.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import React, { useState } from 'react'
import { CippPage } from 'src/components/layout'
import {
CButton,
CCard,
CCardBody,
CCardHeader,
CCardTitle,
CCol,
CCollapse,
CFormInput,
CFormLabel,
CFormSelect,
CRow,
CSpinner,
} from '@coreui/react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faChevronRight, faChevronDown } from '@fortawesome/free-solid-svg-icons'
import { CippTable } from 'src/components/tables'
import { cellGenericFormatter } from 'src/components/tables/CellGenericFormat'
import { useSelector } from 'react-redux'
import { useGenericGetRequestQuery } from 'src/store/api/app'
import { RFFCFormSelect } from 'src/components/forms'

const columns = [
{
name: 'Name',
selector: (row) => row['Name'],
sortable: true,
cell: cellGenericFormatter(),
exportSelector: 'Name',
minWidth: '145px',
maxWidth: '145px',
},
{
name: 'Executions',
selector: (row) => row['ExecutionCount'],
sortable: true,
exportSelector: 'ExecutionCount',
},
{
name: 'Total (seconds)',
selector: (row) => row['TotalSeconds'],
sortable: true,
exportSelector: 'TotalSeconds',
},
{
name: 'Max (seconds)',
selector: (row) => row['MaxSeconds'],
sortable: true,
exportSelector: 'MaxSeconds',
},
{
name: 'Avg (seconds)',
selector: (row) => row['AvgSeconds'],
sortable: true,
exportSelector: 'AvgSeconds',
cell: (row) => Math.round(row['AvgSeconds'] * 100) / 100,
},
]

const Statistics = () => {
const [visibleA, setVisibleA] = useState(false)
const [type, setType] = useState('Functions')
const [interval, setInterval] = useState('Days')
const [time, setTime] = useState(1)
const tenant = useSelector((state) => state.app.currentTenant)
const { data, isFetching, error, isSuccess } = useGenericGetRequestQuery({
path: '/api/ListFunctionStats',
params: {
FunctionType: 'Queue',
Interval: interval,
Time: time,
TenantFilter: tenant?.defaultDomainName,
},
})

return (
<>
<CRow>
<CCol>
<CCard className="options-card">
<CCardHeader>
<CCardTitle className="d-flex justify-content-between">
Options
<CButton
size="sm"
variant="ghost"
className="stretched-link"
onClick={() => setVisibleA(!visibleA)}
>
<FontAwesomeIcon icon={visibleA ? faChevronDown : faChevronRight} />
</CButton>
</CCardTitle>
</CCardHeader>
</CCard>
<CCollapse visible={visibleA}>
<CCard className="options-card">
<CCardHeader></CCardHeader>
<CCardBody>
<CRow>
<CCol>
<CFormLabel>Report</CFormLabel>
<CFormSelect name="Report" onChange={(e) => setType(e.target.value)}>
<option value="Functions">Functions</option>
<option value="Standards">Standards</option>
</CFormSelect>
</CCol>
<CCol>
<div>
<CFormLabel>Interval</CFormLabel>
<CFormSelect name="Interval" onChange={(e) => setInterval(e.target.value)}>
<option value="Minute">Minutes</option>
<option value="Hours">Hours</option>
<option value="Days" selected>
Days
</option>
</CFormSelect>
</div>
<div className="mt-2">
<CFormLabel>Time</CFormLabel>
<CFormInput
name="Time"
onChange={(e) => setTime(e.target.value)}
defaultValue={1}
/>
</div>
</CCol>
</CRow>
</CCardBody>
</CCard>
</CCollapse>
</CCol>
</CRow>
<hr />
<CippPage title="Function Statistics" tenantSelector={false}>
<CCard className="content-card">
<CCardHeader className="d-flex justify-content-between align-items-center">
<CCardTitle>Statistics</CCardTitle>
</CCardHeader>
<CCardBody>
{isFetching && <CSpinner />}
{isSuccess && (
<CippTable reportName={`CIPP-Stats`} data={data?.Results[type]} columns={columns} />
)}
</CCardBody>
</CCard>
</CippPage>
</>
)
}

export default Statistics
2 changes: 1 addition & 1 deletion src/views/email-exchange/connectors/ConnectorList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const Offcanvas = (row, rowIndex, formatExtraData) => {
<FontAwesomeIcon icon={faEllipsisV} />
</CButton>
<CippActionsOffcanvas
title="User Information"
title="Extended Information"
extendedInfo={[
{ label: 'Created by', value: `${row.CreatedBy}` },
{ label: 'Last edit by', value: `${row.LastModifiedBy}` },
Expand Down
Loading