import React, { useEffect } from 'react'; import PropTypes from 'prop-types'; import ReactPaginate from 'react-paginate'; import { CCardBody, CDataTable, CButton, CLink, CCard, CCardHeader, CRow, CCol, CPopover, CSelect, CButtonClose, } from '@coreui/react'; import { cilSync, cilArrowCircleTop, cilCheckCircle, cilTerminal, cilTrash, cilSearch, } from '@coreui/icons'; import CIcon from '@coreui/icons-react'; import ReactTooltip from 'react-tooltip'; import { v4 as createUuid } from 'uuid'; import { cleanBytesString } from 'utils/helper'; import { DeviceBadge, LoadingButton } from 'ucentral-libs'; import ReactCountryFlag from 'react-country-flag'; import styles from './index.module.scss'; const DeviceListTable = ({ currentPage, devices, searchBar, devicesPerPage, loading, updateDevicesPerPage, pageCount, updatePage, refreshDevice, t, toggleFirmwareModal, toggleHistoryModal, upgradeToLatest, upgradeStatus, deviceIcons, connectRtty, deleteDevice, deleteStatus, }) => { const columns = [ { key: 'deviceType', label: '', filter: false, sorter: false, _style: { width: '1%' } }, { key: 'serialNumber', label: t('common.serial_number'), _style: { width: '6%' } }, { key: 'firmware', label: t('firmware.revision') }, { key: 'firmware_button', label: '', filter: false, _style: { width: '1%' } }, { key: 'compatible', label: t('common.type'), filter: false, _style: { width: '13%' } }, { key: 'txBytes', label: 'Tx', filter: false, _style: { width: '14%' } }, { key: 'rxBytes', label: 'Rx', filter: false, _style: { width: '14%' } }, { key: 'ipAddress', label: t('IP'), _style: { width: '10%' } }, { key: 'twoG', label: t('2G'), _style: { width: '10%' } }, { key: 'fiveG', label: t('5G'), _style: { width: '10%' } }, { key: 'actions', label: t('actions.actions'), _style: { width: '10%' } }, ]; const hideTooltips = () => ReactTooltip.hide(); const escFunction = (event) => { if (event.keyCode === 27) { hideTooltips(); } }; const getShortRevision = (revision) => { if (revision.includes(' / ')) { return revision.split(' / ')[1]; } return revision; }; useEffect(() => { document.addEventListener('keydown', escFunction, false); return () => { document.removeEventListener('keydown', escFunction, false); }; }, []); const getFirmwareButton = (latest, device) => { const tooltipId = createUuid(); let text = t('firmware.unknown_firmware_status'); let upgradeText = t('firmware.upgrade_to_latest'); let icon = ; let color = 'secondary'; if (latest !== undefined) { text = t('firmware.newer_firmware_available'); color = 'warning'; if (latest) { icon = ; text = t('firmware.latest_version_installed'); upgradeText = t('firmware.reinstall_latest'); color = 'success'; } } return (
{icon} { const element = document.getElementById(tooltipId); const tooltipWidth = element ? element.offsetWidth : 0; const newLeft = left + tooltipWidth * 0.25; return { top, left: newLeft }; }} > {text} { e.target.parentNode.parentNode.classList.remove('show'); hideTooltips(); }} /> upgradeToLatest(device)} block disabled={ upgradeStatus.loading && upgradeStatus.serialNumber === device.serialNumber } /> { toggleFirmwareModal(device); }} > {t('firmware.choose_custom')} { toggleHistoryModal(device); }} > {t('firmware.history_title')}
); }; const deleteButton = (serialNumber) => { const tooltipId = createUuid(); return ( <> { const element = document.getElementById(tooltipId); const tooltipWidth = element ? element.offsetWidth : 0; const newLeft = left - tooltipWidth * 0.25; return { top, left: newLeft }; }} > {t('common.device_delete', { serialNumber })} { e.target.parentNode.parentNode.classList.remove('show'); hideTooltips(); }} /> { e.target.parentNode.parentNode.parentNode.parentNode.classList.remove('show'); hideTooltips(); deleteDevice(serialNumber); }} block disabled={deleteStatus.loading} /> ); }; return ( <>
{searchBar}
( ), serialNumber: (item) => ( `/devices/${item.serialNumber}`} > {item.serialNumber} ), firmware: (item) => (
{getShortRevision(item.firmware)}
), firmware_button: (item) => ( {item.firmwareInfo ? getFirmwareButton(item.firmwareInfo.latest, item) : getFirmwareButton(undefined, item)} ), compatible: (item) => (
{item.compatible}
), txBytes: (item) => {cleanBytesString(item.txBytes)}, rxBytes: (item) => {cleanBytesString(item.rxBytes)}, ipAddress: (item) => (
{item.locale !== '' && item.ipAddress !== '' && ( )} {` ${item.ipAddress}`}
), twoG: (item) => {item.associations_2G ?? 0}, fiveG: (item) => {item.associations_5G ?? 0}, actions: (item) => (
connectRtty(item.serialNumber)} style={{ width: '33px', height: '30px' }} > {deleteButton(item.serialNumber)} `/devices/${item.serialNumber}`} > refreshDevice(item.serialNumber)} color="primary" variant="outline" shape="square" size="sm" className="mx-1 d-inline" style={{ width: '33px', height: '30px' }} >
), }} />

{t('common.items_per_page')}

updateDevicesPerPage(e.target.value)} disabled={loading} >
); }; DeviceListTable.propTypes = { currentPage: PropTypes.oneOf(['string', 'number']), devices: PropTypes.instanceOf(Array).isRequired, searchBar: PropTypes.node.isRequired, updateDevicesPerPage: PropTypes.func.isRequired, pageCount: PropTypes.number.isRequired, updatePage: PropTypes.func.isRequired, devicesPerPage: PropTypes.string.isRequired, refreshDevice: PropTypes.func.isRequired, t: PropTypes.func.isRequired, loading: PropTypes.bool.isRequired, toggleFirmwareModal: PropTypes.func.isRequired, toggleHistoryModal: PropTypes.func.isRequired, upgradeToLatest: PropTypes.func.isRequired, upgradeStatus: PropTypes.instanceOf(Object).isRequired, deviceIcons: PropTypes.instanceOf(Object).isRequired, connectRtty: PropTypes.func.isRequired, deleteDevice: PropTypes.func.isRequired, deleteStatus: PropTypes.instanceOf(Object).isRequired, }; DeviceListTable.defaultProps = { currentPage: '0', }; export default React.memo(DeviceListTable);