Merge pull request #77 from stephb9959/main

2.5.32
This commit is contained in:
Charles
2022-01-21 19:38:04 +01:00
committed by GitHub
7 changed files with 3843 additions and 7188 deletions

10904
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "ucentral-client", "name": "ucentral-client",
"version": "2.5.27", "version": "2.5.32",
"dependencies": { "dependencies": {
"@coreui/coreui": "^3.4.0", "@coreui/coreui": "^3.4.0",
"@coreui/icons": "^2.0.1", "@coreui/icons": "^2.0.1",
@@ -26,7 +26,7 @@
"react-tooltip": "^4.2.21", "react-tooltip": "^4.2.21",
"react-widgets": "^5.1.1", "react-widgets": "^5.1.1",
"sass": "^1.35.1", "sass": "^1.35.1",
"ucentral-libs": "^1.0.57", "ucentral-libs": "^1.0.58",
"uuid": "^8.3.2" "uuid": "^8.3.2"
}, },
"main": "index.js", "main": "index.js",

View File

@@ -117,14 +117,34 @@ const StatisticsChartList = ({ setOptions, section, setStart, setEnd, time }) =>
for (const log of sortedData) { for (const log of sortedData) {
// Looping through the interfaces of the log // Looping through the interfaces of the log
for (const inter of log.data.interfaces) { for (const inter of log.data.interfaces) {
if (inter.ssids?.length > 0) {
let totalTx = 0;
let totalRx = 0;
for (const ssid of inter.ssids) {
if (ssid.associations) {
for (const assoc of ssid.associations) {
if (assoc.deltas) {
totalTx += assoc.deltas?.tx_bytes ?? 0;
totalRx += assoc.deltas?.rx_bytes ?? 0;
} else {
totalTx += assoc.tx_bytes ?? 0;
totalRx += assoc.rx_bytes ?? 0;
}
}
}
}
interfaceList[interfaceTypes[inter.name]][0].data.push(Math.floor(totalTx / 1024));
interfaceList[interfaceTypes[inter.name]][1].data.push(Math.floor(totalRx / 1024));
} else {
interfaceList[interfaceTypes[inter.name]][0].data.push( interfaceList[interfaceTypes[inter.name]][0].data.push(
inter.counters?.tx_bytes ? Math.floor(inter.counters.tx_bytes / 1024) : 0, inter.counters ? Math.floor(inter.counters.tx_bytes) : 0,
); );
interfaceList[interfaceTypes[inter.name]][1].data.push( interfaceList[interfaceTypes[inter.name]][1].data.push(
inter.counters?.rx_bytes ? Math.floor(inter.counters.rx_bytes / 1024) : 0, inter.counters ? Math.floor(inter.counters.rx_bytes) : 0,
); );
} }
} }
}
const interfaceOptions = { const interfaceOptions = {
chart: { chart: {

View File

@@ -13,14 +13,12 @@ import {
import DatePicker from 'react-widgets/DatePicker'; import DatePicker from 'react-widgets/DatePicker';
import { cilSync } from '@coreui/icons'; import { cilSync } from '@coreui/icons';
import CIcon from '@coreui/icons-react'; import CIcon from '@coreui/icons-react';
import LifetimeStatsmodal from 'components/LifetimeStatsModal';
import StatisticsChartList from './StatisticsChartList'; import StatisticsChartList from './StatisticsChartList';
import LatestStatisticsmodal from './LatestStatisticsModal'; import LatestStatisticsmodal from './LatestStatisticsModal';
const DeviceStatisticsCard = () => { const DeviceStatisticsCard = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const [showLatestModal, setShowLatestModal] = useState(false); const [showLatestModal, setShowLatestModal] = useState(false);
const [showLifetimeModal, setShowLifetimeModal] = useState(false);
const [options, setOptions] = useState([]); const [options, setOptions] = useState([]);
const [section, setSection] = useState(''); const [section, setSection] = useState('');
const [start, setStart] = useState(null); const [start, setStart] = useState(null);
@@ -33,10 +31,6 @@ const DeviceStatisticsCard = () => {
setShowLatestModal(!showLatestModal); setShowLatestModal(!showLatestModal);
}; };
const toggleLifetimeModal = () => {
setShowLifetimeModal(!showLifetimeModal);
};
const modifyStart = (value) => { const modifyStart = (value) => {
try { try {
new Date(value).toISOString(); new Date(value).toISOString();
@@ -102,16 +96,6 @@ const DeviceStatisticsCard = () => {
</div> </div>
From: From:
<div className="px-2"> <div className="px-2">
<CButton size="sm" color="info" onClick={toggleLifetimeModal}>
Lifetime Statistics
</CButton>
</div>
<div className="pl-2">
<CButton size="sm" color="info" onClick={toggleLatestModal}>
{t('statistics.show_latest')}
</CButton>
</div>
<div className="pl-2">
<CSelect <CSelect
custom custom
value={section} value={section}
@@ -125,6 +109,11 @@ const DeviceStatisticsCard = () => {
))} ))}
</CSelect> </CSelect>
</div> </div>
<div className="pl-2">
<CButton size="sm" color="info" onClick={toggleLatestModal}>
{t('statistics.show_latest')}
</CButton>
</div>
</div> </div>
</CCardHeader> </CCardHeader>
<CCardBody className="p-1"> <CCardBody className="p-1">
@@ -138,7 +127,6 @@ const DeviceStatisticsCard = () => {
</CCardBody> </CCardBody>
</CCard> </CCard>
<LatestStatisticsmodal show={showLatestModal} toggle={toggleLatestModal} /> <LatestStatisticsmodal show={showLatestModal} toggle={toggleLatestModal} />
<LifetimeStatsmodal show={showLifetimeModal} toggle={toggleLifetimeModal} />
</div> </div>
); );
}; };

View File

@@ -1,48 +0,0 @@
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import axiosInstance from 'utils/axiosInstance';
import { useTranslation } from 'react-i18next';
import { LifetimeStatsModal as Modal, useAuth, useDevice } from 'ucentral-libs';
const LifetimeStatsModal = ({ show, toggle }) => {
const { t } = useTranslation();
const { currentToken, endpoints } = useAuth();
const { deviceSerialNumber } = useDevice();
const [loading, setLoading] = useState(false);
const [data, setData] = useState({});
const getData = () => {
setLoading(true);
const options = {
headers: {
Accept: 'application/json',
Authorization: `Bearer ${currentToken}`,
},
};
axiosInstance
.get(
`${endpoints.owgw}/api/v1/device/${deviceSerialNumber}/statistics?lifetime=true`,
options,
)
.then((response) => {
setData(response.data);
})
.catch(() => {})
.finally(() => setLoading(false));
};
useEffect(() => {
if (show) getData();
}, [show]);
return <Modal t={t} loading={loading} show={show} toggle={toggle} data={data} />;
};
LifetimeStatsModal.propTypes = {
show: PropTypes.bool.isRequired,
toggle: PropTypes.func.isRequired,
};
export default LifetimeStatsModal;

View File

@@ -120,7 +120,7 @@ const WifiAnalysis = () => {
// Looping through the interfaces // Looping through the interfaces
for (const deviceInterface of stat.data.interfaces) { for (const deviceInterface of stat.data.interfaces) {
if ('counters' in deviceInterface && 'ssids' in deviceInterface) { if ('ssids' in deviceInterface) {
for (const ssid of deviceInterface.ssids) { for (const ssid of deviceInterface.ssids) {
// Information common between all associations // Information common between all associations
const radioInfo = { const radioInfo = {

View File

@@ -20,6 +20,13 @@ axiosInstance.interceptors.response.use(
case 401: case 401:
break; break;
case 403: case 403:
if (error.response.data?.ErrorCode === 13) {
let retries = localStorage.getItem('sec_retries')
? +localStorage.getItem('sec_retries')
: 0;
retries += 1;
localStorage.setItem('sec_retries', retries);
}
if (error.response.data?.ErrorCode === 9) { if (error.response.data?.ErrorCode === 9) {
localStorage.removeItem('access_token'); localStorage.removeItem('access_token');
localStorage.removeItem('gateway_endpoints'); localStorage.removeItem('gateway_endpoints');