Skip to content

Commit

Permalink
Merge pull request #9 from KelvinTegelaar/dev
Browse files Browse the repository at this point in the history
[pull] dev from KelvinTegelaar:dev
  • Loading branch information
kris6673 committed Feb 23, 2024
2 parents 685f936 + 129d3a7 commit 664d002
Show file tree
Hide file tree
Showing 21 changed files with 515 additions and 36 deletions.
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

0 comments on commit 664d002

Please sign in to comment.