mirror of
https://github.com/optim-enterprises-bv/OptimCloud-gw-ui.git
synced 2025-11-01 18:57:46 +00:00
Device # in analysis page, UI fix for status card
This commit is contained in:
18
package-lock.json
generated
18
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "ucentral-client",
|
||||
"version": "2.0.11",
|
||||
"version": "2.0.12",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ucentral-client",
|
||||
"version": "2.0.11",
|
||||
"version": "2.0.12",
|
||||
"dependencies": {
|
||||
"@coreui/coreui": "^3.4.0",
|
||||
"@coreui/icons": "^2.0.1",
|
||||
@@ -29,7 +29,7 @@
|
||||
"react-tooltip": "^4.2.21",
|
||||
"react-widgets": "^5.1.1",
|
||||
"sass": "^1.35.1",
|
||||
"ucentral-libs": "^0.8.51",
|
||||
"ucentral-libs": "^0.8.52",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -14311,9 +14311,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ucentral-libs": {
|
||||
"version": "0.8.51",
|
||||
"resolved": "https://registry.npmjs.org/ucentral-libs/-/ucentral-libs-0.8.51.tgz",
|
||||
"integrity": "sha512-gZHo07Mu1Wl5Gq8fRwRKQOCGVuUC5FA/QrOiLalMahyIhmocRW3rBnE/ieWtV9O3nW5hkBXEpFigiZxX/T9LmA==",
|
||||
"version": "0.8.52",
|
||||
"resolved": "https://registry.npmjs.org/ucentral-libs/-/ucentral-libs-0.8.52.tgz",
|
||||
"integrity": "sha512-ifyXRDxzMnV1NzpsFXy6fn2NMtgR1361cHcRBRjPEdAPY7AWRBFoRsq858ZOU9rD0Loe6gGzVnwSF62rhSMTAw==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
@@ -26634,9 +26634,9 @@
|
||||
}
|
||||
},
|
||||
"ucentral-libs": {
|
||||
"version": "0.8.51",
|
||||
"resolved": "https://registry.npmjs.org/ucentral-libs/-/ucentral-libs-0.8.51.tgz",
|
||||
"integrity": "sha512-gZHo07Mu1Wl5Gq8fRwRKQOCGVuUC5FA/QrOiLalMahyIhmocRW3rBnE/ieWtV9O3nW5hkBXEpFigiZxX/T9LmA==",
|
||||
"version": "0.8.52",
|
||||
"resolved": "https://registry.npmjs.org/ucentral-libs/-/ucentral-libs-0.8.52.tgz",
|
||||
"integrity": "sha512-ifyXRDxzMnV1NzpsFXy6fn2NMtgR1361cHcRBRjPEdAPY7AWRBFoRsq858ZOU9rD0Loe6gGzVnwSF62rhSMTAw==",
|
||||
"requires": {}
|
||||
},
|
||||
"unbox-primitive": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ucentral-client",
|
||||
"version": "2.0.11",
|
||||
"version": "2.0.12",
|
||||
"dependencies": {
|
||||
"@coreui/coreui": "^3.4.0",
|
||||
"@coreui/icons": "^2.0.1",
|
||||
@@ -23,7 +23,7 @@
|
||||
"react-tooltip": "^4.2.21",
|
||||
"react-widgets": "^5.1.1",
|
||||
"sass": "^1.35.1",
|
||||
"ucentral-libs": "^0.8.51",
|
||||
"ucentral-libs": "^0.8.52",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"main": "index.js",
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
"delete": "Löschen",
|
||||
"delete_device": "Gerät löschen",
|
||||
"details": "Einzelheiten",
|
||||
"device": "Gerät #{{serialNumber}}",
|
||||
"device_dashboard": "Geräte-Dashboard",
|
||||
"device_delete": "Gerät Nr.{{serialNumber}}löschen",
|
||||
"device_deleted": "Gerät erfolgreich gelöscht",
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
"delete": "Delete",
|
||||
"delete_device": "Delete Device",
|
||||
"details": "Details",
|
||||
"device": "Device #{{serialNumber}}",
|
||||
"device_dashboard": "Device Dashboard",
|
||||
"device_delete": "Delete Device #{{serialNumber}}",
|
||||
"device_deleted": "Device Successfully Deleted",
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
"delete": "Borrar",
|
||||
"delete_device": "Eliminar dispositivo",
|
||||
"details": "Detalles",
|
||||
"device": "Dispositivo n.º{{serialNumber}}",
|
||||
"device_dashboard": "Panel de control del dispositivo",
|
||||
"device_delete": "Eliminar dispositivo n.º{{serialNumber}}",
|
||||
"device_deleted": "Dispositivo eliminado correctamente",
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
"delete": "Effacer",
|
||||
"delete_device": "Supprimer le périphérique",
|
||||
"details": "Détails",
|
||||
"device": "N° d'appareil{{serialNumber}}",
|
||||
"device_dashboard": "Tableau de bord de l'appareil",
|
||||
"device_delete": "Supprimer l'appareil n°{{serialNumber}}",
|
||||
"device_deleted": "Appareil supprimé avec succès",
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
"delete": "Excluir",
|
||||
"delete_device": "Apagar dispositivo",
|
||||
"details": "Detalhes",
|
||||
"device": "Dispositivo nº{{serialNumber}}",
|
||||
"device_dashboard": "Painel do dispositivo",
|
||||
"device_delete": "Excluir dispositivo nº{{serialNumber}}",
|
||||
"device_deleted": "Dispositivo excluído com sucesso",
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
import React from 'react';
|
||||
import { CPopover, CProgress, CProgressBar } from '@coreui/react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { cleanBytesString } from 'utils/helper';
|
||||
|
||||
const MemoryBar = ({ usedBytes, totalBytes }) => {
|
||||
const { t } = useTranslation();
|
||||
const used = cleanBytesString(usedBytes);
|
||||
const total = cleanBytesString(totalBytes);
|
||||
const percentage = Math.floor((usedBytes / totalBytes) * 100);
|
||||
|
||||
return (
|
||||
<CPopover content={t('status.used_total_memory', { used, total })}>
|
||||
<CProgress>
|
||||
<CProgressBar value={percentage}>
|
||||
{percentage >= 25 ? t('status.percentage_used', { percentage, total }) : ''}
|
||||
</CProgressBar>
|
||||
<CProgressBar value={100 - percentage} color="transparent">
|
||||
<div style={{ color: 'black' }}>
|
||||
{percentage < 25
|
||||
? t('status.percentage_free', { percentage: 100 - percentage, total })
|
||||
: ''}
|
||||
</div>
|
||||
</CProgressBar>
|
||||
</CProgress>
|
||||
</CPopover>
|
||||
);
|
||||
};
|
||||
|
||||
MemoryBar.propTypes = {
|
||||
usedBytes: PropTypes.number.isRequired,
|
||||
totalBytes: PropTypes.number.isRequired,
|
||||
};
|
||||
|
||||
export default React.memo(MemoryBar);
|
||||
@@ -1,26 +1,7 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
CCard,
|
||||
CCardHeader,
|
||||
CRow,
|
||||
CCol,
|
||||
CCardBody,
|
||||
CBadge,
|
||||
CModalBody,
|
||||
CAlert,
|
||||
CPopover,
|
||||
CButton,
|
||||
CSpinner,
|
||||
} from '@coreui/react';
|
||||
import CIcon from '@coreui/icons-react';
|
||||
import { useDevice, useAuth } from 'ucentral-libs';
|
||||
import { cilSync } from '@coreui/icons';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import axiosInstance from 'utils/axiosInstance';
|
||||
import { prettyDate, secondsToDetailed } from 'utils/helper';
|
||||
import MemoryBar from './MemoryBar';
|
||||
|
||||
import styles from './index.module.scss';
|
||||
import { DeviceStatusCard as Card, useDevice, useAuth } from 'ucentral-libs';
|
||||
|
||||
const DeviceStatusCard = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -31,11 +12,6 @@ const DeviceStatusCard = () => {
|
||||
const [error, setError] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const transformLoad = (load) => {
|
||||
if (load === undefined) return t('common.na');
|
||||
return `${((load / 65536) * 100).toFixed(2)}%`;
|
||||
};
|
||||
|
||||
const getData = () => {
|
||||
setLoading(true);
|
||||
const options = {
|
||||
@@ -74,123 +50,17 @@ const DeviceStatusCard = () => {
|
||||
if (deviceSerialNumber) getData();
|
||||
}, [deviceSerialNumber]);
|
||||
|
||||
if (!error) {
|
||||
return (
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<CRow>
|
||||
<CCol>
|
||||
<div className="text-value-lg">
|
||||
{t('status.title', { serialNumber: deviceSerialNumber })}
|
||||
</div>
|
||||
</CCol>
|
||||
<CCol>
|
||||
<div className="text-right">
|
||||
<CPopover content={t('common.refresh')}>
|
||||
<CButton color="secondary" onClick={getData} size="sm">
|
||||
<CIcon content={cilSync} />
|
||||
</CButton>
|
||||
</CPopover>
|
||||
</div>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
{(!lastStats || !status) && loading ? (
|
||||
<div className={styles.centerContainer}>
|
||||
<CSpinner className={styles.spinner} />
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ position: 'relative' }}>
|
||||
<div className={styles.overlayContainer} hidden={!loading}>
|
||||
<CSpinner className={styles.spinner} />
|
||||
</div>
|
||||
<CRow className="my-2">
|
||||
<CCol md="5">{t('status.connection_status')} :</CCol>
|
||||
<CCol xs="10" md="7">
|
||||
{status?.connected ? (
|
||||
<CBadge color="success">{t('common.connected')}</CBadge>
|
||||
) : (
|
||||
<CBadge color="danger">{t('common.not_connected')}</CBadge>
|
||||
)}
|
||||
</CCol>
|
||||
</CRow>
|
||||
<CRow className="my-2">
|
||||
<CCol md="5">{t('status.uptime')} :</CCol>
|
||||
<CCol xs="10" md="7">
|
||||
{secondsToDetailed(
|
||||
lastStats?.unit?.uptime,
|
||||
t('common.day'),
|
||||
t('common.days'),
|
||||
t('common.hour'),
|
||||
t('common.hours'),
|
||||
t('common.minute'),
|
||||
t('common.minutes'),
|
||||
t('common.second'),
|
||||
t('common.seconds'),
|
||||
)}
|
||||
</CCol>
|
||||
</CRow>
|
||||
<CRow className="my-2">
|
||||
<CCol md="5">{t('status.last_contact')} :</CCol>
|
||||
<CCol xs="10" md="7">
|
||||
{prettyDate(status?.lastContact)}
|
||||
</CCol>
|
||||
</CRow>
|
||||
<CRow className="my-2">
|
||||
<CCol md="5">{t('status.localtime')} :</CCol>
|
||||
<CCol xs="10" md="7">
|
||||
{prettyDate(lastStats?.unit?.localtime)}
|
||||
</CCol>
|
||||
</CRow>
|
||||
<CRow className="my-2">
|
||||
<CCol md="5">{t('status.load_averages')} :</CCol>
|
||||
<CCol xs="10" md="7">
|
||||
{transformLoad(lastStats?.unit?.load[0])}
|
||||
{' / '}
|
||||
{transformLoad(lastStats?.unit?.load[1])}
|
||||
{' / '}
|
||||
{transformLoad(lastStats?.unit?.load[2])}
|
||||
</CCol>
|
||||
</CRow>
|
||||
<CRow className="my-2">
|
||||
<CCol md="5">{t('status.memory')} :</CCol>
|
||||
<CCol xs="9" md="6" style={{ paddingTop: '5px' }}>
|
||||
<MemoryBar
|
||||
usedBytes={
|
||||
lastStats?.unit?.memory?.total && lastStats?.unit?.memory?.free
|
||||
? lastStats?.unit?.memory?.total - lastStats?.unit?.memory?.free
|
||||
: 0
|
||||
}
|
||||
totalBytes={lastStats?.unit?.memory?.total ?? 0}
|
||||
/>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</div>
|
||||
)}
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<CRow>
|
||||
<CCol>
|
||||
<div className="text-value-lg">
|
||||
{t('status.title', { serialNumber: deviceSerialNumber })}
|
||||
</div>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCardHeader>
|
||||
<CModalBody>
|
||||
<CAlert hidden={!error} color="danger" className={styles.centerContainer}>
|
||||
{t('status.error')}
|
||||
</CAlert>
|
||||
</CModalBody>
|
||||
</CCard>
|
||||
<Card
|
||||
t={t}
|
||||
loading={loading}
|
||||
error={error}
|
||||
deviceSerialNumber={deviceSerialNumber}
|
||||
getData={getData}
|
||||
status={status}
|
||||
lastStats={lastStats}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(DeviceStatusCard);
|
||||
export default DeviceStatusCard;
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
.centerContainer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.overlayContainer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
}
|
||||
@@ -89,7 +89,7 @@ const TheLayout = () => {
|
||||
<PageContainer t={t} routes={routes} redirectTo="/devices" />
|
||||
</ToastProvider>
|
||||
</div>
|
||||
<Footer t={t} version="2.0.11" />
|
||||
<Footer t={t} version="2.0.12" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -3,11 +3,11 @@ import { useParams } from 'react-router-dom';
|
||||
import { CRow, CCol } from '@coreui/react';
|
||||
import DeviceHealth from 'components/DeviceHealth';
|
||||
import DeviceConfiguration from 'components/DeviceConfiguration';
|
||||
import DeviceStatusCard from 'components/DeviceStatusCard';
|
||||
import CommandHistory from 'components/CommandHistory';
|
||||
import DeviceLogs from 'components/DeviceLogs';
|
||||
import DeviceStatisticsCard from 'components/InterfaceStatistics';
|
||||
import DeviceActionCard from 'components/DeviceActionCard';
|
||||
import DeviceStatusCard from 'components/DeviceStatusCard';
|
||||
import axiosInstance from 'utils/axiosInstance';
|
||||
import { DeviceProvider } from 'ucentral-libs';
|
||||
|
||||
@@ -18,11 +18,11 @@ const DevicePage = () => {
|
||||
<div className="App">
|
||||
<DeviceProvider axiosInstance={axiosInstance} serialNumber={deviceId}>
|
||||
<CRow>
|
||||
<CCol xs="12" sm="6">
|
||||
<CCol xs="12" lg="6">
|
||||
<DeviceStatusCard />
|
||||
<DeviceConfiguration />
|
||||
</CCol>
|
||||
<CCol xs="12" sm="6">
|
||||
<CCol xs="12" lg="6">
|
||||
<DeviceLogs />
|
||||
<DeviceHealth />
|
||||
<DeviceActionCard />
|
||||
|
||||
@@ -180,7 +180,10 @@ const WifiAnalysisPage = () => {
|
||||
<div>
|
||||
<CCard>
|
||||
<CCardHeader>
|
||||
<CRow>
|
||||
<h5 className="mb-0">{t('common.device', { serialNumber: deviceId })}</h5>
|
||||
</CCardHeader>
|
||||
<CCardBody className="overflow-auto" style={{ height: 'calc(100vh - 300px)' }}>
|
||||
<CRow className="mb-4">
|
||||
<CCol className="text-center">
|
||||
<input
|
||||
type="range"
|
||||
@@ -198,8 +201,6 @@ const WifiAnalysisPage = () => {
|
||||
</h5>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCardHeader>
|
||||
<CCardBody className="overflow-auto" style={{ height: 'calc(100vh - 300px)' }}>
|
||||
<h5 className="pb-3 text-center">{t('wifi_analysis.radios')}</h5>
|
||||
<RadioAnalysisTable data={selectedRadioStats ?? []} loading={loading} range={range} />
|
||||
<h5 className="pt-5 pb-3 text-center">{t('wifi_analysis.associations')}</h5>
|
||||
|
||||
Reference in New Issue
Block a user