Skip to content

Commit f888594

Browse files
authored
Merge pull request #2150 from JohnDuprey/dev
Function Statistics
2 parents 72a9146 + 40309f2 commit f888594

File tree

3 files changed

+160
-1
lines changed

3 files changed

+160
-1
lines changed

src/_nav.jsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,11 @@ const _nav = [
742742
name: 'Logbook',
743743
to: '/cipp/logs',
744744
},
745+
{
746+
component: CNavItem,
747+
name: 'Statistics',
748+
to: '/cipp/statistics',
749+
},
745750
{
746751
component: CNavItem,
747752
name: 'SAM Setup Wizard',

src/routes.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React from 'react'
33
const Home = React.lazy(() => import('src/views/home/Home'))
44
const Logs = React.lazy(() => import('src/views/cipp/Logs'))
55
const Scheduler = React.lazy(() => import('src/views/cipp/Scheduler'))
6+
const Statistics = React.lazy(() => import('src/views/cipp/Statistics'))
67
const Users = React.lazy(() => import('src/views/identity/administration/Users'))
78
const DeletedItems = React.lazy(() => import('src/views/identity/administration/Deleted'))
89
const ViewBEC = React.lazy(() => import('src/views/identity/administration/ViewBEC'))
@@ -244,7 +245,7 @@ const routes = [
244245
{ path: '/home', name: 'Home', component: Home },
245246
{ path: '/cipp/logs', name: 'Logs', component: Logs },
246247
{ path: '/cipp/scheduler', name: 'Scheduler', component: Scheduler },
247-
248+
{ path: '/cipp/statistics', name: 'Statistics', component: Statistics },
248249
{ path: '/cipp/404', name: 'Error', component: Page404 },
249250
{ path: '/cipp/403', name: 'Error', component: Page403 },
250251
{ path: '/cipp/500', name: 'Error', component: Page500 },

src/views/cipp/Statistics.jsx

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import React, { useState } from 'react'
2+
import { CippPage } from 'src/components/layout'
3+
import {
4+
CButton,
5+
CCard,
6+
CCardBody,
7+
CCardHeader,
8+
CCardTitle,
9+
CCol,
10+
CCollapse,
11+
CFormInput,
12+
CFormLabel,
13+
CFormSelect,
14+
CRow,
15+
CSpinner,
16+
} from '@coreui/react'
17+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
18+
import { faChevronRight, faChevronDown } from '@fortawesome/free-solid-svg-icons'
19+
import { CippTable } from 'src/components/tables'
20+
import { cellGenericFormatter } from 'src/components/tables/CellGenericFormat'
21+
import { useSelector } from 'react-redux'
22+
import { useGenericGetRequestQuery } from 'src/store/api/app'
23+
import { RFFCFormSelect } from 'src/components/forms'
24+
25+
const columns = [
26+
{
27+
name: 'Name',
28+
selector: (row) => row['Name'],
29+
sortable: true,
30+
cell: cellGenericFormatter(),
31+
exportSelector: 'Name',
32+
minWidth: '145px',
33+
maxWidth: '145px',
34+
},
35+
{
36+
name: 'Executions',
37+
selector: (row) => row['ExecutionCount'],
38+
sortable: true,
39+
exportSelector: 'ExecutionCount',
40+
},
41+
{
42+
name: 'Total (seconds)',
43+
selector: (row) => row['TotalSeconds'],
44+
sortable: true,
45+
exportSelector: 'TotalSeconds',
46+
},
47+
{
48+
name: 'Max (seconds)',
49+
selector: (row) => row['MaxSeconds'],
50+
sortable: true,
51+
exportSelector: 'MaxSeconds',
52+
},
53+
{
54+
name: 'Avg (seconds)',
55+
selector: (row) => row['AvgSeconds'],
56+
sortable: true,
57+
exportSelector: 'AvgSeconds',
58+
cell: (row) => Math.round(row['AvgSeconds'] * 100) / 100,
59+
},
60+
]
61+
62+
const Statistics = () => {
63+
const [visibleA, setVisibleA] = useState(false)
64+
const [type, setType] = useState('Functions')
65+
const [interval, setInterval] = useState('Days')
66+
const [time, setTime] = useState(1)
67+
const tenant = useSelector((state) => state.app.currentTenant)
68+
const { data, isFetching, error, isSuccess } = useGenericGetRequestQuery({
69+
path: '/api/ListFunctionStats',
70+
params: {
71+
FunctionType: 'Queue',
72+
Interval: interval,
73+
Time: time,
74+
TenantFilter: tenant?.defaultDomainName,
75+
},
76+
})
77+
78+
return (
79+
<>
80+
<CRow>
81+
<CCol>
82+
<CCard className="options-card">
83+
<CCardHeader>
84+
<CCardTitle className="d-flex justify-content-between">
85+
Options
86+
<CButton
87+
size="sm"
88+
variant="ghost"
89+
className="stretched-link"
90+
onClick={() => setVisibleA(!visibleA)}
91+
>
92+
<FontAwesomeIcon icon={visibleA ? faChevronDown : faChevronRight} />
93+
</CButton>
94+
</CCardTitle>
95+
</CCardHeader>
96+
</CCard>
97+
<CCollapse visible={visibleA}>
98+
<CCard className="options-card">
99+
<CCardHeader></CCardHeader>
100+
<CCardBody>
101+
<CRow>
102+
<CCol>
103+
<CFormLabel>Report</CFormLabel>
104+
<CFormSelect name="Report" onChange={(e) => setType(e.target.value)}>
105+
<option value="Functions">Functions</option>
106+
<option value="Standards">Standards</option>
107+
</CFormSelect>
108+
</CCol>
109+
<CCol>
110+
<div>
111+
<CFormLabel>Interval</CFormLabel>
112+
<CFormSelect name="Interval" onChange={(e) => setInterval(e.target.value)}>
113+
<option value="Minute">Minutes</option>
114+
<option value="Hours">Hours</option>
115+
<option value="Days" selected>
116+
Days
117+
</option>
118+
</CFormSelect>
119+
</div>
120+
<div className="mt-2">
121+
<CFormLabel>Time</CFormLabel>
122+
<CFormInput
123+
name="Time"
124+
onChange={(e) => setTime(e.target.value)}
125+
defaultValue={1}
126+
/>
127+
</div>
128+
</CCol>
129+
</CRow>
130+
</CCardBody>
131+
</CCard>
132+
</CCollapse>
133+
</CCol>
134+
</CRow>
135+
<hr />
136+
<CippPage title="Function Statistics" tenantSelector={false}>
137+
<CCard className="content-card">
138+
<CCardHeader className="d-flex justify-content-between align-items-center">
139+
<CCardTitle>Statistics</CCardTitle>
140+
</CCardHeader>
141+
<CCardBody>
142+
{isFetching && <CSpinner />}
143+
{isSuccess && (
144+
<CippTable reportName={`CIPP-Stats`} data={data?.Results[type]} columns={columns} />
145+
)}
146+
</CCardBody>
147+
</CCard>
148+
</CippPage>
149+
</>
150+
)
151+
}
152+
153+
export default Statistics

0 commit comments

Comments
 (0)