mirror of
				https://github.com/optim-enterprises-bv/OptimCloud-gw-ui.git
				synced 2025-10-31 02:07:45 +00:00 
			
		
		
		
	Version 2.5.25: added refresh to logs/health/wifi analysis, added vendors to wifi analysis, changed configure feedback to use toast
This commit is contained in:
		
							
								
								
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,12 +1,12 @@ | ||||
| { | ||||
|   "name": "ucentral-client", | ||||
|   "version": "2.5.24", | ||||
|   "version": "2.5.25", | ||||
|   "lockfileVersion": 2, | ||||
|   "requires": true, | ||||
|   "packages": { | ||||
|     "": { | ||||
|       "name": "ucentral-client", | ||||
|       "version": "2.5.24", | ||||
|       "version": "2.5.25", | ||||
|       "dependencies": { | ||||
|         "@coreui/coreui": "^3.4.0", | ||||
|         "@coreui/icons": "^2.0.1", | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "ucentral-client", | ||||
|   "version": "2.5.24", | ||||
|   "version": "2.5.25", | ||||
|   "dependencies": { | ||||
|     "@coreui/coreui": "^3.4.0", | ||||
|     "@coreui/icons": "^2.0.1", | ||||
|   | ||||
| @@ -804,6 +804,7 @@ | ||||
| 		"mode": "Modus", | ||||
| 		"network_diagram": "Netzwerkdiagramm", | ||||
| 		"radios": "Radios", | ||||
| 		"title": "WLAN-Analyse" | ||||
| 		"title": "WLAN-Analyse", | ||||
| 		"vendor": "Verkäufer" | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -804,6 +804,7 @@ | ||||
| 		"mode": "Mode", | ||||
| 		"network_diagram": "Network Diagram", | ||||
| 		"radios": "Radios", | ||||
| 		"title": "Wi-Fi Analysis" | ||||
| 		"title": "Wi-Fi Analysis", | ||||
| 		"vendor": "Vendor" | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -804,6 +804,7 @@ | ||||
| 		"mode": "Modo", | ||||
| 		"network_diagram": "Diagrama de Red", | ||||
| 		"radios": "Radios", | ||||
| 		"title": "Análisis de Wi-Fi" | ||||
| 		"title": "Análisis de Wi-Fi", | ||||
| 		"vendor": "Vendedor" | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -804,6 +804,7 @@ | ||||
| 		"mode": "Mode", | ||||
| 		"network_diagram": "Diagramme de réseau", | ||||
| 		"radios": "Radios", | ||||
| 		"title": "Analyse Wi-Fi" | ||||
| 		"title": "Analyse Wi-Fi", | ||||
| 		"vendor": "vendeur" | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -804,6 +804,7 @@ | ||||
| 		"mode": "Modo", | ||||
| 		"network_diagram": "Diagrama de rede", | ||||
| 		"radios": "Rádios", | ||||
| 		"title": "Análise de Wi-Fi" | ||||
| 		"title": "Análise de Wi-Fi", | ||||
| 		"vendor": "fornecedor" | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -20,7 +20,7 @@ import React, { useState, useEffect } from 'react'; | ||||
| import { useTranslation } from 'react-i18next'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import 'react-widgets/styles.css'; | ||||
| import { useAuth, useDevice } from 'ucentral-libs'; | ||||
| import { useAuth, useDevice, useToast } from 'ucentral-libs'; | ||||
| import { checkIfJson } from 'utils/helper'; | ||||
| import axiosInstance from 'utils/axiosInstance'; | ||||
| import eventBus from 'utils/eventBus'; | ||||
| @@ -29,6 +29,7 @@ import SuccessfulActionModalBody from 'components/SuccessfulActionModalBody'; | ||||
| const ConfigureModal = ({ show, toggleModal }) => { | ||||
|   const { t } = useTranslation(); | ||||
|   const { currentToken, endpoints } = useAuth(); | ||||
|   const { addToast } = useToast(); | ||||
|   const { deviceSerialNumber } = useDevice(); | ||||
|   const [hadSuccess, setHadSuccess] = useState(false); | ||||
|   const [hadFailure, setHadFailure] = useState(false); | ||||
| @@ -91,7 +92,13 @@ const ConfigureModal = ({ show, toggleModal }) => { | ||||
|         { headers }, | ||||
|       ) | ||||
|       .then(() => { | ||||
|         setHadSuccess(true); | ||||
|         addToast({ | ||||
|           title: t('common.success'), | ||||
|           body: t('commands.command_success'), | ||||
|           color: 'success', | ||||
|           autohide: true, | ||||
|         }); | ||||
|         toggleModal(); | ||||
|       }) | ||||
|       .catch(() => { | ||||
|         setResponseBody('Error while submitting command!'); | ||||
|   | ||||
| @@ -11,7 +11,7 @@ import { | ||||
|   CPopover, | ||||
| } from '@coreui/react'; | ||||
| import CIcon from '@coreui/icons-react'; | ||||
| import { cilTrash } from '@coreui/icons'; | ||||
| import { cilSync, cilTrash } from '@coreui/icons'; | ||||
| import { useTranslation } from 'react-i18next'; | ||||
| import DatePicker from 'react-widgets/DatePicker'; | ||||
| import { dateToUnix } from 'utils/helper'; | ||||
| @@ -231,6 +231,11 @@ const DeviceHealth = () => { | ||||
|             <CIcon name="cil-trash" content={cilTrash} className="text-white" size="2xl" /> | ||||
|           </CButton> | ||||
|         </CPopover> | ||||
|         <CPopover content={t('common.refresh')}> | ||||
|           <CButton onClick={getDeviceHealth} size="sm"> | ||||
|             <CIcon name="cil-sync" content={cilSync} className="text-white" size="2xl" /> | ||||
|           </CButton> | ||||
|         </CPopover> | ||||
|       </div> | ||||
|     </CWidgetDropdown> | ||||
|   ); | ||||
|   | ||||
| @@ -12,7 +12,7 @@ import { | ||||
|   CPopover, | ||||
| } from '@coreui/react'; | ||||
| import CIcon from '@coreui/icons-react'; | ||||
| import { cilTrash } from '@coreui/icons'; | ||||
| import { cilSync, cilTrash } from '@coreui/icons'; | ||||
| import { useTranslation } from 'react-i18next'; | ||||
| import DatePicker from 'react-widgets/DatePicker'; | ||||
| import { dateToUnix } from 'utils/helper'; | ||||
| @@ -250,6 +250,11 @@ const DeviceLogs = () => { | ||||
|               <CIcon name="cil-trash" content={cilTrash} className="text-white" size="2xl" /> | ||||
|             </CButton> | ||||
|           </CPopover> | ||||
|           <CPopover content={t('common.refresh')}> | ||||
|             <CButton onClick={getLogs} size="sm"> | ||||
|               <CIcon name="cil-sync" content={cilSync} className="text-white" size="2xl" /> | ||||
|             </CButton> | ||||
|           </CPopover> | ||||
|         </div> | ||||
|       </CWidgetDropdown> | ||||
|       <DeleteLogModal | ||||
|   | ||||
| @@ -22,10 +22,11 @@ const WifiAnalysisTable = ({ t, data, loading }) => { | ||||
|     setShow(!show); | ||||
|   }; | ||||
|   const columns = [ | ||||
|     { key: 'radio', label: '#', _style: { width: '5%' } }, | ||||
|     { key: 'bssid', label: 'BSSID', _style: { width: '14%' } }, | ||||
|     { key: 'mode', label: t('wifi_analysis.mode'), _style: { width: '9%' }, sorter: false }, | ||||
|     { key: 'ssid', label: 'SSID', _style: { width: '17%' } }, | ||||
|     { key: 'radio', label: '#', _style: { width: '1%' } }, | ||||
|     { key: 'bssid', label: 'BSSID', _style: { width: '1%' } }, | ||||
|     { key: 'vendor', label: t('wifi_analysis.vendor'), _style: { width: '15%' }, sorter: false }, | ||||
|     { key: 'mode', label: t('wifi_analysis.mode'), _style: { width: '1%' }, sorter: false }, | ||||
|     { key: 'ssid', label: 'SSID', _style: { width: '15%' } }, | ||||
|     { key: 'rssi', label: 'RSSI', _style: { width: '5%' }, sorter: false }, | ||||
|     { key: 'rxRate', label: 'Rx Rate', _style: { width: '7%' }, sorter: false }, | ||||
|     { key: 'rxBytes', label: 'Rx', _style: { width: '7%' }, sorter: false }, | ||||
| @@ -70,6 +71,7 @@ const WifiAnalysisTable = ({ t, data, loading }) => { | ||||
|         sorter | ||||
|         sorterValue={{ column: 'radio', asc: true }} | ||||
|         scopedSlots={{ | ||||
|           bssid: (item) => <td className="text-center text-monospace">{item.bssid}</td>, | ||||
|           radio: (item) => <td className="text-center">{item.radio.radio}</td>, | ||||
|           rxMcs: (item) => centerIfEmpty(item.rxMcs), | ||||
|           rxNss: (item) => centerIfEmpty(item.rxNss), | ||||
|   | ||||
| @@ -19,7 +19,7 @@ import { | ||||
|   CPopover, | ||||
| } from '@coreui/react'; | ||||
| import CIcon from '@coreui/icons-react'; | ||||
| import { cilX } from '@coreui/icons'; | ||||
| import { cilSync, cilX } from '@coreui/icons'; | ||||
| import RadioAnalysisTable from './RadioAnalysis'; | ||||
| import WifiAnalysisTable from './WifiAnalysis'; | ||||
|  | ||||
| @@ -67,9 +67,33 @@ const WifiAnalysis = () => { | ||||
|     return ips; | ||||
|   }; | ||||
|  | ||||
|   const parseAssociationStats = (json) => { | ||||
|   const getVendors = async (bssids) => { | ||||
|     setLoading(true); | ||||
|     setRange(19); | ||||
|  | ||||
|     const options = { | ||||
|       headers: { | ||||
|         Accept: 'application/json', | ||||
|         Authorization: `Bearer ${currentToken}`, | ||||
|       }, | ||||
|     }; | ||||
|  | ||||
|     return axiosInstance | ||||
|       .get(`${endpoints.owgw}/api/v1/ouis?macList=${bssids.join(',')}`, options) | ||||
|       .then((response) => { | ||||
|         const newObj = bssids; | ||||
|         for (const tag of response.data.tagList) { | ||||
|           newObj[tag.tag] = tag.value; | ||||
|         } | ||||
|         return newObj; | ||||
|       }) | ||||
|       .catch(() => ({})); | ||||
|   }; | ||||
|  | ||||
|   const parseAssociationStats = async (json) => { | ||||
|     const newParsedAssociationStats = []; | ||||
|     const newParsedRadioStats = []; | ||||
|     const bssidObj = {}; | ||||
|  | ||||
|     for (const stat of json.data) { | ||||
|       const associations = []; | ||||
| @@ -123,6 +147,8 @@ const WifiAnalysis = () => { | ||||
|  | ||||
|             if ('associations' in ssid) { | ||||
|               for (const association of ssid.associations) { | ||||
|                 bssidObj[association.bssid] = 0; | ||||
|  | ||||
|                 const data = { | ||||
|                   radio: radioInfo, | ||||
|                   ...extractIp(stat.data, association.bssid), | ||||
| @@ -149,6 +175,16 @@ const WifiAnalysis = () => { | ||||
|       newParsedAssociationStats.push(associations); | ||||
|     } | ||||
|  | ||||
|     // Adding Vendor info to associations | ||||
|     const vendors = await getVendors(Object.keys(bssidObj)); | ||||
|  | ||||
|     for (let i = 0; i < newParsedAssociationStats.length; i += 1) { | ||||
|       for (let y = 0; y < newParsedAssociationStats[i].length; y += 1) { | ||||
|         newParsedAssociationStats[i][y].vendor = | ||||
|           vendors[newParsedAssociationStats[i][y].bssid] ?? '-'; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Radio Stats | ||||
|     const ascOrderedRadioStats = newParsedRadioStats.reverse(); | ||||
|     setParsedRadioStats(ascOrderedRadioStats); | ||||
| @@ -203,14 +239,19 @@ const WifiAnalysis = () => { | ||||
|   return ( | ||||
|     <div> | ||||
|       <CCard> | ||||
|         <CCardHeader className="dark-header"> | ||||
|           <CRow> | ||||
|             <CCol className="text-right"> | ||||
|         <CCardHeader className="dark-header d-flex flex-row-reverse align-items-center"> | ||||
|           <div className="pl-2"> | ||||
|             <CPopover content={t('common.refresh')}> | ||||
|               <CButton size="sm" color="info" onClick={getLatestAssociationStats}> | ||||
|                 <CIcon content={cilSync} /> | ||||
|               </CButton> | ||||
|             </CPopover> | ||||
|           </div> | ||||
|           <div> | ||||
|             <CButton color="info" size="sm" onClick={toggleModal}> | ||||
|               {t('wifi_analysis.network_diagram')} | ||||
|             </CButton> | ||||
|             </CCol> | ||||
|           </CRow> | ||||
|           </div> | ||||
|         </CCardHeader> | ||||
|         <CCardBody> | ||||
|           <CRow className="mb-4"> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Charles
					Charles