);\r\n }\r\n\r\n return (\r\n
\r\n \r\n \r\n \r\n
\r\n {renderHeader()}\r\n
\r\n \r\n
{ResourceLang.micro_controller_info}\r\n
{ResourceLang.micro_controller} \r\n {renderDeviceTypeIcon()}\r\n {renderExtensionIcon()}\r\n {renderMemoryIcon()}\r\n
\r\n {renderDropZoneArea()}\r\n
\r\n {renderUploadButton()}\r\n {renderSnackbar()}\r\n
\r\n \r\n {!MenuItems ?
: null}\r\n
);\r\n}\r\n\r\n\r\nexport default withRouter(UploadFirmwarePage);","import React from 'react';\r\nimport PropTypes from 'prop-types';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport { Stepper, Step, StepLabel } from '@material-ui/core';\r\n\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n root: {\r\n width: '100%',\r\n },\r\n button: {\r\n marginRight: theme.spacing(1),\r\n },\r\n instructions: {\r\n marginTop: theme.spacing(1),\r\n marginBottom: theme.spacing(1),\r\n },\r\n}));\r\n\r\n\r\nconst DialogStepper = ({\r\n activeStep, steps, stepProps = {}, labelProps = {}, ...other\r\n}) => {\r\n const classes = useStyles();\r\n return (\r\n \r\n \r\n {steps.map((label) => {\r\n return (\r\n {label}\r\n );\r\n })}\r\n \r\n
\r\n );\r\n}\r\n\r\nDialogStepper.propTypes = {\r\n activeStep: PropTypes.number.isRequired,\r\n steps: PropTypes.array.isRequired\r\n};\r\n\r\nexport default DialogStepper;\r\n","import PropTypes from 'prop-types';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport React from 'react';\r\nimport {makeStyles } from '@material-ui/core/styles';\r\nimport InputLabel from '@material-ui/core/InputLabel';\r\nimport MenuItem from '@material-ui/core/MenuItem';\r\nimport FormControl from '@material-ui/core/FormControl';\r\nimport Select from '@material-ui/core/Select';\r\nimport ResourceLang from '../../resources/Language';\r\nimport { Typography } from '@material-ui/core';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n button: {\r\n display: 'block',\r\n marginTop: theme.spacing(2),\r\n },\r\n formControl: {\r\n margin: theme.spacing(1),\r\n minWidth: 120,\r\n },\r\n body_content:{\r\n marginTop: 30,\r\n textAlign: 'center'\r\n }\r\n}));\r\n\r\n\r\nconst SelectVersions = ({availableVersions, versionSelected}) => {\r\n const classes = useStyles();\r\n const [versionChoosen, setVersionChoosen] = React.useState('');\r\n const [open, setOpen] = React.useState(false);\r\n\r\n const renderContent = () => {\r\n const handleChange = (event) => {\r\n setVersionChoosen(event.target.value)\r\n versionSelected(availableVersions[event.target.value].current_firmware_version)\r\n };\r\n \r\n const handleClose = () => {\r\n setOpen(false);\r\n };\r\n \r\n const handleOpen = () => {\r\n setOpen(true);\r\n };\r\n\r\n const renderVersionChoosenOnDropDown = () =>{\r\n return(\r\n {ResourceLang.version}\r\n )\r\n }\r\n\r\n return(\r\n \r\n {renderVersionChoosenOnDropDown}\r\n \r\n \r\n
\r\n )\r\n }\r\n\r\n return(\r\n \r\n \r\n \r\n \r\n {ResourceLang.update_version_choose} \r\n \r\n {renderContent()}\r\n
\r\n \r\n \r\n )\r\n}\r\n\r\nSelectVersions.propTypes = {\r\n availableVersions: PropTypes.object.isRequired,\r\n versionSelected: PropTypes.func.isRequired\r\n};\r\n\r\nexport default SelectVersions;","import React from 'react'\r\nimport PropTypes from 'prop-types';\r\nimport { Grid, ScrollSync , AutoSizer } from 'react-virtualized';\r\nimport { scrollbarSize } from '../../utils/BrowserServices';\r\nimport { withStyles } from '@material-ui/core/styles';\r\nimport TableCell from '@material-ui/core/TableCell';\r\n\r\n\r\nconst styles = (theme) => ({\r\n gridColumn: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n flex: '1 1 auto',\r\n height: '100%'\r\n },\r\n headerContainer: {\r\n backgroundColor: theme.palette.primary.main,\r\n borderRadius: '4px 4px 0 0',\r\n },\r\n headerGrid: {\r\n width: '100%',\r\n overflow: 'hidden !important',\r\n border: `1px solid ${theme.palette.primary.main}`,\r\n borderRadius: '4px 4px 0 0',\r\n },\r\n bodyGrid: {\r\n width: '100%',\r\n },\r\n headerCell: {\r\n border: 'none',\r\n fontSize: '0.8rem',\r\n padding: theme.spacing(1),\r\n color: 'white',\r\n backgroundColor: theme.palette.primary.main,\r\n },\r\n bodyCell: {\r\n borderBottom: '1px solid rgba(224, 224, 224, 1)',\r\n borderLeft: '1px solid rgba(224, 224, 224, 1)',\r\n fontSize: '0.75rem',\r\n padding: theme.spacing(1),\r\n },\r\n truncateText: {\r\n whiteSpace: 'nowrap',\r\n overflow: 'hidden',\r\n textOverflow: 'ellipsis',\r\n },\r\n evenRow: {\r\n backgroundColor: '#ffffff',\r\n },\r\n oddRow: {\r\n backgroundColor: '#eeeeee',\r\n },\r\n flexContainer: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n boxSizing: 'border-box',\r\n },\r\n});\r\n\r\n\r\nconst RawVirtualizedGrid = ({\r\n rowCount, columns, columnWidth = 200, rowHeight = 40, overscanRowCount = 10, rowGetter, classes\r\n}) => {\r\n const headerCellRenderer = ({columnIndex, key, rowIndex, style, ...ohter}) => {\r\n const column = columns[columnIndex];\r\n const label = column.label || column.dataKey;\r\n \r\n return (\r\n {label}\r\n );\r\n }\r\n\r\n const bodyCellRenderer = ({columnIndex, key, rowIndex, style, ...ohter}) => {\r\n const rowData = rowGetter(rowIndex);\r\n const column = columns[columnIndex];\r\n\r\n let cellData = rowData[column.dataKey] || \"-\";\r\n if(column.dataKey ===\"#\"){\r\n cellData = (<>{rowIndex + 1}>);\r\n }\r\n else if (column.render) {\r\n cellData = column.render(rowData);\r\n }\r\n else if(cellData instanceof Date){\r\n cellData = `${cellData.toLocaleDateString()} ${cellData.toLocaleTimeString()}`\r\n }\r\n else if(typeof(cellData) === 'number') {\r\n if (cellData && !isNaN(cellData)) {\r\n cellData = Number(Math.round(cellData))\r\n }\r\n else\r\n cellData = \"-\";\r\n }\r\n else if (typeof(cellData) === 'object') {\r\n cellData = JSON.stringify(cellData);\r\n }\r\n\r\n return (\r\n {cellData}\r\n );\r\n }\r\n\r\n\r\n const renderGrid = ({clientHeight, clientWidth,\r\n onScroll, scrollHeight, scrollLeft, scrollTop, scrollWidth,\r\n }) => {\r\n return (\r\n
\r\n {({width, height}) => {\r\n const scrollBarSize = scrollbarSize();\r\n const headerRowHeight = rowHeight;\r\n return (<>\r\n \r\n \r\n
\r\n \r\n >);\r\n }}\r\n \r\n
);\r\n }\r\n\r\n\r\n return (\r\n {(scrollProps) => renderGrid(scrollProps)}\r\n );\r\n}\r\n\r\n\r\nRawVirtualizedGrid.propTypes = {\r\n rowCount: PropTypes.number.isRequired,\r\n columns: PropTypes.arrayOf(\r\n PropTypes.shape({\r\n dataKey: PropTypes.string.isRequired,\r\n label: PropTypes.string,\r\n render: PropTypes.func,\r\n decimalPlaces: PropTypes.number, //if typeof(value) number\r\n }),\r\n ).isRequired,\r\n columnWidth: PropTypes.number,\r\n rowHeight: PropTypes.number,\r\n overscanRowCount: PropTypes.number,\r\n rowGetter: PropTypes.func.isRequired,\r\n};\r\n\r\nexport default withStyles(styles)(RawVirtualizedGrid);","import React from 'react';\r\nimport ResourceLang from '../../resources/Language';\r\nimport PropTypes from 'prop-types';\r\nimport { Grid, InputLabel } from '@material-ui/core';\r\nimport RawVirtualizedGrid from '../tables/RawVirtualizedGrid'\r\n\r\nconst UploadReview = ({devices, next_version}) => {\r\n\r\n const DeviceKeysEnum = {\r\n UPDATE_VERSION: 'update_firmware_version',\r\n UPDATE_REQUEST_DATE_VERSION: 'update_request_date'\r\n }\r\n \r\n const renderContent = () => {\r\n return (\r\n \r\n \r\n \r\n \r\n {ResourceLang.next_version} {next_version}\r\n {ResourceLang.devices}\r\n {renderDeviceItems()}\r\n \r\n \r\n );\r\n }\r\n\r\n const renderDeviceItems = () => {\r\n const gridRowGetter = (index) => { return devices[index]; }\r\n const keys = Object.keys(devices[0]);\r\n var columns = keys.map(key => ({label: ResourceLang[key], dataKey:key}))\r\n .filter(x => x.dataKey !== DeviceKeysEnum.UPDATE_VERSION \r\n && x.dataKey !== DeviceKeysEnum.UPDATE_REQUEST_DATE_VERSION);\r\n \r\n return (\r\n \r\n
);\r\n }\r\n return (<>{renderContent()}>)\r\n}\r\n\r\nUploadReview.propTypes = {\r\n devices: PropTypes.object.isRequired,\r\n next_version: PropTypes.string.isRequired\r\n};\r\n\r\nexport default UploadReview;","import React from 'react'\r\nimport PropTypes from 'prop-types'\r\nimport ResourceLang from '../../resources/Language'\r\nimport {\r\n AutoSizer,\r\n Column,\r\n Table,\r\n InfiniteLoader,\r\n SortIndicator,\r\n defaultTableRowRenderer,\r\n} from 'react-virtualized'\r\nimport { Link } from 'react-router-dom'\r\nimport {\r\n ContextMenu,\r\n ContextMenuTrigger,\r\n connectMenu,\r\n hideMenu,\r\n} from 'react-contextmenu'\r\nimport { withStyles } from '@material-ui/core/styles'\r\nimport clsx from 'clsx'\r\nimport {\r\n TableRow,\r\n TableCell,\r\n Tooltip,\r\n Typography,\r\n IconButton,\r\n Paper,\r\n MenuList,\r\n MenuItem,\r\n Checkbox,\r\n} from '@material-ui/core'\r\nimport ExpandLessIcon from '@material-ui/icons/ExpandLess'\r\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore'\r\n\r\nconst styles = (theme) => ({\r\n flexContainer: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n boxSizing: 'border-box',\r\n },\r\n table: {\r\n // temporary right-to-left patch, waiting for\r\n // https://github.com/bvaughn/react-virtualized/issues/454\r\n '& .ReactVirtualized__Table__headerRow': {\r\n flip: false,\r\n paddingRight: theme.direction === 'rtl' ? '0px !important' : undefined,\r\n },\r\n },\r\n tableRow: {\r\n cursor: 'pointer',\r\n },\r\n tableRowHover: {\r\n '&:hover': {\r\n backgroundColor: theme.palette.grey[200],\r\n },\r\n },\r\n tableCell: {\r\n flex: 1,\r\n },\r\n tableFooter: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n },\r\n footerlabel: {\r\n marginLeft: theme.spacing(3),\r\n },\r\n firstCell: {\r\n marginLeft: theme.spacing(1),\r\n },\r\n noClick: {\r\n cursor: 'initial',\r\n },\r\n})\r\n\r\nconst MENU_TYPE = 'DYNAMIC'\r\nconst collectTriggerProps = (props) => props\r\n\r\nconst DynamicMenu = ({ id, contextMenuOptions, trigger }) => {\r\n const { data } = trigger || {}\r\n\r\n return (\r\n \r\n \r\n \r\n {!trigger\r\n ? null\r\n : contextMenuOptions.map(({ label, onClick }, index) => {\r\n const onMenuItemClick = (e) => {\r\n hideMenu()\r\n onClick(e, data)\r\n }\r\n\r\n return (\r\n \r\n )\r\n })}\r\n \r\n \r\n \r\n )\r\n}\r\n\r\nDynamicMenu.propTypes = {\r\n id: PropTypes.string.isRequired,\r\n contextMenuOptions: PropTypes.arrayOf(\r\n PropTypes.shape({\r\n label: PropTypes.string.isRequired,\r\n onClick: PropTypes.func.isRequired,\r\n })\r\n ).isRequired,\r\n trigger: PropTypes.shape({\r\n data: PropTypes.object.isRequired,\r\n }),\r\n}\r\n\r\nconst ConnectedMenu = connectMenu(MENU_TYPE)(DynamicMenu)\r\n\r\nclass MuiFiltersSelectAllVirtualizedTable extends React.PureComponent {\r\n static defaultProps = {\r\n disableHeader: false,\r\n headerHeight: 48,\r\n rowHeight: 48,\r\n detailRowHeight: 48 * 2,\r\n }\r\n\r\n constructor(props) {\r\n super(props)\r\n\r\n this.state = {\r\n selectedIndex: -1,\r\n }\r\n this.tableRef = React.createRef()\r\n this._isRowLoaded = this._isRowLoaded.bind(this)\r\n this._loadMoreRows = this._loadMoreRows.bind(this)\r\n this._handleExpandClick = this._handleExpandClick.bind(this)\r\n }\r\n\r\n cellRenderer = ({ cellData, columnIndex, rowIndex, rowData }) => {\r\n const { columns, rowHeight, classes } = this.props\r\n const column = columns[columnIndex]\r\n let value = cellData\r\n\r\n if (column.dataKey === '#') {\r\n value = {rowIndex + 1}
\r\n } else if (column.render) {\r\n value = column.render(rowData)\r\n } else if (column.date === true) {\r\n const date = new Date(cellData)\r\n value = `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`\r\n } else if (column.numeric === true) {\r\n const decimalPlaces = column.decimalPlaces || 2\r\n if (cellData && !isNaN(cellData)) {\r\n value = Number(\r\n Math.round(value + ('e' + decimalPlaces)) + ('e-' + decimalPlaces)\r\n ).toFixed(decimalPlaces)\r\n } else value = '-'\r\n }\r\n\r\n if (column.link) {\r\n value = (\r\n event.stopPropagation()}\r\n to={column.link(rowData)}\r\n >\r\n {value}\r\n \r\n )\r\n }\r\n\r\n return (\r\n \r\n {value}\r\n \r\n )\r\n }\r\n\r\n headerRenderer = ({\r\n label,\r\n columnIndex,\r\n dataKey,\r\n sortBy,\r\n sortDirection,\r\n selectAll,\r\n allSelected,\r\n }) => {\r\n const { headerHeight, columns, classes } = this.props\r\n const column = columns[columnIndex]\r\n\r\n let content = ''\r\n if (columnIndex === 0) {\r\n content = (\r\n \r\n \r\n {\r\n selectAll(e)\r\n }}\r\n color='primary'\r\n checked={allSelected}\r\n />\r\n \r\n {sortBy === dataKey && (\r\n \r\n )}\r\n
\r\n )\r\n } else {\r\n content = (\r\n <>\r\n {label}\r\n {sortBy === dataKey && (\r\n \r\n )}\r\n >\r\n )\r\n }\r\n\r\n return (\r\n \r\n {content}\r\n \r\n )\r\n }\r\n\r\n rowRendererDetailed = (params) => {\r\n const { classes, rowHeight, detailRowHeight, detailRowRenderer } =\r\n this.props\r\n const { index, style, className, key } = params\r\n\r\n if (index === this.state.selectedIndex) {\r\n return (\r\n \r\n {defaultTableRowRenderer({\r\n ...params,\r\n style: { width: '100%', height: rowHeight },\r\n })}\r\n
{\r\n let target = event.target\r\n\r\n while (target.getAttribute('role') !== 'row') {\r\n target = target.parentNode\r\n }\r\n\r\n target.previousElementSibling.click()\r\n }}\r\n >\r\n {detailRowRenderer(params, detailRowHeight)}\r\n \r\n
\r\n )\r\n } else return defaultTableRowRenderer(params)\r\n }\r\n\r\n renderDetailButton = (width) => {\r\n const { classes, headerHeight, rowHeight } = this.props\r\n const key = 'detailButton'\r\n const disableSort = true\r\n\r\n return (\r\n {\r\n return (\r\n \r\n )\r\n }}\r\n cellRenderer={({ cellData, columnIndex, rowIndex, rowData }) => {\r\n const isSelected = this.state.selectedIndex === rowIndex\r\n const expandIcon = isSelected ? (\r\n \r\n ) : (\r\n \r\n )\r\n const label = isSelected\r\n ? ResourceLang.HideDetails\r\n : ResourceLang.ShowDetails\r\n\r\n return (\r\n \r\n \r\n {\r\n event.stopPropagation()\r\n this._handleExpandClick(rowIndex)\r\n }}\r\n >\r\n {expandIcon}\r\n \r\n \r\n \r\n )\r\n }}\r\n />\r\n )\r\n }\r\n\r\n getRowClassName = ({ index }) => {\r\n const { classes } = this.props\r\n return index !== -1\r\n ? clsx(classes.tableRow, classes.flexContainer, classes.tableRowHover)\r\n : clsx(classes.tableRow, classes.flexContainer)\r\n }\r\n\r\n getHeaderRowClassName = (disableSort) => {\r\n const { classes } = this.props\r\n return clsx([\r\n classes.tableCell,\r\n classes.flexContainer,\r\n disableSort === true ? classes.noClick : classes.tableRow,\r\n ])\r\n }\r\n\r\n getRowHeight = ({ index }) => {\r\n return index === this.state.selectedIndex\r\n ? this.props.detailRowHeight + this.props.rowHeight\r\n : this.props.rowHeight\r\n }\r\n\r\n getColumnAlign = (column) => {\r\n if (column.align) return column.align\r\n\r\n return column.numeric ? 'right' : 'left'\r\n }\r\n\r\n _isRowLoaded(args) {\r\n const obj = this.props.rowGetter(args)\r\n return obj !== undefined\r\n }\r\n\r\n _loadMoreRows(args) {\r\n this.props.onLoadMore(args)\r\n }\r\n\r\n _handleExpandClick(rowIndex) {\r\n const newIndex = this.state.selectedIndex === rowIndex ? -1 : rowIndex\r\n this.setState({ ...this.state, selectedIndex: newIndex })\r\n\r\n if (this.tableRef) {\r\n this.tableRef.recomputeRowHeights()\r\n }\r\n }\r\n\r\n render() {\r\n const {\r\n classes,\r\n columns,\r\n rowHeight,\r\n headerHeight,\r\n disableHeader,\r\n detailRowRenderer,\r\n contextMenuOptions,\r\n selectAll,\r\n allSelected,\r\n ...tableProps\r\n } = this.props\r\n const footerHeight = headerHeight\r\n\r\n const rowContentRenderer = detailRowRenderer\r\n ? this.rowRendererDetailed\r\n : defaultTableRowRenderer\r\n const rowRenderer = !contextMenuOptions\r\n ? rowContentRenderer\r\n : (params) => {\r\n const { style, key, rowData } = params\r\n\r\n return (\r\n \r\n )\r\n }\r\n\r\n return (\r\n <>\r\n \r\n {({ onRowsRendered, registerChild }) => (\r\n \r\n {({ height, width }) => (\r\n <>\r\n {\r\n this.tableRef = ref\r\n registerChild(ref)\r\n }}\r\n onRowsRendered={onRowsRendered}\r\n height={height - footerHeight}\r\n width={width}\r\n rowHeight={\r\n detailRowRenderer ? this.getRowHeight : rowHeight\r\n }\r\n gridStyle={{ direction: 'inherit' }}\r\n disableHeader={disableHeader}\r\n headerHeight={headerHeight}\r\n className={classes.table}\r\n {...tableProps}\r\n rowRenderer={rowRenderer}\r\n rowClassName={this.getRowClassName}\r\n >\r\n {columns.map(\r\n ({ dataKey, columnWidth, ...other }, index) => {\r\n const cellWidth = columnWidth * width\r\n return (\r\n \r\n this.headerRenderer({\r\n ...headerProps,\r\n columnIndex: index,\r\n selectAll: selectAll,\r\n allSelected: allSelected,\r\n })\r\n }\r\n className={classes.flexContainer}\r\n cellRenderer={this.cellRenderer}\r\n dataKey={dataKey}\r\n width={cellWidth}\r\n {...other}\r\n />\r\n )\r\n }\r\n )}\r\n {detailRowRenderer ? this.renderDetailButton(width) : null}\r\n
\r\n \r\n \r\n {this.props.totalRows} {ResourceLang.items}\r\n \r\n
\r\n >\r\n )}\r\n \r\n )}\r\n \r\n {contextMenuOptions ? (\r\n \r\n ) : null}\r\n >\r\n )\r\n }\r\n}\r\n\r\nMuiFiltersSelectAllVirtualizedTable.propTypes = {\r\n classes: PropTypes.object.isRequired,\r\n columns: PropTypes.arrayOf(\r\n PropTypes.shape({\r\n dataKey: PropTypes.string.isRequired,\r\n label: PropTypes.string,\r\n numeric: PropTypes.bool,\r\n date: PropTypes.bool,\r\n align: PropTypes.oneOf(['left', 'center', 'right']),\r\n columnWidth: PropTypes.number.isRequired,\r\n render: PropTypes.func,\r\n link: PropTypes.func,\r\n })\r\n ).isRequired,\r\n disableHeader: PropTypes.bool,\r\n headerHeight: PropTypes.number,\r\n onRowClick: PropTypes.func,\r\n rowHeight: PropTypes.number,\r\n detailRowRenderer: PropTypes.func,\r\n detailRowHeight: PropTypes.number,\r\n selectAll: PropTypes.func,\r\n allSelected: PropTypes.bool,\r\n contextMenuOptions: PropTypes.arrayOf(\r\n PropTypes.shape({\r\n label: PropTypes.string.isRequired,\r\n onClick: PropTypes.func.isRequired,\r\n })\r\n ),\r\n}\r\n\r\nexport default withStyles(styles)(MuiFiltersSelectAllVirtualizedTable)\r\n","import React from 'react'\r\nimport PropTypes from 'prop-types'\r\nimport ResourceLang from '../../resources/Language'\r\nimport {\r\n AutoSizer,\r\n Column,\r\n Table,\r\n InfiniteLoader,\r\n SortIndicator,\r\n defaultTableRowRenderer,\r\n} from 'react-virtualized'\r\nimport { Link } from 'react-router-dom'\r\nimport {\r\n ContextMenu,\r\n ContextMenuTrigger,\r\n connectMenu,\r\n hideMenu,\r\n} from 'react-contextmenu'\r\nimport { withStyles } from '@material-ui/core/styles'\r\nimport clsx from 'clsx'\r\nimport {\r\n TableRow,\r\n TableCell,\r\n Tooltip,\r\n Typography,\r\n IconButton,\r\n Paper,\r\n MenuList,\r\n MenuItem,\r\n} from '@material-ui/core'\r\nimport ExpandLessIcon from '@material-ui/icons/ExpandLess'\r\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore'\r\n\r\nconst styles = (theme) => ({\r\n flexContainer: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n boxSizing: 'border-box',\r\n },\r\n table: {\r\n // temporary right-to-left patch, waiting for\r\n // https://github.com/bvaughn/react-virtualized/issues/454\r\n '& .ReactVirtualized__Table__headerRow': {\r\n flip: false,\r\n paddingRight: theme.direction === 'rtl' ? '0px !important' : undefined,\r\n },\r\n },\r\n tableRow: {\r\n cursor: 'pointer',\r\n },\r\n tableRowHover: {\r\n '&:hover': {\r\n backgroundColor: theme.palette.grey[200],\r\n },\r\n },\r\n tableCell: {\r\n flex: 1,\r\n },\r\n tableFooter: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n },\r\n footerlabel: {\r\n marginLeft: theme.spacing(3),\r\n },\r\n firstCell: {\r\n marginLeft: theme.spacing(1),\r\n },\r\n noClick: {\r\n cursor: 'initial',\r\n },\r\n})\r\n\r\nconst MENU_TYPE = 'DYNAMIC'\r\nconst collectTriggerProps = (props) => props\r\n\r\nconst DynamicMenu = ({ id, contextMenuOptions, trigger }) => {\r\n const { data } = trigger || {}\r\n\r\n return (\r\n \r\n \r\n \r\n {!trigger\r\n ? null\r\n : contextMenuOptions.map(({ label, onClick }, index) => {\r\n const onMenuItemClick = (e) => {\r\n hideMenu()\r\n onClick(e, data)\r\n }\r\n\r\n return (\r\n \r\n )\r\n })}\r\n \r\n \r\n \r\n )\r\n}\r\n\r\nDynamicMenu.propTypes = {\r\n id: PropTypes.string.isRequired,\r\n contextMenuOptions: PropTypes.arrayOf(\r\n PropTypes.shape({\r\n label: PropTypes.string.isRequired,\r\n onClick: PropTypes.func.isRequired,\r\n })\r\n ).isRequired,\r\n trigger: PropTypes.shape({\r\n data: PropTypes.object.isRequired,\r\n }),\r\n}\r\n\r\nconst ConnectedMenu = connectMenu(MENU_TYPE)(DynamicMenu)\r\n\r\nclass MuiVirtualizedTable extends React.PureComponent {\r\n static defaultProps = {\r\n disableHeader: false,\r\n headerHeight: 48,\r\n rowHeight: 48,\r\n detailRowHeight: 48 * 2,\r\n }\r\n\r\n constructor(props) {\r\n super(props)\r\n\r\n this.state = {\r\n selectedIndex: -1,\r\n }\r\n this.tableRef = React.createRef()\r\n this._isRowLoaded = this._isRowLoaded.bind(this)\r\n this._loadMoreRows = this._loadMoreRows.bind(this)\r\n this._handleExpandClick = this._handleExpandClick.bind(this)\r\n }\r\n\r\n cellRenderer = ({ cellData, columnIndex, rowIndex, rowData }) => {\r\n const { columns, rowHeight, classes } = this.props\r\n const column = columns[columnIndex]\r\n let value = cellData\r\n\r\n if (column.dataKey === '#') {\r\n value = {rowIndex + 1}
\r\n } else if (column.render) {\r\n value = column.render(rowData)\r\n } else if (column.date === true) {\r\n const date = new Date(cellData)\r\n value = `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`\r\n } else if (column.numeric === true) {\r\n const decimalPlaces = column.decimalPlaces || 2\r\n if (cellData && !isNaN(cellData)) {\r\n value = Number(\r\n Math.round(value + ('e' + decimalPlaces)) + ('e-' + decimalPlaces)\r\n ).toFixed(decimalPlaces)\r\n } else value = '-'\r\n }\r\n\r\n if (column.link) {\r\n value = (\r\n event.stopPropagation()}\r\n to={column.link(rowData)}\r\n >\r\n {value}\r\n \r\n )\r\n }\r\n\r\n return (\r\n \r\n {value}\r\n \r\n )\r\n }\r\n\r\n headerRenderer = ({ label, columnIndex, dataKey, sortBy, sortDirection }) => {\r\n const { headerHeight, columns, classes } = this.props\r\n const column = columns[columnIndex]\r\n\r\n let content = ''\r\n if (columnIndex === 0) {\r\n content = (\r\n \r\n {label}\r\n {sortBy === dataKey && (\r\n \r\n )}\r\n
\r\n )\r\n } else {\r\n content = (\r\n <>\r\n {label}\r\n {sortBy === dataKey && (\r\n \r\n )}\r\n >\r\n )\r\n }\r\n\r\n return (\r\n \r\n {content}\r\n \r\n )\r\n }\r\n\r\n rowRendererDetailed = (params) => {\r\n const { classes, rowHeight, detailRowHeight, detailRowRenderer } =\r\n this.props\r\n const { index, style, className, key } = params\r\n\r\n if (index === this.state.selectedIndex) {\r\n return (\r\n \r\n {defaultTableRowRenderer({\r\n ...params,\r\n style: { width: '100%', height: rowHeight },\r\n })}\r\n
{\r\n let target = event.target\r\n\r\n while (target.getAttribute('role') !== 'row') {\r\n target = target.parentNode\r\n }\r\n\r\n target.previousElementSibling.click()\r\n }}\r\n >\r\n {detailRowRenderer(params, detailRowHeight)}\r\n \r\n
\r\n )\r\n } else return defaultTableRowRenderer(params)\r\n }\r\n\r\n renderDetailButton = (width) => {\r\n const { classes, headerHeight, rowHeight } = this.props\r\n const key = 'detailButton'\r\n const disableSort = true\r\n\r\n return (\r\n {\r\n return (\r\n \r\n )\r\n }}\r\n cellRenderer={({ cellData, columnIndex, rowIndex, rowData }) => {\r\n const isSelected = this.state.selectedIndex === rowIndex\r\n const expandIcon = isSelected ? (\r\n \r\n ) : (\r\n \r\n )\r\n const label = isSelected\r\n ? ResourceLang.HideDetails\r\n : ResourceLang.ShowDetails\r\n\r\n return (\r\n \r\n \r\n {\r\n event.stopPropagation()\r\n this._handleExpandClick(rowIndex)\r\n }}\r\n >\r\n {expandIcon}\r\n \r\n \r\n \r\n )\r\n }}\r\n />\r\n )\r\n }\r\n\r\n getRowClassName = ({ index }) => {\r\n const { classes } = this.props\r\n return index !== -1\r\n ? clsx(classes.tableRow, classes.flexContainer, classes.tableRowHover)\r\n : clsx(classes.tableRow, classes.flexContainer)\r\n }\r\n\r\n getHeaderRowClassName = (disableSort) => {\r\n const { classes } = this.props\r\n return clsx([\r\n classes.tableCell,\r\n classes.flexContainer,\r\n disableSort === true ? classes.noClick : classes.tableRow,\r\n ])\r\n }\r\n\r\n getRowHeight = ({ index }) => {\r\n return index === this.state.selectedIndex\r\n ? this.props.detailRowHeight + this.props.rowHeight\r\n : this.props.rowHeight\r\n }\r\n\r\n getColumnAlign = (column) => {\r\n if (column.align) return column.align\r\n\r\n return column.numeric ? 'right' : 'left'\r\n }\r\n\r\n _isRowLoaded(args) {\r\n const obj = this.props.rowGetter(args)\r\n return obj !== undefined\r\n }\r\n\r\n _loadMoreRows(args) {\r\n this.props.onLoadMore(args)\r\n }\r\n\r\n _handleExpandClick(rowIndex) {\r\n const newIndex = this.state.selectedIndex === rowIndex ? -1 : rowIndex\r\n this.setState({ ...this.state, selectedIndex: newIndex })\r\n\r\n if (this.tableRef) {\r\n this.tableRef.recomputeRowHeights()\r\n }\r\n }\r\n\r\n render() {\r\n const {\r\n classes,\r\n columns,\r\n rowHeight,\r\n headerHeight,\r\n disableHeader,\r\n detailRowRenderer,\r\n contextMenuOptions,\r\n ...tableProps\r\n } = this.props\r\n const footerHeight = headerHeight\r\n\r\n const rowContentRenderer = detailRowRenderer\r\n ? this.rowRendererDetailed\r\n : defaultTableRowRenderer\r\n const rowRenderer = !contextMenuOptions\r\n ? rowContentRenderer\r\n : (params) => {\r\n const { style, key, rowData } = params\r\n\r\n return (\r\n \r\n )\r\n }\r\n\r\n return (\r\n <>\r\n \r\n {({ onRowsRendered, registerChild }) => (\r\n \r\n {({ height, width }) => (\r\n <>\r\n {\r\n this.tableRef = ref\r\n registerChild(ref)\r\n }}\r\n onRowsRendered={onRowsRendered}\r\n height={height - footerHeight}\r\n width={width}\r\n rowHeight={\r\n detailRowRenderer ? this.getRowHeight : rowHeight\r\n }\r\n gridStyle={{ direction: 'inherit' }}\r\n disableHeader={disableHeader}\r\n headerHeight={headerHeight}\r\n className={classes.table}\r\n {...tableProps}\r\n rowRenderer={rowRenderer}\r\n rowClassName={this.getRowClassName}\r\n >\r\n {columns.map(\r\n ({ dataKey, columnWidth, ...other }, index) => {\r\n const cellWidth = columnWidth * width\r\n return (\r\n \r\n this.headerRenderer({\r\n ...headerProps,\r\n columnIndex: index,\r\n })\r\n }\r\n className={classes.flexContainer}\r\n cellRenderer={this.cellRenderer}\r\n dataKey={dataKey}\r\n width={cellWidth}\r\n {...other}\r\n />\r\n )\r\n }\r\n )}\r\n {detailRowRenderer ? this.renderDetailButton(width) : null}\r\n
\r\n \r\n \r\n {this.props.totalRows} {ResourceLang.items}\r\n \r\n
\r\n >\r\n )}\r\n \r\n )}\r\n \r\n {contextMenuOptions ? (\r\n \r\n ) : null}\r\n >\r\n )\r\n }\r\n}\r\n\r\nMuiVirtualizedTable.propTypes = {\r\n classes: PropTypes.object.isRequired,\r\n columns: PropTypes.arrayOf(\r\n PropTypes.shape({\r\n dataKey: PropTypes.string.isRequired,\r\n label: PropTypes.string,\r\n numeric: PropTypes.bool,\r\n date: PropTypes.bool,\r\n align: PropTypes.oneOf(['left', 'center', 'right']),\r\n columnWidth: PropTypes.number.isRequired,\r\n render: PropTypes.func,\r\n link: PropTypes.func,\r\n })\r\n ).isRequired,\r\n disableHeader: PropTypes.bool,\r\n headerHeight: PropTypes.number,\r\n onRowClick: PropTypes.func,\r\n rowHeight: PropTypes.number,\r\n detailRowRenderer: PropTypes.func,\r\n detailRowHeight: PropTypes.number,\r\n contextMenuOptions: PropTypes.arrayOf(\r\n PropTypes.shape({\r\n label: PropTypes.string.isRequired,\r\n onClick: PropTypes.func.isRequired,\r\n })\r\n ),\r\n}\r\n\r\nexport default withStyles(styles)(MuiVirtualizedTable)\r\n","const DEVICE_KEYS = {\r\n CURRENT_VERSION: 'current_firmware_version',\r\n UPDATE_VERSION: 'update_firmware_version',\r\n UPDATE_REQUEST_DATE_VERSION: 'update_request_date',\r\n DEVICE_ID: 'device_id',\r\n SERIAL_NUMBER: 'serial_number',\r\n FIRMWARE_DOWNLOAD_ATEMPTS: 'firmware_download_atempts',\r\n FIRMWARE_ID: 'firmware_id'\r\n}\r\n\r\nconst SETTINGS_TYPE = {\r\n APN: 1,\r\n NTP: 2\r\n}\r\n\r\nconst DEVICE_VERSION_VALUES = {\r\n V1:\"V1\",\r\n V2:\"V2\",\r\n V3:\"V3\",\r\n V4: \"V4\"\r\n};\r\n\r\nexport const DEVICE_KEYS_ENUM = Object.freeze(DEVICE_KEYS);\r\nexport const DEVICE_VERSION_VALUES_ENUM = Object.freeze(DEVICE_VERSION_VALUES);\r\nexport const SETTINGS_TYPE_ENUM = Object.freeze(SETTINGS_TYPE);","import React from 'react'\r\nimport PropTypes from 'prop-types'\r\nimport ResourceLang from '../../resources/Language'\r\nimport { getDateTimeStringFormat, is12Hours } from '../../utils/DateServices'\r\nimport {\r\n Grid,\r\n Popover,\r\n Typography,\r\n TextField,\r\n LinearProgress,\r\n FormControl,\r\n IconButton,\r\n InputAdornment,\r\n} from '@material-ui/core'\r\nimport { withStyles } from '@material-ui/core/styles'\r\nimport { Autocomplete } from '@material-ui/lab'\r\nimport { DateTimePicker, MuiPickersUtilsProvider } from '@material-ui/pickers'\r\nimport MomentUtils from '@date-io/moment'\r\nimport EventIcon from '@material-ui/icons/Event'\r\n//TODO: update @date-io/moment to lastest version after @material-ui/pickers 4 has been released.\r\n\r\nconst styles = (theme) => ({\r\n container: {\r\n padding: theme.spacing(2),\r\n maxWidth: 1000,\r\n minWidth: 400,\r\n marginBottom: 20,\r\n },\r\n formControl: {\r\n width: '100%',\r\n minWidth: 200,\r\n },\r\n option: {\r\n fontSize: 15,\r\n '& > span': {\r\n marginRight: 10,\r\n fontSize: 18,\r\n },\r\n },\r\n})\r\n\r\nconst FilterPopover = ({\r\n filters,\r\n classes,\r\n anchorEl,\r\n updateAnchorEl,\r\n onChange,\r\n}) => {\r\n const renderFilter = (filter, isLoading) => {\r\n switch (filter.type) {\r\n case 'select':\r\n return renderSelectFilter(filter, isLoading)\r\n default:\r\n case 'text':\r\n return renderTextFilter(filter, isLoading)\r\n case 'date':\r\n return renderDateFilter(filter, isLoading)\r\n }\r\n }\r\n\r\n const renderSelectFilter = (filter, isLoading) => {\r\n const { key, label, options, value = [], multiple } = filter\r\n\r\n return (\r\n option.name}\r\n getOptionSelected={(option) => {\r\n const target = value.find((x) => x.value === option.value)\r\n return target != null ? true : false\r\n }}\r\n disabled={isLoading}\r\n value={value}\r\n onChange={(event, newValue) => {\r\n const result =\r\n !multiple && newValue.length === 2 ? [newValue[1]] : newValue\r\n handleValueChange(result, key)\r\n }}\r\n renderInput={(params) => (\r\n \r\n )}\r\n />\r\n )\r\n }\r\n\r\n const renderTextFilter = (filter, isLoading) => {\r\n const { key, label, value, options } = filter\r\n\r\n return (\r\n {\r\n return option && typeof option === 'object' ? option.name : option\r\n }}\r\n disabled={isLoading}\r\n value={value == null ? '' : value}\r\n onInputChange={(event, newValue) =>\r\n handleValueChange(\r\n newValue && typeof newValue === 'object' ? newValue.name : newValue,\r\n key\r\n )\r\n }\r\n renderInput={(params) => (\r\n \r\n )}\r\n />\r\n )\r\n }\r\n\r\n const renderDateFilter = (filter, isLoading) => {\r\n const { key, label, value, maxValueKey, minValueKey } = filter\r\n const is12Hour = is12Hours(value || new Date())\r\n let maxDate = undefined\r\n let minDate = undefined\r\n\r\n if (maxValueKey) {\r\n const target = filters.find((x) => x.key === maxValueKey)\r\n maxDate = target && target.value ? target.value : undefined\r\n }\r\n\r\n if (minValueKey) {\r\n const target = filters.find((x) => x.key === minValueKey)\r\n minDate = target && target.value ? target.value : undefined\r\n }\r\n\r\n return (\r\n \r\n \r\n handleValueChange(date.toDate(), key)}\r\n labelFunc={(date) => {\r\n return date ? getDateTimeStringFormat(date.toDate()) : ''\r\n }}\r\n minDate={minDate}\r\n maxDate={maxDate}\r\n strictCompareDates={true}\r\n InputProps={{\r\n endAdornment: (\r\n \r\n \r\n \r\n \r\n \r\n ),\r\n }}\r\n />\r\n \r\n \r\n )\r\n }\r\n\r\n const handleValueChange = (newValue, key) => {\r\n const newFilters = [...filters]\r\n const target = newFilters.find((x) => x.key === key)\r\n\r\n if (target) {\r\n target.value = newValue\r\n }\r\n\r\n onChange(newFilters)\r\n }\r\n\r\n const renderContent = () => {\r\n let loadingSpinner = null\r\n let isLoading = false\r\n\r\n if (anchorEl) {\r\n //gather data if necessary\r\n const optionsToGet = filters.filter((x) => x.getOptions && !x.options)\r\n\r\n if (optionsToGet.length > 0) {\r\n const promisses = optionsToGet.map((x) => x.getOptions())\r\n Promise.all(promisses).then((responses) => {\r\n const newFilters = [...filters]\r\n\r\n for (let i = 0; i < optionsToGet.length; i++) {\r\n const target = newFilters.find((x) => x.key === optionsToGet[i].key)\r\n if (target) {\r\n target.options = responses[i] || []\r\n }\r\n }\r\n\r\n onChange(newFilters)\r\n })\r\n\r\n isLoading = true\r\n loadingSpinner = \r\n }\r\n }\r\n\r\n const xsSize = filters.length >= 2 ? 6 : 12\r\n const mdSize = filters.length >= 3 ? 6 : xsSize\r\n\r\n return (\r\n \r\n \r\n {ResourceLang.Filters}\r\n {loadingSpinner}\r\n \r\n {filters.map((item) => {\r\n return (\r\n \r\n {renderFilter(item, isLoading)}\r\n \r\n )\r\n })}\r\n \r\n )\r\n }\r\n\r\n return (\r\n {\r\n updateAnchorEl(null)\r\n }}\r\n anchorOrigin={{\r\n vertical: 'bottom',\r\n horizontal: 'center',\r\n }}\r\n transformOrigin={{\r\n vertical: 'top',\r\n horizontal: 'center',\r\n }}\r\n >\r\n {renderContent()}
\r\n \r\n )\r\n}\r\n\r\nFilterPopover.propTypes = {\r\n filters: PropTypes.arrayOf(\r\n PropTypes.shape({\r\n key: PropTypes.string.isRequired,\r\n label: PropTypes.string.isRequired,\r\n type: PropTypes.oneOf(['date', 'text', 'select']),\r\n options: PropTypes.arrayOf(\r\n PropTypes.shape({\r\n name: PropTypes.string.isRequired,\r\n value: PropTypes.oneOfType([PropTypes.number, PropTypes.string])\r\n .isRequired,\r\n })\r\n ),\r\n getOptions: PropTypes.func,\r\n value: PropTypes.oneOfType([\r\n PropTypes.string,\r\n PropTypes.number,\r\n PropTypes.instanceOf(Date),\r\n PropTypes.arrayOf(\r\n PropTypes.shape({\r\n name: PropTypes.string.isRequired,\r\n value: PropTypes.oneOfType([PropTypes.number, PropTypes.string])\r\n .isRequired,\r\n })\r\n ),\r\n ]),\r\n multiple: PropTypes.bool,\r\n maxValueKey: PropTypes.string,\r\n minValueKey: PropTypes.string,\r\n })\r\n ).isRequired,\r\n anchorEl: PropTypes.oneOfType([\r\n PropTypes.instanceOf(Element),\r\n PropTypes.func,\r\n ]),\r\n updateAnchorEl: PropTypes.func.isRequired,\r\n onChange: PropTypes.func.isRequired,\r\n}\r\n\r\nexport default withStyles(styles)(FilterPopover)\r\n","export function getLocalDateTimeString(value){\r\n if(!value || value === '')\r\n return '';\r\n\r\n const date = (typeof(value) === 'string' || typeof(value) === 'number' ?\r\n new Date(value) : value);\r\n\r\n return `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;\r\n}\r\n\r\nexport function getDateTimeStringFormat(date){\r\n if(date === null || date === undefined || date === '')\r\n return '';\r\n \r\n return date.toLocaleDateString() + \" \" + date.toLocaleTimeString();\r\n}\r\n\r\nexport function is12Hours(date) {\r\n return date.toLocaleTimeString().match(/am|pm/i);\r\n}\r\n\r\nexport function addDays (date, days) {\r\n const newDate = new Date(date);\r\n newDate.setDate(date.getDate() + days);\r\n return newDate;\r\n}\r\n\r\nexport function addMonths (date, moths) {\r\n const newDate = new Date(date);\r\n newDate.setMonth(date.getMonth() + moths);\r\n return newDate;\r\n}\r\n\r\n\r\n","import React from 'react'\r\nimport PropTypes from 'prop-types'\r\nimport { withStyles } from '@material-ui/core/styles'\r\nimport FilterListIcon from '@material-ui/icons/FilterList'\r\nimport FilterPopover from '../filters/FilterPopover'\r\nimport Tooltip from '@material-ui/core/Tooltip'\r\nimport { IconButton } from '@material-ui/core'\r\nimport ResourceLang from '../../resources/Language'\r\n\r\nconst styles = () => ({\r\n header: {\r\n display: 'flex',\r\n flexDirection: 'row',\r\n height: '2rem',\r\n alignItems: 'center',\r\n backgroundColor: 'rgba(0, 0, 0, 0.05)',\r\n border: '1px solid rgba(0, 0, 0, 0.15)',\r\n borderRadius: '0.5vh',\r\n },\r\n title: {\r\n fontWeight: 'bold',\r\n fontSize: '14px',\r\n },\r\n leftCell: {\r\n marginLeft: '1.5rem',\r\n marginRight: 'auto',\r\n },\r\n rightCell: {\r\n marginRight: '1.5rem',\r\n marginLeft: 'auto',\r\n },\r\n})\r\n\r\nconst TableHeader = ({\r\n tableTitle,\r\n filters,\r\n anchorEl,\r\n updateAnchorEl,\r\n setFilters,\r\n classes,\r\n showFilters,\r\n}) => {\r\n return (\r\n <>\r\n \r\n
\r\n {tableTitle}\r\n
\r\n {showFilters === false ? (\r\n <>>\r\n ) : (\r\n <>\r\n
\r\n \r\n updateAnchorEl(event.currentTarget)}\r\n >\r\n \r\n \r\n \r\n \r\n
\r\n >\r\n )}\r\n
\r\n >\r\n )\r\n}\r\n\r\nTableHeader.propTypes = {\r\n tableTitle: PropTypes.string,\r\n filters: PropTypes.array.isRequired,\r\n anchorEl: PropTypes.oneOfType([\r\n PropTypes.instanceOf(Element),\r\n PropTypes.func,\r\n ]),\r\n updateAnchorEl: PropTypes.func.isRequired,\r\n setFilters: PropTypes.func.isRequired,\r\n showFilters: PropTypes.bool,\r\n}\r\n\r\nexport default withStyles(styles)(TableHeader)\r\n","import React, { useEffect, useState } from 'react'\r\nimport ResourceLang from '../../resources/Language'\r\nimport { withRouter } from 'react-router'\r\nimport Grid from '@material-ui/core/Grid'\r\nimport Checkbox from '@material-ui/core/Checkbox'\r\nimport { compareValues } from '../../utils/BrowserServices'\r\nimport MuiFiltersSelectAllVirtualizedTable from '../tables/MuiFiltersSelectAllVirtualizedTable'\r\nimport MuiVirtualizedTable from '../tables/MuiVirtualizedTable'\r\nimport CircularLoading from '../loadings/CircularLoading'\r\nimport { SortDirection } from 'react-virtualized'\r\nimport PropTypes from 'prop-types'\r\nimport { DEVICE_KEYS_ENUM } from '../../utils/Enums'\r\nimport TableHeader from '../tables/TableHeader'\r\n\r\nconst SelectDevices = ({\r\n devices,\r\n selectedDevices,\r\n availableVersions,\r\n filteredAvailableVersions,\r\n handleSelection,\r\n handleAllSelections,\r\n isLoading,\r\n currentVersions,\r\n updateVersions,\r\n handleFilters,\r\n}) => {\r\n const pageHeight = window.innerHeight\r\n const percentageOffSet = 0.45\r\n const [versionsSort, setVersionsSort] = useState({\r\n sortBy: DEVICE_KEYS_ENUM.CURRENT_VERSION,\r\n sortDirection: 'DESC',\r\n })\r\n const [devicesSort, setDevicesSort] = useState({\r\n sortBy: DEVICE_KEYS_ENUM.SERIAL_NUMBER,\r\n sortDirection: 'DESC',\r\n })\r\n const [allSelected, setAllSelected] = useState(false)\r\n\r\n const [anchorEl, updateAnchorEl] = useState(null)\r\n const [filters, setFilters] = useState([\r\n {\r\n key: 'current_version',\r\n label: ResourceLang.current_version,\r\n type: 'select',\r\n options: currentVersions,\r\n },\r\n {\r\n key: 'update_version',\r\n label: ResourceLang.update_version,\r\n type: 'select',\r\n options: updateVersions,\r\n },\r\n ])\r\n\r\n useEffect(() => {\r\n filters.forEach((filter) => {\r\n if (filter.key === 'current_version') {\r\n filter.options = currentVersions\r\n }\r\n\r\n if (filter.key === 'update_version') {\r\n filter.options = updateVersions\r\n }\r\n })\r\n }, [currentVersions, updateVersions, filters])\r\n\r\n useEffect(() => {\r\n handleFilters(filters)\r\n }, [filters, handleFilters])\r\n\r\n const handleSelectDevice = (rowData, event) => {\r\n handleSelection(rowData, event.target.checked)\r\n }\r\n\r\n const isSelected = (rowData) => {\r\n const isChecked = selectedDevices.some(function (device) {\r\n return device.device_id === rowData.device_id\r\n })\r\n\r\n return isChecked\r\n }\r\n\r\n const getTableItems = (items, sort) => {\r\n if (sort.sortDirection === SortDirection.ASC) {\r\n items.sort((a, b) => compareValues(b[sort.sortBy], a[sort.sortBy]))\r\n } else {\r\n items.sort((a, b) => compareValues(a[sort.sortBy], b[sort.sortBy]))\r\n }\r\n return items\r\n }\r\n\r\n const selectAll = (event) => {\r\n handleAllSelections(devices, event.target.checked)\r\n setAllSelected(event.target.checked)\r\n }\r\n\r\n const renderDevicesTable = () => {\r\n if (devices !== undefined && devices.length > 0) {\r\n const columns = [\r\n {\r\n columnWidth: 35,\r\n label: '#',\r\n dataKey: DEVICE_KEYS_ENUM.DEVICE_ID,\r\n disableSort: true,\r\n render: (rowData) => {\r\n return (\r\n {\r\n handleSelectDevice(rowData, e)\r\n }}\r\n color='primary'\r\n checked={isSelected(rowData)}\r\n />\r\n )\r\n },\r\n },\r\n {\r\n columnWidth: 75,\r\n label: ResourceLang.serial_number,\r\n dataKey: DEVICE_KEYS_ENUM.SERIAL_NUMBER,\r\n disableSort: false,\r\n },\r\n {\r\n columnWidth: 60,\r\n label: ResourceLang.current_version,\r\n dataKey: DEVICE_KEYS_ENUM.CURRENT_VERSION,\r\n disableSort: false,\r\n },\r\n {\r\n columnWidth: 60,\r\n label: ResourceLang.update_version,\r\n dataKey: DEVICE_KEYS_ENUM.UPDATE_VERSION,\r\n disableSort: false,\r\n },\r\n ]\r\n\r\n const handleSort = (event) => {\r\n setDevicesSort({\r\n sortBy: event.sortBy,\r\n sortDirection: event.sortDirection,\r\n })\r\n }\r\n\r\n const tableItems = getTableItems(devices, devicesSort)\r\n\r\n return (\r\n <>\r\n \r\n tableItems[index]}\r\n sort={handleSort}\r\n sortBy={devicesSort.sortBy}\r\n sortDirection={devicesSort.sortDirection}\r\n onRowClick={() => {}}\r\n onLoadMore={() => {}}\r\n columns={columns}\r\n selectAll={selectAll}\r\n allSelected={allSelected}\r\n />\r\n >\r\n )\r\n } else {\r\n return <>>\r\n }\r\n }\r\n\r\n const handleAvailableVersions = (index) => {\r\n return filteredAvailableVersions[index]\r\n }\r\n\r\n const renderVersionsTable = () => {\r\n if (!availableVersions !== undefined && availableVersions.length > 0) {\r\n const columns = [\r\n {\r\n columnWidth: 50,\r\n label: ResourceLang.available_versions,\r\n dataKey: DEVICE_KEYS_ENUM.CURRENT_VERSION,\r\n disableSort: false,\r\n },\r\n {\r\n columnWidth: 75,\r\n label: ResourceLang.creation_date,\r\n dataKey: DEVICE_KEYS_ENUM.UPDATE_REQUEST_DATE_VERSION,\r\n disableSort: false,\r\n },\r\n ]\r\n\r\n const handleSort = (event) => {\r\n setVersionsSort({\r\n sortBy: event.sortBy,\r\n sortDirection: event.sortDirection,\r\n })\r\n }\r\n\r\n const tableItems = getTableItems(filteredAvailableVersions, versionsSort)\r\n\r\n return (\r\n <>\r\n \r\n handleAvailableVersions(index)}\r\n sort={handleSort}\r\n sortBy={versionsSort.sortBy}\r\n sortDirection={versionsSort.sortDirection}\r\n columns={columns}\r\n />\r\n >\r\n )\r\n } else {\r\n return <>>\r\n }\r\n }\r\n\r\n return (\r\n \r\n \r\n {isLoading === false ? renderDevicesTable() : }\r\n \r\n \r\n {isLoading === false ? renderVersionsTable() : }\r\n \r\n \r\n )\r\n}\r\n\r\nSelectDevices.propTypes = {\r\n devices: PropTypes.array.isRequired,\r\n selectedDevices: PropTypes.array.isRequired,\r\n availableVersions: PropTypes.array.isRequired,\r\n filteredAvailableVersions: PropTypes.array.isRequired,\r\n handleSelection: PropTypes.func.isRequired,\r\n isLoading: PropTypes.bool,\r\n currentVersions: PropTypes.array,\r\n updateVersions: PropTypes.array,\r\n handleFilters: PropTypes.func,\r\n}\r\n\r\nexport default withRouter(SelectDevices)\r\n","import React, { useEffect } from 'react'\r\nimport Grid from '@material-ui/core/Grid'\r\nimport { withRouter } from 'react-router'\r\nimport Button from '@material-ui/core/Button'\r\nimport ResourceLang from '../../resources/Language'\r\nimport DialogStepper from '../stepper/DialogStepper'\r\nimport { FirmwareAPI } from '../../utils/APIRequester'\r\nimport CircularLoading from '../loadings/CircularLoading'\r\nimport SelectVersions from './SelectVersions'\r\nimport UpdateReview from './UpdateReview'\r\nimport SelectDevices from './SelectDevices'\r\nimport PropTypes from 'prop-types'\r\nimport { DEVICE_KEYS_ENUM } from '../../utils/Enums'\r\nimport { getLocalDateTimeString } from '../../utils/DateServices'\r\n\r\nconst SELECT_DEVICES_STEP = 0\r\nconst SELECT_VERSION_STEP = 1\r\nconst REVIEW_STEP = 2\r\n\r\nfunction getSteps() {\r\n return [\r\n ResourceLang.device_to_be_upgraded,\r\n ResourceLang.version_choose,\r\n ResourceLang.review_and_confirmation,\r\n ]\r\n}\r\n\r\nconst fwFilenameToVersion = (microController, filename) => {\r\n let versionName = filename.substr(0, filename.indexOf('.'))\r\n\r\n try {\r\n if (microController.toUpperCase() === 'COM' && versionName.length >= 3) {\r\n versionName = parseInt(versionName.substr(0, 3))\r\n } else if (\r\n microController.toUpperCase() === 'MEA' &&\r\n versionName.length >= 6\r\n ) {\r\n versionName = parseInt(versionName.substr(3, 3))\r\n }\r\n } catch (ex) {\r\n console.error(ex.message)\r\n return ResourceLang.invalid_fw_version\r\n }\r\n\r\n if (Number.isNaN(versionName)) {\r\n return ResourceLang.invalid_fw_version\r\n }\r\n\r\n return versionName\r\n}\r\n\r\nconst UpdateFirmwarePanel = ({\r\n match,\r\n deviceTypeName,\r\n deviceVersion,\r\n microController,\r\n closePanel,\r\n}) => {\r\n const [state, setState] = React.useState({\r\n devices: [],\r\n fullDevices: [],\r\n activeStep: 0,\r\n disableNext: true,\r\n disableBack: true,\r\n error: false,\r\n isLoading: true,\r\n devicesIsLoading: true,\r\n updateRequestVersion: undefined,\r\n selectedDevices: [],\r\n availableVersions: [],\r\n filteredAvailableVersions: [],\r\n filterCurrentVersion: null,\r\n filterUpdateVersion: null,\r\n currentVersions: [],\r\n updateVersions: [],\r\n })\r\n\r\n const envID = match.params.envId\r\n const steps = getSteps()\r\n\r\n const closeWithError = React.useCallback(\r\n (message) => {\r\n closePanel('error', message)\r\n },\r\n [closePanel]\r\n )\r\n\r\n const prepareFirmwareVersions = React.useCallback(\r\n (rawVersions) => {\r\n const versions = rawVersions.map(function (curVersion) {\r\n var version = {}\r\n\r\n version[DEVICE_KEYS_ENUM.UPDATE_REQUEST_DATE_VERSION] =\r\n getLocalDateTimeString(curVersion.creation_date)\r\n version[DEVICE_KEYS_ENUM.CURRENT_VERSION] = fwFilenameToVersion(\r\n microController,\r\n curVersion.filename\r\n )\r\n\r\n return version\r\n })\r\n\r\n if (versions.length === 0) {\r\n closeWithError(ResourceLang.no_versions)\r\n return undefined\r\n }\r\n\r\n return versions\r\n },\r\n [closeWithError, microController]\r\n )\r\n\r\n const prepareDevices = React.useCallback(\r\n (rawDevices) => {\r\n const devices = rawDevices.map(function (curDevice) {\r\n var device = {}\r\n device[DEVICE_KEYS_ENUM.DEVICE_ID] = curDevice.device_id\r\n device[DEVICE_KEYS_ENUM.SERIAL_NUMBER] = curDevice.serial_number\r\n\r\n var curFirmware = curDevice.device_firmware.filter(function (\r\n curMicrocontroller\r\n ) {\r\n return curMicrocontroller.firmware_id === microController\r\n })\r\n\r\n device[DEVICE_KEYS_ENUM.CURRENT_VERSION] =\r\n curFirmware[0].current_firmware_version\r\n device[DEVICE_KEYS_ENUM.UPDATE_VERSION] =\r\n curFirmware[0].update_firmware_version\r\n device[DEVICE_KEYS_ENUM.UPDATE_REQUEST_DATE_VERSION] =\r\n curFirmware[0].update_request_date\r\n device[DEVICE_KEYS_ENUM.FIRMWARE_DOWNLOAD_ATEMPTS] =\r\n curFirmware[0].firmware_download_atempts\r\n device[DEVICE_KEYS_ENUM.FIRMWARE_ID] = curFirmware[0].firmware_id\r\n\r\n return device\r\n })\r\n\r\n if (devices.length === 0) {\r\n closeWithError(ResourceLang.no_devices)\r\n return undefined\r\n }\r\n\r\n return devices\r\n },\r\n [closeWithError, microController]\r\n )\r\n\r\n const getCurrentVersions = () => {\r\n var currentVersions = []\r\n var devices = state.fullDevices\r\n\r\n if (\r\n state.filterUpdateVersion &&\r\n state.filterUpdateVersion !== null &&\r\n state.filterUpdateVersion.length > 0 &&\r\n state.filterUpdateVersion[0].value\r\n ) {\r\n devices = devices.filter(function (f) {\r\n return f.update_firmware_version === state.filterUpdateVersion[0].value\r\n })\r\n }\r\n\r\n devices.forEach(function (device) {\r\n var curr = currentVersions.findIndex(\r\n (x) => x.name == device.current_firmware_version\r\n )\r\n if (curr <= -1) {\r\n currentVersions.push({\r\n name: device.current_firmware_version,\r\n value: device.current_firmware_version,\r\n })\r\n }\r\n })\r\n return versionsSort(currentVersions)\r\n }\r\n\r\n const getUpdateVersions = () => {\r\n var updateVersions = []\r\n var devices = state.fullDevices\r\n\r\n if (\r\n state.filterCurrentVersion &&\r\n state.filterCurrentVersion !== null &&\r\n state.filterCurrentVersion.length > 0 &&\r\n state.filterCurrentVersion[0].value\r\n ) {\r\n devices = devices.filter(function (f) {\r\n return (\r\n f.current_firmware_version === state.filterCurrentVersion[0].value\r\n )\r\n })\r\n }\r\n\r\n devices.forEach(function (device) {\r\n var curr = updateVersions.findIndex(\r\n (x) => x.name == device.update_firmware_version\r\n )\r\n if (curr <= -1) {\r\n updateVersions.push({\r\n name: device.update_firmware_version,\r\n value: device.update_firmware_version,\r\n })\r\n }\r\n })\r\n return versionsSort(updateVersions)\r\n }\r\n\r\n const versionsSort = (versions) => {\r\n return versions.sort(function (a, b) {\r\n if (a.name < b.name) {\r\n return -1\r\n }\r\n if (a.name > b.name) {\r\n return 1\r\n }\r\n return 0\r\n })\r\n }\r\n\r\n const handleFilters = (filters) => {\r\n filters.forEach((filter) => {\r\n if (\r\n filter.key === 'current_version' &&\r\n filter.value !== state.filterCurrentVersion\r\n ) {\r\n setState((prevState) => ({\r\n ...prevState,\r\n filterCurrentVersion: filter.value,\r\n }))\r\n }\r\n\r\n if (\r\n filter.key === 'update_version' &&\r\n filter.value !== state.filterUpdateVersion\r\n ) {\r\n setState((prevState) => ({\r\n ...prevState,\r\n filterUpdateVersion: filter.value,\r\n }))\r\n }\r\n })\r\n }\r\n\r\n useEffect(() => {\r\n if (\r\n state.filterCurrentVersion &&\r\n state.filterCurrentVersion !== null &&\r\n state.filterCurrentVersion.length > 0 &&\r\n state.filterCurrentVersion[0].value\r\n ) {\r\n var devices = state.devices.filter(function (f) {\r\n return (\r\n f.current_firmware_version === state.filterCurrentVersion[0].value\r\n )\r\n })\r\n setState((prevState) => ({ ...prevState, devices: devices }))\r\n } else if (\r\n state.filterCurrentVersion &&\r\n state.filterCurrentVersion !== null &&\r\n state.filterCurrentVersion.length === 0\r\n ) {\r\n if (\r\n state.filterUpdateVersion &&\r\n state.filterUpdateVersion !== null &&\r\n state.filterUpdateVersion.length > 0 &&\r\n state.filterUpdateVersion[0].value\r\n ) {\r\n var devices = state.fullDevices.filter(function (f) {\r\n return (\r\n f.update_firmware_version === state.filterUpdateVersion[0].value\r\n )\r\n })\r\n setState((prevState) => ({ ...prevState, devices: devices }))\r\n } else {\r\n setState((prevState) => ({ ...prevState, devices: state.fullDevices }))\r\n }\r\n }\r\n }, [state.filterCurrentVersion])\r\n\r\n useEffect(() => {\r\n if (\r\n state.filterUpdateVersion &&\r\n state.filterUpdateVersion !== null &&\r\n state.filterUpdateVersion.length > 0 &&\r\n state.filterUpdateVersion[0].value\r\n ) {\r\n var devices = state.devices.filter(function (f) {\r\n return f.update_firmware_version === state.filterUpdateVersion[0].value\r\n })\r\n setState((prevState) => ({ ...prevState, devices: devices }))\r\n } else if (\r\n state.filterUpdateVersion &&\r\n state.filterUpdateVersion !== null &&\r\n state.filterUpdateVersion.length === 0\r\n ) {\r\n if (\r\n state.filterCurrentVersion &&\r\n state.filterCurrentVersion !== null &&\r\n state.filterCurrentVersion.length > 0 &&\r\n state.filterCurrentVersion[0].value\r\n ) {\r\n var devices = state.fullDevices.filter(function (f) {\r\n return (\r\n f.current_firmware_version === state.filterCurrentVersion[0].value\r\n )\r\n })\r\n setState((prevState) => ({ ...prevState, devices: devices }))\r\n } else {\r\n setState((prevState) => ({\r\n ...prevState,\r\n devices: state.fullDevices,\r\n }))\r\n }\r\n }\r\n }, [state.filterUpdateVersion])\r\n\r\n const getAllData = React.useCallback(() => {\r\n setState((prevState) => ({\r\n ...prevState,\r\n devicesIsLoading: true,\r\n }))\r\n\r\n Promise.all([\r\n FirmwareAPI.getDevicesByFamily(\r\n envID,\r\n deviceTypeName,\r\n deviceVersion,\r\n microController\r\n ),\r\n FirmwareAPI.getAllVersions(\r\n envID,\r\n deviceTypeName,\r\n deviceVersion,\r\n microController\r\n ),\r\n ])\r\n .then((responses) => {\r\n var devices = []\r\n var versions = []\r\n if (responses[0] && Array.isArray(responses[0])) {\r\n devices = prepareDevices(responses[0])\r\n }\r\n if (responses[1] && Array.isArray(responses[1])) {\r\n versions = prepareFirmwareVersions(responses[1])\r\n }\r\n setState((prevState) => ({\r\n ...prevState,\r\n isLoading: false,\r\n devicesIsLoading: false,\r\n devices: devices,\r\n fullDevices: devices,\r\n availableVersions: versions,\r\n filteredAvailableVersions: versions,\r\n }))\r\n })\r\n .catch((error) => {\r\n setState((prevState) => ({\r\n ...prevState,\r\n isLoading: false,\r\n devicesIsLoading: false,\r\n }))\r\n closeWithError(ResourceLang.generic_error)\r\n })\r\n }, [\r\n prepareDevices,\r\n closeWithError,\r\n prepareFirmwareVersions,\r\n envID,\r\n deviceTypeName,\r\n deviceVersion,\r\n microController,\r\n ])\r\n\r\n useEffect(() => {\r\n const load = async () => {\r\n getAllData()\r\n }\r\n\r\n load()\r\n }, [getAllData])\r\n\r\n const updateDeviceFirmware = (selectedDevices) => {\r\n const devices = selectedDevices.map(function (curDevice) {\r\n curDevice[DEVICE_KEYS_ENUM.UPDATE_VERSION] = state.updateRequestVersion\r\n return curDevice\r\n })\r\n\r\n const formData = new FormData()\r\n formData.append('devices', JSON.stringify(devices))\r\n FirmwareAPI.updateDeviceFirmware(envID, formData)\r\n .then((response) => {\r\n setState((prevState) => ({\r\n ...prevState,\r\n selectedDevices: devices,\r\n }))\r\n })\r\n .catch((error) => {\r\n setState((prevState) => ({\r\n ...prevState,\r\n isLoading: false,\r\n }))\r\n closePanel('error', error)\r\n })\r\n }\r\n\r\n const handleNext = () => {\r\n if (state.activeStep === REVIEW_STEP) {\r\n updateDeviceFirmware(state.selectedDevices)\r\n setState((prevState) => ({\r\n ...prevState,\r\n activeStep: 0,\r\n }))\r\n\r\n closePanel('success', ResourceLang.update_with_success)\r\n } else if (state.activeStep === SELECT_VERSION_STEP) {\r\n setState((prevState) => ({\r\n ...prevState,\r\n activeStep: state.activeStep + 1,\r\n disableNext: false,\r\n }))\r\n } else {\r\n setState((prevState) => ({\r\n ...prevState,\r\n activeStep: state.activeStep + 1,\r\n disableBack: false,\r\n disableNext: true,\r\n }))\r\n }\r\n }\r\n\r\n const handleBack = () => {\r\n if (state.activeStep === SELECT_VERSION_STEP) {\r\n setState((prevState) => ({\r\n ...prevState,\r\n selectedDevices: [],\r\n filteredAvailableVersions: state.availableVersions,\r\n disableBack: true,\r\n disableNext: true,\r\n }))\r\n } else if (state.activeStep === REVIEW_STEP) {\r\n setState((prevState) => ({\r\n ...prevState,\r\n updateRequestVersion: undefined,\r\n disableNext: true,\r\n }))\r\n }\r\n setState((prevState) => ({\r\n ...prevState,\r\n activeStep: state.activeStep - 1,\r\n }))\r\n }\r\n\r\n const setUploadRequestVersion = (requestVersion) => {\r\n if (requestVersion !== undefined) {\r\n setState((prevState) => ({\r\n ...prevState,\r\n updateRequestVersion: requestVersion,\r\n disableNext: false,\r\n }))\r\n }\r\n }\r\n\r\n const getHigherFirmwareVersionsToUpdate = (devices) => {\r\n return devices.reduce(\r\n (maxVersion, curDevice) =>\r\n curDevice[DEVICE_KEYS_ENUM.CURRENT_VERSION] > maxVersion\r\n ? curDevice[DEVICE_KEYS_ENUM.CURRENT_VERSION]\r\n : maxVersion,\r\n devices[0][DEVICE_KEYS_ENUM.CURRENT_VERSION]\r\n )\r\n }\r\n\r\n const checkAvailableVersionsForDevice = (devices) => {\r\n var canClickNextButton = false\r\n var actualVersions = state.availableVersions\r\n var maxVersion = undefined\r\n if (devices.length > 0) {\r\n maxVersion = getHigherFirmwareVersionsToUpdate(devices)\r\n actualVersions = actualVersions.filter(\r\n (item) => Number(item.current_firmware_version) > Number(maxVersion)\r\n )\r\n\r\n if (actualVersions.length > 0) {\r\n canClickNextButton = true\r\n }\r\n setState((prevState) => ({\r\n ...prevState,\r\n selectedDevices: devices,\r\n filteredAvailableVersions: actualVersions,\r\n disableNext: !canClickNextButton,\r\n }))\r\n } else {\r\n setState((prevState) => ({\r\n ...prevState,\r\n selectedDevices: devices,\r\n filteredAvailableVersions: actualVersions,\r\n disableNext: true,\r\n }))\r\n }\r\n return canClickNextButton\r\n }\r\n\r\n const setDeviceSelected = (rowData, isChecked) => {\r\n var devices = state.selectedDevices\r\n\r\n if (isChecked === true) {\r\n devices.push(rowData)\r\n } else {\r\n devices = state.selectedDevices.filter(function (device) {\r\n return device.device_id !== rowData.device_id\r\n })\r\n }\r\n\r\n return devices\r\n }\r\n\r\n const handleSelection = (rowData, isChecked) => {\r\n if (rowData !== undefined) {\r\n const devices = setDeviceSelected(rowData, isChecked)\r\n checkAvailableVersionsForDevice(devices)\r\n }\r\n }\r\n\r\n const handleAllSelections = (rowData, isChecked) => {\r\n var devices = []\r\n\r\n if (isChecked === true) {\r\n devices = rowData\r\n }\r\n\r\n checkAvailableVersionsForDevice(devices)\r\n }\r\n\r\n const renderBody = () => {\r\n switch (state.activeStep) {\r\n case SELECT_DEVICES_STEP:\r\n return (\r\n \r\n )\r\n case SELECT_VERSION_STEP:\r\n return (\r\n \r\n )\r\n case REVIEW_STEP:\r\n return (\r\n \r\n )\r\n default:\r\n return <>>\r\n }\r\n }\r\n\r\n const renderContent = () => {\r\n return (\r\n \r\n \r\n {renderBody()}\r\n {state.isLoading === false ? <>> : }\r\n
\r\n )\r\n }\r\n\r\n const renderFooter = () => {\r\n return (\r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n )\r\n }\r\n\r\n return (\r\n \r\n \r\n {renderContent()}\r\n {renderFooter()}\r\n \r\n \r\n )\r\n}\r\n\r\nUpdateFirmwarePanel.propTypes = {\r\n match: PropTypes.object.isRequired,\r\n deviceTypeName: PropTypes.string.isRequired,\r\n deviceVersion: PropTypes.string.isRequired,\r\n microController: PropTypes.string.isRequired,\r\n closePanel: PropTypes.func.isRequired,\r\n}\r\n\r\nexport default withRouter(UpdateFirmwarePanel)\r\n","import React, { useState, useEffect } from 'react'\r\nimport { withRouter } from 'react-router'\r\nimport PageHeader from '../components/headers/PageHeader'\r\nimport { Typography, Divider, Chip } from '@material-ui/core'\r\nimport DeviceMenuItems from '../components/MenuItems/MenuItems'\r\nimport { makeStyles } from '@material-ui/core/styles'\r\nimport ResourceLang from '../resources/Language'\r\nimport { FirmwareAPI } from '../utils/APIRequester'\r\nimport MessageSnackbar from '../components/notifications/MessageSnackbar'\r\nimport ExtensionIcon from '@material-ui/icons/Extension'\r\nimport MemoryIcon from '@material-ui/icons/Memory'\r\nimport DevicesOtherIcon from '@material-ui/icons/DevicesOther'\r\nimport PageLoading from '../components/loadings/PageLoading'\r\nimport UpdateFirmwarePanel from '../components/panels/UpdateFirmwarePanel'\r\nimport Grid from '@material-ui/core/Grid'\r\n// import FilterListIcon from '@material-ui/icons/FilterList'\r\n// import FilterPopover from '../components/filters/FilterPopover'\r\n// import Tooltip from '@material-ui/core/Tooltip'\r\n// import { IconButton } from '@material-ui/core'\r\nimport {\r\n translateObjectToMenu,\r\n findElementById,\r\n} from '../utils/FirmwareServices'\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n root: {\r\n display: 'flex',\r\n marginTop: 1,\r\n height: '100vh',\r\n },\r\n body_info: {\r\n paddingLeft: theme.spacing(4),\r\n paddingRight: theme.spacing(2),\r\n },\r\n treeView: {\r\n backgroundColor: '#2C4153',\r\n height: '100vh',\r\n overflow: 'auto',\r\n },\r\n header: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n },\r\n filters: {\r\n right: 0,\r\n },\r\n firmware_panel: {\r\n height: 400,\r\n paddingLeft: theme.spacing(4),\r\n paddingRight: theme.spacing(2),\r\n marginTop: theme.spacing(2),\r\n },\r\n content: {\r\n flexGrow: 1,\r\n padding: theme.spacing(2),\r\n },\r\n chip: {\r\n marginRight: 5,\r\n },\r\n}))\r\n\r\nconst UpdateFirmwarePage = ({ match, location, history, ...props }) => {\r\n const classes = useStyles()\r\n const [MenuItems, setMenuItems] = useState(undefined)\r\n const [isDisableUpdateFirmwarePanel, setDisableUpdateFirmwarePanel] =\r\n useState(true)\r\n const [snackbar, setSnackbar] = useState({\r\n open: false,\r\n variant: 'error',\r\n message: '',\r\n })\r\n const [micro_controller, setMicro] = useState(undefined)\r\n const [device_type_name, setDevice] = useState(undefined)\r\n const [device_version, setVersion] = useState(undefined)\r\n // const [currentVersions, setCurrentVersions] = useState(null)\r\n // const [updateVersions, setUpdateVersions] = useState(null)\r\n\r\n // const [anchorEl, updateAnchorEl] = useState(null)\r\n // const [filters, setFilters] = useState([\r\n // {\r\n // key: 'current_version',\r\n // label: ResourceLang.current_version,\r\n // type: 'select',\r\n // options: currentVersions,\r\n // },\r\n // {\r\n // key: 'update_version',\r\n // label: ResourceLang.update_version,\r\n // type: 'select',\r\n // options: updateVersions,\r\n // },\r\n // ])\r\n\r\n const envId = match.params.envId\r\n\r\n useEffect(() => {\r\n if (!MenuItems) {\r\n FirmwareAPI.getStructure(envId).then((response) => {\r\n translateObjectToMenu(response)\r\n setMenuItems(response)\r\n })\r\n }\r\n }, [envId, MenuItems])\r\n\r\n // const renderFilterButton = () => {\r\n // return (\r\n // <>\r\n // \r\n // updateAnchorEl(event.currentTarget)}\r\n // >\r\n // \r\n // \r\n // \r\n // \r\n // >\r\n // )\r\n // }\r\n\r\n const renderDeviceTypeIcon = () => {\r\n if (device_type_name) {\r\n return (\r\n }\r\n label={device_type_name}\r\n />\r\n )\r\n }\r\n\r\n return null\r\n }\r\n\r\n const renderExtensionIcon = () => {\r\n if (device_version) {\r\n return (\r\n }\r\n label={device_version}\r\n />\r\n )\r\n }\r\n\r\n return null\r\n }\r\n\r\n const renderMemoryIcon = () => {\r\n if (micro_controller) {\r\n return (\r\n }\r\n label={micro_controller}\r\n />\r\n )\r\n }\r\n\r\n return null\r\n }\r\n\r\n const renderUpdateFirmwareButton = () => {\r\n if (!micro_controller || !device_type_name || !device_version) {\r\n return null\r\n }\r\n }\r\n\r\n const closeUpdateFirmware = (successFromPanel, messageFromPanel) => {\r\n setDisableUpdateFirmwarePanel(true)\r\n setSnackbar((prevState) => ({\r\n ...prevState,\r\n open: true,\r\n message: messageFromPanel,\r\n variant: successFromPanel,\r\n }))\r\n }\r\n\r\n const renderFirmwarePanel = () => {\r\n return (\r\n <>\r\n {!isDisableUpdateFirmwarePanel ? (\r\n \r\n ) : null}\r\n >\r\n )\r\n }\r\n\r\n const setDeviceChoosen = (ItemSelected) => {\r\n if (ItemSelected) {\r\n const deviceSelected = findElementById(MenuItems, ItemSelected)\r\n if (deviceSelected) {\r\n setDisableUpdateFirmwarePanel(false)\r\n setDevice(deviceSelected.deviceType)\r\n setVersion(deviceSelected.version)\r\n setMicro(deviceSelected.micro)\r\n }\r\n }\r\n }\r\n\r\n const renderHeader = () => {\r\n return (\r\n }\r\n >\r\n )\r\n }\r\n\r\n const handleSnackbarClose = () => {\r\n setSnackbar((prevState) => ({ ...prevState, open: false }))\r\n }\r\n\r\n const renderSnackbar = () => {\r\n return (\r\n \r\n )\r\n }\r\n\r\n return (\r\n \r\n
\r\n \r\n \r\n \r\n
\r\n {renderHeader()}\r\n
\r\n \r\n
\r\n {ResourceLang.micro_controller_info}\r\n \r\n {/* TODO: Do not have inline styles */}\r\n {/*
*/}\r\n
{ResourceLang.micro_controller} \r\n {renderDeviceTypeIcon()}\r\n {renderExtensionIcon()}\r\n {renderMemoryIcon()}\r\n {renderUpdateFirmwareButton()}\r\n {/*
\r\n {renderFilterButton()}\r\n
\r\n
*/}\r\n
\r\n {renderFirmwarePanel()}
\r\n {renderSnackbar()}\r\n \r\n {!MenuItems ?
: null}\r\n
\r\n )\r\n}\r\n\r\nexport default withRouter(UpdateFirmwarePage)\r\n","import React from 'react'\r\nimport PropTypes from 'prop-types'\r\nimport ResourceLang from '../../resources/Language'\r\nimport {\r\n AutoSizer,\r\n Column,\r\n Table,\r\n SortIndicator,\r\n defaultTableRowRenderer,\r\n} from 'react-virtualized'\r\nimport { Link } from 'react-router-dom'\r\nimport {\r\n ContextMenu,\r\n ContextMenuTrigger,\r\n connectMenu,\r\n hideMenu,\r\n} from 'react-contextmenu'\r\nimport { withStyles } from '@material-ui/core/styles'\r\nimport clsx from 'clsx'\r\nimport {\r\n TableRow,\r\n TableCell,\r\n Tooltip,\r\n Typography,\r\n IconButton,\r\n Paper,\r\n MenuList,\r\n MenuItem,\r\n TablePagination,\r\n Input,\r\n} from '@material-ui/core'\r\nimport ExpandLessIcon from '@material-ui/icons/ExpandLess'\r\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore'\r\n\r\nconst styles = (theme) => ({\r\n flexContainer: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n boxSizing: 'border-box',\r\n },\r\n table: {\r\n // temporary right-to-left patch, waiting for\r\n // https://github.com/bvaughn/react-virtualized/issues/454\r\n '& .ReactVirtualized__Table__headerRow': {\r\n flip: false,\r\n paddingRight: theme.direction === 'rtl' ? '0px !important' : undefined,\r\n },\r\n },\r\n tableRow: {\r\n cursor: 'pointer',\r\n },\r\n input: {\r\n width: '2rem',\r\n },\r\n caption: {\r\n fontSize: '0.875rem',\r\n fontFamily: 'Roboto',\r\n },\r\n tableRowHover: {\r\n '&:hover': {\r\n backgroundColor: theme.palette.grey[200],\r\n },\r\n },\r\n tableCell: {\r\n flex: 1,\r\n },\r\n tableFooter: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n },\r\n footerlabel: {\r\n marginLeft: theme.spacing(3),\r\n },\r\n firstCell: {\r\n marginLeft: theme.spacing(1),\r\n },\r\n noClick: {\r\n cursor: 'initial',\r\n },\r\n})\r\n\r\nconst MENU_TYPE = 'DYNAMIC'\r\nconst collectTriggerProps = (props) => props\r\n\r\nconst DynamicMenu = ({ id, contextMenuOptions, trigger }) => {\r\n const { data } = trigger || {}\r\n\r\n return (\r\n \r\n \r\n \r\n {!trigger\r\n ? null\r\n : contextMenuOptions.map(({ label, onClick }, index) => {\r\n const onMenuItemClick = (e) => {\r\n hideMenu()\r\n onClick(e, data)\r\n }\r\n\r\n return (\r\n \r\n )\r\n })}\r\n \r\n \r\n \r\n )\r\n}\r\n\r\nDynamicMenu.propTypes = {\r\n id: PropTypes.string.isRequired,\r\n contextMenuOptions: PropTypes.arrayOf(\r\n PropTypes.shape({\r\n label: PropTypes.string.isRequired,\r\n onClick: PropTypes.func.isRequired,\r\n })\r\n ).isRequired,\r\n trigger: PropTypes.shape({\r\n data: PropTypes.object.isRequired,\r\n }),\r\n}\r\n\r\nconst ConnectedMenu = connectMenu(MENU_TYPE)(DynamicMenu)\r\n\r\nclass MuiPaginatedVirtualizedTable extends React.PureComponent {\r\n static defaultProps = {\r\n disableHeader: false,\r\n headerHeight: 48 * 2,\r\n rowHeight: 48,\r\n detailRowHeight: 48 * 2,\r\n }\r\n\r\n constructor(props) {\r\n super(props)\r\n\r\n this.state = {\r\n selectedIndex: -1,\r\n }\r\n this.tableRef = React.createRef()\r\n this._handleExpandClick = this._handleExpandClick.bind(this)\r\n }\r\n\r\n cellRenderer = ({ cellData, columnIndex, rowIndex, rowData }) => {\r\n const { columns, rowHeight, classes } = this.props\r\n const column = columns[columnIndex]\r\n let value = cellData\r\n\r\n if (column.dataKey === '#') {\r\n value = {rowIndex + 1}
\r\n } else if (column.render) {\r\n value = column.render(rowData)\r\n } else if (column.date === true) {\r\n const date = new Date(cellData)\r\n value = `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`\r\n } else if (column.numeric === true) {\r\n const decimalPlaces = column.decimalPlaces || 2\r\n if (cellData && !isNaN(cellData)) {\r\n value = Number(\r\n Math.round(value + ('e' + decimalPlaces)) + ('e-' + decimalPlaces)\r\n ).toFixed(decimalPlaces)\r\n } else value = '-'\r\n }\r\n\r\n if (column.link) {\r\n value = (\r\n event.stopPropagation()}\r\n to={column.link(rowData)}\r\n >\r\n {value}\r\n \r\n )\r\n }\r\n\r\n return (\r\n \r\n {value}\r\n \r\n )\r\n }\r\n\r\n headerRenderer = ({ label, columnIndex, dataKey, sortBy, sortDirection }) => {\r\n const { headerHeight, columns, classes } = this.props\r\n const column = columns[columnIndex]\r\n\r\n let content = ''\r\n if (columnIndex === 0) {\r\n content = (\r\n \r\n {label}\r\n {sortBy === dataKey && (\r\n \r\n )}\r\n
\r\n )\r\n } else {\r\n content = (\r\n <>\r\n {label}\r\n {sortBy === dataKey && (\r\n \r\n )}\r\n >\r\n )\r\n }\r\n\r\n return (\r\n \r\n {content}\r\n \r\n )\r\n }\r\n\r\n rowRendererDetailed = (params) => {\r\n const { classes, rowHeight, detailRowHeight, detailRowRenderer } =\r\n this.props\r\n const { index, style, className, key } = params\r\n\r\n if (index === this.state.selectedIndex) {\r\n return (\r\n \r\n {defaultTableRowRenderer({\r\n ...params,\r\n style: { width: '100%', height: rowHeight },\r\n })}\r\n
{\r\n let target = event.target\r\n\r\n while (target.getAttribute('role') !== 'row') {\r\n target = target.parentNode\r\n }\r\n\r\n target.previousElementSibling.click()\r\n }}\r\n >\r\n {detailRowRenderer(params, detailRowHeight)}\r\n \r\n
\r\n )\r\n } else return defaultTableRowRenderer(params)\r\n }\r\n\r\n renderDetailButton = (width) => {\r\n const { classes, headerHeight, rowHeight } = this.props\r\n const key = 'detailButton'\r\n const disableSort = true\r\n\r\n return (\r\n {\r\n return (\r\n \r\n )\r\n }}\r\n cellRenderer={({ cellData, columnIndex, rowIndex, rowData }) => {\r\n const isSelected = this.state.selectedIndex === rowIndex\r\n const expandIcon = isSelected ? (\r\n \r\n ) : (\r\n \r\n )\r\n const label = isSelected\r\n ? ResourceLang.HideDetails\r\n : ResourceLang.ShowDetails\r\n\r\n return (\r\n \r\n \r\n {\r\n event.stopPropagation()\r\n this._handleExpandClick(rowIndex)\r\n }}\r\n >\r\n {expandIcon}\r\n \r\n \r\n \r\n )\r\n }}\r\n />\r\n )\r\n }\r\n\r\n getRowClassName = ({ index }) => {\r\n const { classes } = this.props\r\n return index !== -1\r\n ? clsx(classes.tableRow, classes.flexContainer, classes.tableRowHover)\r\n : clsx(classes.tableRow, classes.flexContainer)\r\n }\r\n\r\n getHeaderRowClassName = (disableSort) => {\r\n const { classes } = this.props\r\n return clsx([\r\n classes.tableCell,\r\n classes.flexContainer,\r\n disableSort === true ? classes.noClick : classes.tableRow,\r\n ])\r\n }\r\n\r\n getRowHeight = ({ index }) => {\r\n return index === this.state.selectedIndex\r\n ? this.props.detailRowHeight + this.props.rowHeight\r\n : this.props.rowHeight\r\n }\r\n\r\n getColumnAlign = (column) => {\r\n if (column.align) return column.align\r\n\r\n return column.numeric ? 'right' : 'left'\r\n }\r\n\r\n _handleExpandClick(rowIndex) {\r\n const newIndex = this.state.selectedIndex === rowIndex ? -1 : rowIndex\r\n this.setState({ ...this.state, selectedIndex: newIndex })\r\n\r\n if (this.tableRef) {\r\n this.tableRef.recomputeRowHeights()\r\n }\r\n }\r\n\r\n render() {\r\n const {\r\n pagination,\r\n classes,\r\n columns,\r\n rowHeight,\r\n headerHeight,\r\n disableHeader,\r\n detailRowRenderer,\r\n contextMenuOptions,\r\n onGoToPage,\r\n pageError,\r\n labelPage,\r\n ...tableProps\r\n } = this.props\r\n const footerHeight = headerHeight\r\n\r\n const rowContentRenderer = detailRowRenderer\r\n ? this.rowRendererDetailed\r\n : defaultTableRowRenderer\r\n const rowRenderer = !contextMenuOptions\r\n ? rowContentRenderer\r\n : (params) => {\r\n const { style, key, rowData } = params\r\n\r\n return (\r\n \r\n )\r\n }\r\n\r\n return (\r\n <>\r\n \r\n {({ height, width }) => (\r\n <>\r\n \r\n {columns.map(({ dataKey, columnWidth, ...other }, index) => {\r\n const cellWidth = columnWidth * width\r\n return (\r\n \r\n this.headerRenderer({\r\n ...headerProps,\r\n columnIndex: index,\r\n })\r\n }\r\n className={classes.flexContainer}\r\n cellRenderer={this.cellRenderer}\r\n dataKey={dataKey}\r\n width={cellWidth}\r\n {...other}\r\n />\r\n )\r\n })}\r\n {detailRowRenderer ? this.renderDetailButton(width) : null}\r\n
\r\n \r\n
\r\n Page:\r\n
\r\n
\r\n
\r\n
\r\n >\r\n )}\r\n \r\n {contextMenuOptions ? (\r\n \r\n ) : null}\r\n >\r\n )\r\n }\r\n}\r\n\r\nMuiPaginatedVirtualizedTable.propTypes = {\r\n classes: PropTypes.object.isRequired,\r\n columns: PropTypes.arrayOf(\r\n PropTypes.shape({\r\n dataKey: PropTypes.string.isRequired,\r\n label: PropTypes.string,\r\n numeric: PropTypes.bool,\r\n date: PropTypes.bool,\r\n align: PropTypes.oneOf(['left', 'center', 'right']),\r\n columnWidth: PropTypes.number.isRequired,\r\n render: PropTypes.func,\r\n link: PropTypes.func,\r\n })\r\n ).isRequired,\r\n pagination: PropTypes.object,\r\n disableHeader: PropTypes.bool,\r\n headerHeight: PropTypes.number,\r\n onRowClick: PropTypes.func,\r\n rowHeight: PropTypes.number,\r\n detailRowRenderer: PropTypes.func,\r\n detailRowHeight: PropTypes.number,\r\n contextMenuOptions: PropTypes.arrayOf(\r\n PropTypes.shape({\r\n label: PropTypes.string.isRequired,\r\n onClick: PropTypes.func.isRequired,\r\n })\r\n ),\r\n onGoToPage: PropTypes.func,\r\n pageError: PropTypes.bool,\r\n labelPage: PropTypes.string,\r\n}\r\n\r\nexport default withStyles(styles)(MuiPaginatedVirtualizedTable)\r\n","import React from 'react';\r\nimport SvgIcon from '@material-ui/core/SvgIcon';\r\n\r\n\r\nconst ExcelIcon = props => {\r\n\r\n return(\r\n \r\n \r\n \r\n )\r\n}\r\n\r\nexport default ExcelIcon;","import React from 'react';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport Button from '@material-ui/core/Button';\r\n\r\n\r\nconst useStyles = makeStyles(theme => ({\r\n blueButton: {\r\n margin: theme.spacing(1),\r\n backgroundColor: '#2C4153',\r\n border: 'solid 1px #F1C419',\r\n color: 'rgb(241,198,25)',\r\n fontSize: 12,\r\n fontWeight: 'bold',\r\n '&:hover':{\r\n backgroundColor: 'rgb(241,198,25)',\r\n color: '#2C4153',\r\n }\r\n },\r\n}));\r\n\r\nexport const ButtonBlue = props =>{\r\n const {size} = props || 'medium';\r\n const classes = useStyles();\r\n\r\n return(\r\n \r\n )\r\n}","import React, { useState, useEffect } from 'react'\r\nimport { withRouter } from 'react-router'\r\nimport Toolbar from '@material-ui/core/Toolbar'\r\nimport { makeStyles } from '@material-ui/core/styles'\r\nimport ResourceLang from '../../resources/Language'\r\nimport MemoryIcon from '@material-ui/icons/Memory'\r\nimport { FirmwareAPI } from '../../utils/APIRequester'\r\nimport Tooltip from '@material-ui/core/Tooltip'\r\nimport PageLoading from '../../components/loadings/PageLoading'\r\nimport { handleBodyResize, compareValues } from '../../utils/BrowserServices'\r\nimport { SortDirection } from 'react-virtualized'\r\nimport { Paper, Grid, IconButton, Chip, Typography } from '@material-ui/core'\r\nimport MuiPaginatedVirtualizedTable from '../../components/tables/MuiPaginatedVirtualizedTable'\r\nimport FilterListIcon from '@material-ui/icons/FilterList'\r\nimport FilterPopover from '../../components/filters/FilterPopover'\r\nimport { DEVICE_VERSION_VALUES_ENUM } from '../../utils/Enums'\r\nimport ExcelIcon from '../../components/icons/ExcelIcon'\r\nimport { ButtonBlue } from '../../components/buttons/RectanguleButton'\r\nimport { useDebounce } from 'use-debounce'\r\nimport { isPoleMountedOrDtvi4G } from '../../utils/DeviceServices';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n root: {\r\n width: '100%',\r\n height: '100%',\r\n },\r\n paper: {\r\n width: '100%',\r\n height: '100%',\r\n overflow: 'auto',\r\n },\r\n headerTitle: {\r\n flexGrow: 1,\r\n marginLeft: theme.spacing(2),\r\n },\r\n tableContainer: {\r\n marginLeft: theme.spacing(1),\r\n marginRight: theme.spacing(1),\r\n },\r\n toolbar: {\r\n marginLeft: theme.spacing(2),\r\n marginRight: theme.spacing(1),\r\n },\r\n chip: {\r\n margin: theme.spacing(0.5),\r\n },\r\n}))\r\n\r\nconst ListDevicePage = ({ match, location, history, ...props }) => {\r\n const classes = useStyles()\r\n const DEVICE_VERSION_POSITION = 11\r\n const [anchorEl, updateAnchorEl] = useState(null)\r\n const [state, setState] = useState({\r\n selected: undefined,\r\n deviceItems: undefined,\r\n currentVersions: undefined,\r\n })\r\n\r\n const [pageError, setPageError] = useState(false)\r\n const [pageSize, setPageSize] = useState(50)\r\n const [totalRows, setTotalRows] = useState(0)\r\n const [currentPage, setCurrentPage] = useState(0)\r\n const [debouncedCurrentPage] = useDebounce(currentPage, 500)\r\n const [firmwareIds, setFirmwareIds] = useState(null)\r\n const [currentVersions, setCurrentVersions] = useState(null)\r\n const [selectedFirmware, setSelectedFirmware] = useState(null)\r\n const [selectedVersion, setSelectedVersion] = useState(null)\r\n const [selectedSerial, setSelectedSerial] = useState(null)\r\n const [debouncedselectedSerial] = useDebounce(selectedSerial, 500)\r\n const [isLoading, setIsLoading] = useState(true)\r\n\r\n const [filters, setFilters] = useState([\r\n {\r\n key: 'serial_number',\r\n label: ResourceLang.serial_number,\r\n type: 'text',\r\n },\r\n ])\r\n\r\n const [sort, setSort] = useState({\r\n sortBy: 'created',\r\n sortDirection: SortDirection.ASC,\r\n })\r\n\r\n const envId = match.params.envId\r\n\r\n useEffect(() => {\r\n function formatVersion(deviceItem) {\r\n deviceItem.formattedMSP = allEqual(deviceItem.MSP, '0')\r\n ? '0'\r\n : deviceItem.MSP.replace(/\\b0+/g, '')\r\n\r\n deviceItem.formattedPIC = allEqual(deviceItem.PIC, '0')\r\n ? '0'\r\n : deviceItem.PIC.replace(/\\b0+/g, '')\r\n\r\n deviceItem.formattedMEA = allEqual(deviceItem.MEA, '0')\r\n ? '0'\r\n : deviceItem.MEA.replace(/\\b0+/g, '')\r\n\r\n deviceItem.formattedCOM = allEqual(deviceItem.COM, '0')\r\n ? '0'\r\n : deviceItem.COM.replace(/\\b0+/g, '')\r\n }\r\n\r\n function setFirmwareData(deviceItem) {\r\n deviceItem.MSP = 'N/A'\r\n deviceItem.PIC = 'N/A'\r\n deviceItem.MEA = 'N/A'\r\n deviceItem.COM = 'N/A'\r\n\r\n if (deviceItem.device_firmware != null) {\r\n deviceItem.device_firmware.forEach((firmware) => {\r\n switch (firmware.firmware_id) {\r\n case 'MSP':\r\n deviceItem.MSP = firmware.current_firmware_version\r\n break\r\n case 'PIC':\r\n deviceItem.PIC = firmware.current_firmware_version\r\n break\r\n case 'DTE':\r\n deviceItem.PIC = firmware.current_firmware_version\r\n break\r\n case 'MEA':\r\n deviceItem.MEA = firmware.current_firmware_version\r\n break\r\n case 'COM':\r\n deviceItem.COM = firmware.current_firmware_version\r\n break\r\n default:\r\n break\r\n }\r\n })\r\n }\r\n\r\n formatVersion(deviceItem)\r\n }\r\n\r\n function setFamilyVersion(deviceItem) {\r\n if (deviceItem.serial_number.length > DEVICE_VERSION_POSITION) {\r\n let version = parseInt(\r\n deviceItem.serial_number[DEVICE_VERSION_POSITION]\r\n )\r\n let typeDescription = deviceItem.device_type_description;\r\n\r\n if (isNaN(version)) {\r\n deviceItem.family_version = ResourceLang.not_applicable\r\n } else {\r\n deviceItem.family_version = translateVersion(typeDescription, version)\r\n }\r\n } else {\r\n deviceItem.family_version = ResourceLang.not_applicable\r\n }\r\n }\r\n\r\n function setSIMCardData(deviceItem) {\r\n if (deviceItem.interface_gprs.iccid == null) {\r\n deviceItem.iccid = ''\r\n } else {\r\n deviceItem.iccid = deviceItem.interface_gprs.iccid\r\n }\r\n\r\n if (deviceItem.interface_gprs.current_ip == null) {\r\n deviceItem.current_ip = ''\r\n } else {\r\n deviceItem.current_ip = deviceItem.interface_gprs.current_ip\r\n }\r\n }\r\n\r\n if (state.deviceItems) {\r\n state.deviceItems.forEach((device) => {\r\n setSIMCardData(device)\r\n setFamilyVersion(device)\r\n setFirmwareData(device)\r\n })\r\n }\r\n }, [state.deviceItems])\r\n\r\n useEffect(() => {\r\n function setFirmwareOptionIds(firmware_ids) {\r\n let ids = []\r\n firmware_ids.forEach((firmware_id) => {\r\n let id = {\r\n name: firmware_id,\r\n value: firmware_id,\r\n }\r\n if (uniqueAdd(ids, id)) ids.push(id)\r\n })\r\n\r\n setFirmwareIds(stringArraySort(ids))\r\n }\r\n\r\n if (!state.deviceItems) {\r\n let data = {}\r\n data.pageSize = pageSize\r\n data.orderBy = null\r\n\r\n setIsLoading(true)\r\n\r\n FirmwareAPI.getAllDevices(envId, data)\r\n .then((response) => {\r\n setState((prevState) => ({\r\n ...prevState,\r\n deviceItems: response.devices,\r\n currentVersions: response.firmware_versions,\r\n }))\r\n setTotalRows(response.total_devices)\r\n setFirmwareOptionIds(response.firmware_ids)\r\n })\r\n .catch((error) => {\r\n setState((prevState) => ({\r\n ...prevState,\r\n deviceItems: [],\r\n }))\r\n })\r\n .finally(() => {\r\n setIsLoading(false)\r\n })\r\n }\r\n\r\n window.addEventListener('resize', handleBodyResize, true)\r\n return () => {\r\n window.removeEventListener('resize', handleBodyResize, true)\r\n }\r\n }, [state.deviceItems, envId, pageSize])\r\n\r\n useEffect(() => {\r\n let addFilter = true\r\n\r\n filters.forEach((filter) => {\r\n if (filter.key === 'firmware_id' || firmwareIds == null) {\r\n addFilter = false\r\n }\r\n })\r\n\r\n if (addFilter === true) {\r\n let filter = {\r\n key: 'firmware_id',\r\n label: ResourceLang.firmware_id,\r\n type: 'select',\r\n options: firmwareIds,\r\n }\r\n setFilters([...filters, filter])\r\n }\r\n }, [firmwareIds, filters])\r\n\r\n useEffect(() => {\r\n function getFormatedVersion(version) {\r\n return allEqual(version, '0') ? '0' : version.replace(/\\b0+/g, '')\r\n }\r\n\r\n function uniqueAdd(array, object) {\r\n for (const index in array) {\r\n if (array[index].name === object.name) return false\r\n }\r\n return true\r\n }\r\n\r\n function setCurrentVersionOptions() {\r\n let ids = []\r\n\r\n if (state.currentVersions) {\r\n state.currentVersions.forEach((firmware_id) => {\r\n let id = {\r\n name: getFormatedVersion(firmware_id),\r\n value: firmware_id,\r\n }\r\n if (uniqueAdd(ids, id)) ids.push(id)\r\n })\r\n\r\n setCurrentVersions(stringArraySort(ids))\r\n }\r\n }\r\n\r\n setCurrentVersionOptions()\r\n }, [selectedFirmware, state.deviceItems, state.currentVersions])\r\n\r\n useEffect(() => {\r\n let addFilter = true\r\n let removeFilter = false\r\n\r\n if (\r\n selectedFirmware == null &&\r\n filters.find((filter) => filter.key === 'current_firmware_version')\r\n ) {\r\n removeFilter = true\r\n }\r\n\r\n let serialFilter = filters.find((filter) => filter.key === 'serial_number')\r\n if (serialFilter.value === '') {\r\n setCurrentPage(0)\r\n setPageSize(50)\r\n setSelectedSerial(null)\r\n }\r\n\r\n if (\r\n filters.find((filter) => filter.key === 'current_firmware_version') ||\r\n currentVersions == null ||\r\n currentVersions.length === 0 ||\r\n removeFilter === true ||\r\n selectedFirmware == null\r\n ) {\r\n addFilter = false\r\n }\r\n\r\n let filter = {\r\n key: 'current_firmware_version',\r\n label: ResourceLang.current_version,\r\n type: 'select',\r\n options: currentVersions,\r\n }\r\n\r\n if (addFilter === true && removeFilter === false) {\r\n setFilters([...filters, filter])\r\n }\r\n\r\n if (removeFilter === true) {\r\n setFilters(\r\n filters.filter(function (x) {\r\n return x.key !== 'current_firmware_version'\r\n })\r\n )\r\n }\r\n }, [currentVersions, selectedFirmware, filters])\r\n\r\n useEffect(() => {\r\n let data = {}\r\n data.serialNumber = debouncedselectedSerial\r\n data.firmwareId = selectedFirmware\r\n data.firmwareVersion = selectedVersion\r\n data.pageSize = pageSize\r\n data.toSkip = debouncedCurrentPage * pageSize\r\n data.orderBy = null\r\n\r\n setIsLoading(true)\r\n\r\n FirmwareAPI.getAllDevices(envId, data)\r\n .then((response) => {\r\n setState((prevState) => ({\r\n ...prevState,\r\n deviceItems: response.devices,\r\n currentVersions: response.firmware_versions,\r\n }))\r\n setTotalRows(response.total_devices)\r\n })\r\n .catch((error) => {\r\n setState((prevState) => ({\r\n ...prevState,\r\n deviceItems: [],\r\n }))\r\n })\r\n .finally(() => {\r\n setIsLoading(false)\r\n })\r\n }, [\r\n selectedFirmware,\r\n debouncedselectedSerial,\r\n selectedVersion,\r\n pageSize,\r\n envId,\r\n debouncedCurrentPage,\r\n ])\r\n\r\n function translateVersion(typeDescription, version) {\r\n if (isPoleMountedOrDtvi4G(typeDescription) === true) {\r\n return translatePoleMountVersion(version);\r\n } else {\r\n return translateDTVIVersion(version);\r\n }\r\n }\r\n\r\n function translatePoleMountVersion(version) {\r\n if (version === 1 || version === 2) {\r\n return DEVICE_VERSION_VALUES_ENUM.V1\r\n }\r\n else {\r\n return ResourceLang.not_applicable;\r\n }\r\n }\r\n\r\n function translateDTVIVersion(version) {\r\n\r\n if (version === 1) {\r\n return DEVICE_VERSION_VALUES_ENUM.V1\r\n }\r\n else if (version === 2) {\r\n return DEVICE_VERSION_VALUES_ENUM.V2\r\n }\r\n else if (version === 3 || version === 4) {\r\n return DEVICE_VERSION_VALUES_ENUM.V3\r\n }\r\n else if (version === 5 || version === 6) {\r\n return DEVICE_VERSION_VALUES_ENUM.V4\r\n }\r\n else {\r\n return ResourceLang.not_applicable\r\n }\r\n }\r\n\r\n function uniqueAdd(array, object) {\r\n for (const index in array) {\r\n if (\r\n array[index].value === object.value &&\r\n array[index].name === object.name\r\n )\r\n return false\r\n }\r\n return true\r\n }\r\n\r\n function allEqual(string, character) {\r\n return string.split('').every((char) => char === character)\r\n }\r\n\r\n function stringArraySort(array) {\r\n return array.sort(function (a, b) {\r\n return a.name.localeCompare(b.name)\r\n })\r\n }\r\n\r\n function exportCSVFile(deviceItems) {\r\n if (deviceItems !== null) {\r\n const formData = new FormData()\r\n formData.append('devices', JSON.stringify(deviceItems))\r\n FirmwareAPI.getCSVExportFile(formData)\r\n .then((response) => {\r\n const url = window.URL.createObjectURL(new Blob([response]), {\r\n type: 'text/csv',\r\n })\r\n const link = document.createElement('a')\r\n link.href = url\r\n link.target = '_blank'\r\n link.download = 'export_devices.csv'\r\n document.body.appendChild(link)\r\n link.click()\r\n })\r\n .catch((error) => {\r\n console.log(error)\r\n })\r\n }\r\n }\r\n\r\n const renderPageHeader = () => {\r\n return (\r\n \r\n \r\n \r\n {ResourceLang.list_device}\r\n \r\n {renderFilterButton()}\r\n {renderExportButton()}\r\n \r\n )\r\n }\r\n\r\n handleBodyResize()\r\n\r\n const renderExportButton = () => {\r\n return (\r\n <>\r\n {\r\n exportCSVFile(getTableItems())\r\n }}\r\n >\r\n \r\n {ResourceLang.export}\r\n \r\n >\r\n )\r\n }\r\n\r\n const renderFilterButton = () => {\r\n return (\r\n <>\r\n \r\n updateAnchorEl(event.currentTarget)}\r\n >\r\n \r\n \r\n \r\n \r\n >\r\n )\r\n }\r\n\r\n const renderFilters = (filterValues) => {\r\n return (\r\n \r\n \r\n {filterValues.map((item, index) => {\r\n return (\r\n {\r\n const newFilters = [...filters]\r\n const targetKey = newFilters.find((x) => x.key === item.key)\r\n if (targetKey.value instanceof Array) {\r\n targetKey.value = targetKey.value.filter(\r\n (x) => x.value !== item.value\r\n )\r\n } else {\r\n targetKey.value = null\r\n }\r\n setFilters(newFilters)\r\n }}\r\n className={classes.chip}\r\n />\r\n )\r\n })}\r\n \r\n \r\n )\r\n }\r\n\r\n const getFilterValuesArray = () => {\r\n const filterValues = []\r\n for (let i = 0; i < filters.length; i++) {\r\n if (filters[i].value instanceof Array) {\r\n if (filters[i].value.length > 0) {\r\n for (let j = 0; j < filters[i].value.length; j++) {\r\n if (\r\n filters[i].key === 'firmware_id' &&\r\n selectedFirmware !== filters[i].value[j].value\r\n ) {\r\n setCurrentPage(0)\r\n setPageSize(50)\r\n setSelectedFirmware(filters[i].value[j].value)\r\n } else if (\r\n filters[i].key === 'current_firmware_version' &&\r\n selectedVersion !== filters[i].value[j].value &&\r\n selectedFirmware !== null\r\n ) {\r\n setCurrentPage(0)\r\n setPageSize(50)\r\n setSelectedVersion(filters[i].value[j].value)\r\n }\r\n\r\n filterValues.push({\r\n ...filters[i].value[j],\r\n key: filters[i].key,\r\n type: filters[i].type,\r\n })\r\n }\r\n } else {\r\n if (filters[i].key === 'firmware_id' && selectedFirmware !== null) {\r\n setCurrentPage(0)\r\n setPageSize(50)\r\n setSelectedVersion(null)\r\n setSelectedFirmware(null)\r\n } else if (\r\n filters[i].key === 'current_firmware_version' &&\r\n selectedVersion !== null\r\n ) {\r\n setCurrentPage(0)\r\n setPageSize(50)\r\n setSelectedVersion(null)\r\n }\r\n }\r\n } else if (filters[i].value) {\r\n let name = filters[i].value\r\n\r\n if (filters[i].value instanceof Date)\r\n name = `${filters[i].label}: ${name.toLocaleDateString()}`\r\n\r\n if (\r\n filters[i].key === 'serial_number' &&\r\n selectedSerial !== filters[i].value\r\n ) {\r\n setCurrentPage(0)\r\n setPageSize(50)\r\n setSelectedSerial(filters[i].value)\r\n }\r\n\r\n filterValues.push({\r\n name: name,\r\n value: filters[i].value,\r\n key: filters[i].key,\r\n type: filters[i].type,\r\n })\r\n }\r\n }\r\n return filterValues\r\n }\r\n\r\n const renderTable = () => {\r\n const { deviceItems } = state\r\n if (!deviceItems) {\r\n return null\r\n }\r\n\r\n const columns = [\r\n {\r\n columnWidth: 50,\r\n label: '#',\r\n dataKey: 'device_id',\r\n align: 'left',\r\n disableSort: true,\r\n },\r\n {\r\n columnWidth: 150,\r\n label: ResourceLang.type,\r\n dataKey: 'device_type_description',\r\n },\r\n {\r\n columnWidth: 200,\r\n label: ResourceLang.hardware_version,\r\n dataKey: 'family_version',\r\n },\r\n {\r\n columnWidth: 225,\r\n label: ResourceLang.serial_number,\r\n dataKey: 'serial_number',\r\n },\r\n {\r\n columnWidth: 150,\r\n label: ResourceLang.ICCID,\r\n dataKey: 'iccid',\r\n },\r\n {\r\n columnWidth: 150,\r\n label: ResourceLang.CurrentIP,\r\n dataKey: 'current_ip',\r\n },\r\n {\r\n columnWidth: 125,\r\n label: ResourceLang.MSP,\r\n dataKey: 'formattedMSP',\r\n },\r\n {\r\n columnWidth: 125,\r\n label: ResourceLang.PIC,\r\n dataKey: 'formattedPIC',\r\n },\r\n {\r\n columnWidth: 125,\r\n label: ResourceLang.MEA,\r\n dataKey: 'formattedMEA',\r\n },\r\n {\r\n columnWidth: 125,\r\n label: ResourceLang.COM,\r\n dataKey: 'formattedCOM',\r\n },\r\n {\r\n columnWidth: 150,\r\n label: ResourceLang.last_communication,\r\n dataKey: 'last_contact',\r\n date: true,\r\n },\r\n ]\r\n\r\n const tableItems = getTableItems()\r\n\r\n const rowGetter = ({ index }) => {\r\n return tableItems[index]\r\n }\r\n\r\n const handleSort = (event) => {\r\n setSort({\r\n sortBy: event.sortBy,\r\n sortDirection: event.sortDirection,\r\n })\r\n }\r\n\r\n const onGoToPage = (event) => {\r\n let totalPages = Math.ceil(totalRows / pageSize)\r\n\r\n if (\r\n !event.target.value.includes('NaN') &&\r\n totalPages >= event.target.value\r\n ) {\r\n setPageError(false)\r\n setCurrentPage(event.target.value)\r\n } else {\r\n setPageError(true)\r\n setCurrentPage(null)\r\n }\r\n }\r\n\r\n function onChangePage(event, page) {\r\n setCurrentPage(page)\r\n }\r\n\r\n function onRowsPerPageChange(object) {\r\n setCurrentPage(0)\r\n setPageSize(object.target.value)\r\n }\r\n\r\n function getPagination() {\r\n let pagination = {}\r\n pagination.count = totalRows\r\n pagination.onChangePage = onChangePage\r\n pagination.page =\r\n debouncedCurrentPage == null ? 0 : parseInt(debouncedCurrentPage)\r\n pagination.rowsPerPage = pageSize\r\n pagination.onChangeRowsPerPage = onRowsPerPageChange\r\n pagination.rowsPerPageOptions = [10, 25, 50, 100, totalRows]\r\n return pagination\r\n }\r\n\r\n return (\r\n {\r\n setState((prevState) => ({ ...prevState, selected: rowData }))\r\n history.push(\r\n '/environment/' +\r\n envId +\r\n '/device/' +\r\n rowData.device_id +\r\n '/summary',\r\n { context: location.state.context }\r\n )\r\n }}\r\n />\r\n )\r\n }\r\n\r\n const filterValues = getFilterValuesArray()\r\n\r\n const getTableItems = () => {\r\n let results = [...state.deviceItems]\r\n\r\n if (sort.sortDirection === SortDirection.ASC) {\r\n results.sort((a, b) => compareValues(b[sort.sortBy], a[sort.sortBy]))\r\n } else {\r\n results.sort((a, b) => compareValues(a[sort.sortBy], b[sort.sortBy]))\r\n }\r\n\r\n return results\r\n }\r\n\r\n const hasFilters = filterValues.length > 0\r\n const HEADER_HEIGHT = 64\r\n const FILTERS_HEIGHT = 40\r\n const TOP_OFFSET = HEADER_HEIGHT + (hasFilters ? FILTERS_HEIGHT : 0)\r\n\r\n return (\r\n \r\n
\r\n \r\n \r\n {renderPageHeader()}\r\n \r\n {hasFilters ? (\r\n \r\n {renderFilters(filterValues)}\r\n \r\n ) : null}\r\n \r\n \r\n \r\n {renderTable()}\r\n \r\n \r\n \r\n {isLoading ?
: null}\r\n
\r\n )\r\n}\r\n\r\nexport default withRouter(ListDevicePage)","export function isDTVI(typeDescription){\r\n \r\n return (typeDescription === \"DTVIg\"\r\n || typeDescription === \"DTVIm\"\r\n || typeDescription === \"DTVI4g\"\r\n || typeDescription === \"DTVI-g PMT2\"\r\n || typeDescription === \"DTVI4-g PMT2\"\r\n || typeDescription === \"Pole Mount DTVIg\"\r\n || typeDescription === \"Pole Mount DTVI4-g\");\r\n}\r\n\r\nexport function isPoleMountedOrDtvi4G(typeDescription){\r\n return (typeDescription === \"DTVI-g PMT2\"\r\n || typeDescription === \"DTVI4-g PMT2\"\r\n || typeDescription === \"Pole Mount DTVIg\"\r\n || typeDescription === \"Pole Mount DTVI4-g\"\r\n || typeDescription === \"DTVI4-g\");\r\n}\r\n\r\nexport function isDTE(typeDescription){\r\n return (typeDescription === \"DTE\");\r\n}","import React, { useState } from 'react';\r\nimport {InputGroup, InputGroupAddon, InputGroupText, Input, FormFeedback } from 'reactstrap';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport VisibilityIcon from '@material-ui/icons/Visibility';\r\nimport VisibilityOffIcon from '@material-ui/icons/VisibilityOff';\r\n\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n passwordToogle: {\r\n cursor: 'pointer'\r\n }\r\n}));\r\n\r\n\r\nconst usePasswordToggle = () => {\r\n const [visible, setVisiblity] = useState(false);\r\n\r\n const Icon = (\r\n visible === true ?\r\n setVisiblity(visiblity => !visiblity)} />\r\n : setVisiblity(visiblity => !visiblity)} />\r\n );\r\n\r\n const InputType = visible ? \"text\" : \"password\";\r\n\r\n return [InputType, Icon];\r\n};\r\n\r\n\r\nconst InputPassword = ({\r\n value = \"\", readOnly = false, onChange = undefined, feedbackText = undefined, ...others\r\n}) => {\r\n const classes = useStyles();\r\n const [PasswordInputType, ToggleIcon] = usePasswordToggle();\r\n\r\n return (<>\r\n \r\n \r\n \r\n {readOnly ? null : {ToggleIcon}}\r\n \r\n {feedbackText ? {feedbackText} : null}\r\n \r\n >);\r\n}\r\n\r\n\r\nexport default InputPassword;","import React from 'react';\r\nimport Fab from '@material-ui/core/Fab';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\n\r\nexport const useStyles = makeStyles(theme => ({\r\n margin: {\r\n margin: theme.spacing(1),\r\n display: 'inline', float: 'right',\r\n backgroundColor: '#f3f3f4',\r\n border: 'solid 1px #F1C419',\r\n color: '#2C4153',\r\n fontSize: 12,\r\n fontWeight: 'bold',\r\n '&:hover':{\r\n backgroundColor: '#F1C419',\r\n color: 'white'\r\n }\r\n },\r\n extendedIcon: {\r\n fontSize:16,\r\n marginRight: theme.spacing(1),\r\n },\r\n submitButton: {\r\n margin: theme.spacing(1),\r\n backgroundColor: '#2C4153',\r\n border: 'solid 1px #F1C419',\r\n color: '#white',\r\n fontSize: 12,\r\n fontWeight: 'bold',\r\n '&:hover':{\r\n backgroundColor: '#F1C419',\r\n color: 'white'\r\n }\r\n },\r\n cancelButton: {\r\n margin: theme.spacing(1),\r\n backgroundColor: '#f3f3f4',\r\n border: 'solid 1px #F1C419',\r\n color: '#2C4153',\r\n fontSize: 12,\r\n fontWeight: 'bold',\r\n '&:hover':{\r\n backgroundColor: '#F1C419',\r\n color: 'white'\r\n }\r\n },\r\n }));\r\n\r\n\r\n export const OvalButtonPrimary = props =>{\r\n return(\r\n \r\n\r\n {props.children}\r\n \r\n )\r\n }\r\n","import Fab from '@material-ui/core/Fab';\r\nimport { withStyles } from '@material-ui/core/styles';\r\n\r\nexport const CircularButtonTransparent = withStyles(theme => ({\r\n root: {\r\n color: '#233442',\r\n backgroundColor: 'white',\r\n '&:hover': {\r\n backgroundColor: 'rgba(0, 0, 0, 0.08)',\r\n },\r\n },\r\n}))(Fab);\r\n\r\n\r\n","import React from 'react'\r\nimport PropTypes from 'prop-types';\r\nimport { withStyles } from '@material-ui/core/styles';\r\nimport { DialogTitle as MuiDialogTitle , DialogContent as MuiDialogContent,\r\n DialogActions as MuiDialogActions, IconButton, Typography, Tooltip,\r\n Dialog as MuiDialog} from '@material-ui/core';\r\nimport CloseIcon from '@material-ui/icons/Close';\r\n\r\n\r\nconst styles = (theme) => ({\r\n root: {\r\n margin: 0,\r\n padding: theme.spacing(2),\r\n },\r\n closeButton: {\r\n position: 'absolute',\r\n right: theme.spacing(1),\r\n top: theme.spacing(1),\r\n color: theme.palette.grey[500],\r\n },\r\n});\r\n \r\n\r\nconst DialogTitle = withStyles(styles)(({children, classes, onClose, closeLabel = 'Close', ...other}) => {\r\n return (\r\n {children}\r\n \r\n \r\n \r\n \r\n \r\n );\r\n});\r\n\r\n\r\nconst DialogContent = withStyles((theme) => ({\r\n root: {\r\n padding: theme.spacing(2),\r\n },\r\n}))(MuiDialogContent);\r\n\r\nconst DialogActions = withStyles((theme) => ({\r\n root: {\r\n margin: 0,\r\n padding: theme.spacing(2),\r\n },\r\n}))(MuiDialogActions);\r\n\r\n\r\nconst Dialog = ({fullWidth = true, disableBackdropClick = true, disableEscapeKeyDown = true,\r\n onClose, closeLabel, titleRenderer, actionsRenderer, children, ...other\r\n}) => {\r\n return (\r\n \r\n \r\n {titleRenderer()}\r\n \r\n \r\n {children}\r\n \r\n {actionsRenderer ?(\r\n \r\n {actionsRenderer()}\r\n ) : null\r\n }\r\n \r\n
);\r\n}\r\n\r\n\r\nDialog.propTypes = {\r\n open: PropTypes.bool.isRequired,\r\n fullWidth: PropTypes.bool,\r\n disableBackdropClick: PropTypes.bool,\r\n disableEscapeKeyDown: PropTypes.bool,\r\n onClose: PropTypes.func.isRequired,\r\n closeLabel: PropTypes.string,\r\n titleRenderer: PropTypes.func.isRequired,\r\n actionsRenderer: PropTypes.func\r\n};\r\n\r\nexport default Dialog;","\r\nimport MuiVirtualizedTable from '../../../components/tables/MuiVirtualizedTable';\r\nimport ResourceLang from '../../../resources/Language';\r\nimport PropTypes from 'prop-types';\r\nimport cloneDeep from 'lodash/cloneDeep';\r\n\r\nconst NTPSettings = ({settings}) => {\r\n\r\n const DEVICE_SETTINGS_KEYS = {\r\n TIMESERVER_URL: 'timeserver_url',\r\n TIMESERVER_PORT:'timeserver_port',\r\n TIMESERVER_PROTOCOL: 'timeserver_protocol',\r\n TIMESERVER_TYPE: 'timeserver_type' \r\n }\r\n const translatedSettings = cloneDeep(settings);\r\n\r\n function translateSettingsToTableRender(settingsToUpdate) {\r\n if(settingsToUpdate.timeserver_type !== undefined){\r\n if(settingsToUpdate.timeserver_type === 0){\r\n settingsToUpdate.timeserver_type = ResourceLang.ntp\r\n }\r\n else if (settingsToUpdate.timeserver_type === 1)\r\n {\r\n settingsToUpdate.timeserver_type = ResourceLang.htp\r\n }\r\n else if (settingsToUpdate.timeserver_type === 2)\r\n {\r\n settingsToUpdate.timeserver_type = ResourceLang.deepgrid\r\n }\r\n }\r\n }\r\n\r\n\r\n const renderSettingsTable = () => {\r\n if (translatedSettings !== undefined ) {\r\n translateSettingsToTableRender(translatedSettings[0])\r\n const columns = [\r\n {\r\n columnWidth: 75,\r\n label: ResourceLang.timeserver_url,\r\n dataKey: DEVICE_SETTINGS_KEYS.TIMESERVER_URL,\r\n disableSort: false,\r\n },\r\n {\r\n columnWidth: 75,\r\n label: ResourceLang.timeserver_port,\r\n dataKey: DEVICE_SETTINGS_KEYS.TIMESERVER_PORT,\r\n disableSort: false,\r\n },\r\n {\r\n columnWidth: 75,\r\n label: ResourceLang.timeserver_protocol,\r\n dataKey: DEVICE_SETTINGS_KEYS.TIMESERVER_PROTOCOL,\r\n disableSort: false,\r\n },\r\n {\r\n columnWidth: 75,\r\n label: ResourceLang.timeserver_type,\r\n dataKey: DEVICE_SETTINGS_KEYS.TIMESERVER_TYPE,\r\n disableSort: false,\r\n }\r\n ];\r\n \r\n return ( translatedSettings[index]}\r\n sortBy={DEVICE_SETTINGS_KEYS.TIMESERVER_URL}\r\n sortDirection={'ASC'}\r\n columns={columns}\r\n />);\r\n }\r\n else {\r\n return (<>>)\r\n }\r\n \r\n }\r\n\r\n return(<>{renderSettingsTable()}>)\r\n\r\n}\r\n\r\n\r\nNTPSettings.propTypes = {\r\n settings: PropTypes.array.isRequired\r\n};\r\n\r\nexport default NTPSettings; ","\r\nimport MuiVirtualizedTable from '../../../components/tables/MuiVirtualizedTable';\r\nimport ResourceLang from '../../../resources/Language';\r\nimport PropTypes from 'prop-types';\r\nimport cloneDeep from 'lodash/cloneDeep';\r\n\r\nconst APNSettings = ({settings}) => {\r\n\r\n const DEVICE_SETTINGS_KEYS = {\r\n APN_NAME: 'apn_name',\r\n APN_USER:'apn_user',\r\n APN_PWD: 'apn_pwd',\r\n APN_AUTH_TYPE: 'apn_auth_type' \r\n }\r\n\r\n const translatedSettings = cloneDeep(settings);\r\n\r\n function translateApnAuthType(translatedSettings){\r\n if(translatedSettings.apn_auth_type === 1){\r\n translatedSettings.apn_auth_type = ResourceLang.PAP\r\n }\r\n else if (translatedSettings.apn_auth_type === 2)\r\n {\r\n translatedSettings.apn_auth_type = ResourceLang.CHAP\r\n }\r\n else if (translatedSettings.apn_auth_type === 3)\r\n {\r\n translatedSettings.apn_auth_type = ResourceLang.PAP_OR_CHAP\r\n }\r\n }\r\n\r\n function translatePwd(translatedSettings){\r\n let password_chars=\"\";\r\n for(let index = 0;index {\r\n if (translatedSettings !== undefined) {\r\n translateSettingsToTableRender(translatedSettings[0])\r\n const columns = [\r\n {\r\n columnWidth: 150,\r\n label: ResourceLang.name,\r\n dataKey: DEVICE_SETTINGS_KEYS.APN_NAME,\r\n disableSort: false,\r\n },\r\n {\r\n columnWidth: 75,\r\n label: ResourceLang.User,\r\n dataKey: DEVICE_SETTINGS_KEYS.APN_USER,\r\n disableSort: false,\r\n },\r\n {\r\n columnWidth: 75,\r\n label: ResourceLang.password,\r\n dataKey: DEVICE_SETTINGS_KEYS.APN_PWD,\r\n disableSort: false,\r\n },\r\n {\r\n columnWidth: 100,\r\n label: ResourceLang.Auth,\r\n dataKey: DEVICE_SETTINGS_KEYS.APN_AUTH_TYPE,\r\n disableSort: false\r\n }\r\n ];\r\n \r\n return ( translatedSettings[index]}\r\n sortBy={DEVICE_SETTINGS_KEYS.APN_NAME}\r\n sortDirection={'ASC'}\r\n columns={columns}\r\n />);\r\n }\r\n else {\r\n return (<>>)\r\n }\r\n \r\n }\r\n\r\n return(<>{renderSettingsTable()}>)\r\n\r\n}\r\n\r\nAPNSettings.propTypes = {\r\n settings: PropTypes.array.isRequired\r\n};\r\n\r\nexport default APNSettings; ","import React from 'react';\r\nimport ResourceLang from '../../../resources/Language';\r\nimport { withRouter } from \"react-router\";\r\nimport Grid from '@material-ui/core/Grid';\r\nimport Checkbox from '@material-ui/core/Checkbox';\r\nimport MuiVirtualizedTable from '../../tables/MuiVirtualizedTable';\r\nimport PropTypes from 'prop-types';\r\nimport { DEVICE_KEYS_ENUM, SETTINGS_TYPE_ENUM } from '../../../utils/Enums';\r\nimport NTPSettings from './NTPSettings';\r\nimport APNSetting from './APNSettings';\r\nimport { Autocomplete } from '@material-ui/lab';\r\nimport CheckIcon from '@material-ui/icons/Check';\r\nimport ClearIcon from '@material-ui/icons/Clear';\r\nimport {Typography, TextField} from '@material-ui/core';\r\nimport Button from '@material-ui/core/Button';\r\n\r\nconst SelectDeviceSettings = ({ devices, selectedDevices, settingsToUpdate,\r\n settingsType , handleSelection, selectAllDevices, clearAllSelectedDevices }) => {\r\n\r\n const [serialNumberFilter, setSerialNumberFilter] = React.useState();\r\n\r\n const handleSelectDevice = (rowData, event) => {\r\n handleSelection(rowData, event.target.checked)\r\n }\r\n\r\n const isSelected = (rowData) => {\r\n const isChecked = selectedDevices.some(function (device) {\r\n return device.device_id === rowData.device_id;\r\n });\r\n\r\n return isChecked\r\n }\r\n\r\n\r\n const renderDevicesTable = () => {\r\n if (devices !== undefined && devices.length > 0) {\r\n const columns = [\r\n {\r\n columnWidth: 35,\r\n label: '#',\r\n dataKey: DEVICE_KEYS_ENUM.DEVICE_ID,\r\n disableSort: true,\r\n render: (rowData) => {\r\n return ( { handleSelectDevice(rowData, e) }}\r\n color='primary'\r\n checked={isSelected(rowData)} />)\r\n }\r\n },\r\n {\r\n columnWidth: 75,\r\n label: ResourceLang.serial_number,\r\n dataKey: DEVICE_KEYS_ENUM.SERIAL_NUMBER,\r\n disableSort: false,\r\n }\r\n ];\r\n if(!serialNumberFilter){\r\n return ( devices[index]}\r\n sortBy={DEVICE_KEYS_ENUM.SERIAL_NUMBER}\r\n sortDirection={'ASC'}\r\n onRowClick={() => { }}\r\n onLoadMore={() => { }}\r\n columns={columns}\r\n />);\r\n }\r\n else{\r\n return ( obj.serial_number === serialNumberFilter).length}\r\n rowCount={devices.filter(obj => obj.serial_number === serialNumberFilter).length}\r\n rowGetter={({ index }) => devices[index]}\r\n sortBy={DEVICE_KEYS_ENUM.SERIAL_NUMBER}\r\n sortDirection={'ASC'}\r\n onRowClick={() => { }}\r\n onLoadMore={() => { }}\r\n columns={columns}\r\n />);\r\n }\r\n \r\n }\r\n else {\r\n return (<>>)\r\n }\r\n\r\n }\r\n\r\n const renderSettingsTable = () => {\r\n if(settingsType === SETTINGS_TYPE_ENUM.APN) {\r\n return(\r\n \r\n )\r\n }\r\n else if (settingsType === SETTINGS_TYPE_ENUM.NTP) {\r\n return(\r\n \r\n )\r\n }\r\n else{\r\n return (<>>)\r\n }\r\n }\r\n\r\n const renderSelectButton = () => {\r\n if (!selectedDevices.length) {\r\n return ();\r\n }\r\n else {\r\n return ();\r\n }\r\n}\r\n\r\n\r\n const renderDeviceSearch = () => {\r\n if(selectedDevices !== undefined){\r\n return ( obj.serial_number)}\r\n onInputChange={(event, newValue, reason) => {\r\n console.log(newValue)\r\n if (reason === 'clear'){\r\n setSerialNumberFilter(newValue);\r\n }\r\n else{\r\n setSerialNumberFilter(newValue);\r\n }\r\n }}\r\n renderInput={(params) => (\r\n \r\n )}\r\n />);\r\n }\r\n else{\r\n return (<>>)\r\n }\r\n}\r\n\r\n\r\n const renderHeader = () => {\r\n return (\r\n \r\n \r\n {ResourceLang.total_devices} ({selectedDevices ? selectedDevices.length : 0})\r\n \r\n \r\n \r\n \r\n {renderDeviceSearch()}\r\n {renderSelectButton()}\r\n \r\n \r\n );\r\n}\r\n\r\n return (\r\n \r\n \r\n {renderHeader()}\r\n \r\n \r\n {renderDevicesTable()}\r\n \r\n \r\n {renderSettingsTable()}\r\n \r\n \r\n );\r\n}\r\n\r\nSelectDeviceSettings.propTypes = {\r\n devices: PropTypes.array.isRequired,\r\n selectedDevices: PropTypes.array.isRequired,\r\n settingsToUpdate: PropTypes.array.isRequired,\r\n settingsType: PropTypes.number.isRequired,\r\n handleSelection: PropTypes.func.isRequired,\r\n selectAllDevices: PropTypes.func.isRequired,\r\n clearAllSelectedDevices: PropTypes.func.isRequired\r\n};\r\n\r\nexport default withRouter(SelectDeviceSettings);","import React from 'react';\r\nimport ResourceLang from '../../../resources/Language';\r\nimport PropTypes from 'prop-types';\r\nimport { Grid, InputLabel } from '@material-ui/core';\r\nimport RawVirtualizedGrid from '../../tables/RawVirtualizedGrid';\r\nimport cloneDeep from 'lodash/cloneDeep';\r\n\r\nconst UpdateNTPSettings = ({devices, dataToBeUpdated}) => {\r\n\r\n const DeviceKeysEnum = {\r\n SERIAL_NUMBER: 'serial_number'\r\n }\r\n\r\n const DEVICE_SETTINGS_KEYS = {\r\n TIMESERVER_URL: 'timeserver_url',\r\n TIMESERVER_PORT:'timeserver_port',\r\n TIMESERVER_PROTOCOL: 'timeserver_protocol',\r\n TIMESERVER_TYPE: 'timeserver_type' \r\n }\r\n\r\n const NTP_SETTINGS_INDEX = {\r\n NTP: 0,\r\n HTP: 1,\r\n DEEPGRID: 2\r\n }\r\n\r\n function translateSettingsToTableRender(settingsToUpdate) {\r\n if(settingsToUpdate.timeserver_type !== undefined){\r\n if(settingsToUpdate.timeserver_type === NTP_SETTINGS_INDEX.NTP){\r\n settingsToUpdate.timeserver_type = ResourceLang.ntp\r\n }\r\n else if (settingsToUpdate.timeserver_type === NTP_SETTINGS_INDEX.HTP)\r\n {\r\n settingsToUpdate.timeserver_type = ResourceLang.htp\r\n }\r\n else if (settingsToUpdate.timeserver_type === NTP_SETTINGS_INDEX.DEEPGRID)\r\n {\r\n settingsToUpdate.timeserver_type = ResourceLang.deepgrid\r\n }\r\n }\r\n }\r\n\r\n const translatedSettings = cloneDeep(dataToBeUpdated);\r\n \r\n const renderContent = () => {\r\n return (\r\n \r\n {ResourceLang.devices}\r\n {renderDeviceItems()}\r\n {ResourceLang.data_update_apn}\r\n {renderNTPSettings()}\r\n \r\n \r\n );\r\n }\r\n\r\n const renderDeviceItems = () => {\r\n const gridRowGetter = (index) => { return devices[index]; }\r\n const keys = Object.keys(devices[0]);\r\n var columns = keys.map(key => ({label: ResourceLang[key], dataKey:key}))\r\n .filter(x => x.dataKey === DeviceKeysEnum.SERIAL_NUMBER );\r\n \r\n return (\r\n \r\n
);\r\n }\r\n\r\n const renderNTPSettings = () => {\r\n translateSettingsToTableRender(translatedSettings[0])\r\n const gridRowGetter = (index) => { return translatedSettings[index]; }\r\n const columns = [\r\n {\r\n columnWidth: 75,\r\n label: ResourceLang.timeserver_url,\r\n dataKey: DEVICE_SETTINGS_KEYS.TIMESERVER_URL,\r\n disableSort: false,\r\n },\r\n {\r\n columnWidth: 75,\r\n label: ResourceLang.timeserver_port,\r\n dataKey: DEVICE_SETTINGS_KEYS.TIMESERVER_PORT,\r\n disableSort: false,\r\n },\r\n {\r\n columnWidth: 75,\r\n label: ResourceLang.timeserver_protocol,\r\n dataKey: DEVICE_SETTINGS_KEYS.TIMESERVER_PROTOCOL,\r\n disableSort: false,\r\n },\r\n {\r\n columnWidth: 75,\r\n label: ResourceLang.timeserver_type,\r\n dataKey: DEVICE_SETTINGS_KEYS.TIMESERVER_TYPE,\r\n disableSort: false,\r\n }\r\n ];\r\n \r\n return (\r\n \r\n
);\r\n }\r\n\r\n\r\n return (<>{renderContent()}>)\r\n}\r\n\r\nUpdateNTPSettings.propTypes = {\r\n devices: PropTypes.array.isRequired,\r\n dataToBeUpdated: PropTypes.array.isRequired\r\n};\r\n\r\nexport default UpdateNTPSettings;","import React from 'react';\r\nimport ResourceLang from '../../../resources/Language';\r\nimport PropTypes from 'prop-types';\r\nimport { Grid, InputLabel } from '@material-ui/core';\r\nimport RawVirtualizedGrid from '../../tables/RawVirtualizedGrid';\r\nimport cloneDeep from 'lodash/cloneDeep';\r\n\r\nconst UpdateAPNSettings = ({devices, dataToBeUpdated}) => {\r\n\r\n const DeviceKeysEnum = {\r\n SERIAL_NUMBER: 'serial_number'\r\n }\r\n\r\n const DEVICE_SETTINGS_KEYS = {\r\n APN_NAME: 'apn_name',\r\n APN_USER:'apn_user',\r\n APN_PWD: 'apn_pwd',\r\n APN_AUTH_TYPE: 'apn_auth_type' \r\n }\r\n\r\n const APN_SETTINGS_INDEX = {\r\n PAP: 1,\r\n CHAP: 2,\r\n PAP_OR_CHAP: 3\r\n }\r\n\r\n function translateApnAuthType(translatedSettings){\r\n if(translatedSettings.apn_auth_type === APN_SETTINGS_INDEX.PAP){\r\n translatedSettings.apn_auth_type = ResourceLang.PAP\r\n }\r\n else if (translatedSettings.apn_auth_type === APN_SETTINGS_INDEX.CHAP)\r\n {\r\n translatedSettings.apn_auth_type = ResourceLang.CHAP\r\n }\r\n else if (translatedSettings.apn_auth_type === APN_SETTINGS_INDEX.PAP_OR_CHAP)\r\n {\r\n translatedSettings.apn_auth_type = ResourceLang.PAP_OR_CHAP\r\n }\r\n }\r\n \r\n function translatePwd(translatedSettings){\r\n let password_chars=\"\";\r\n for(let index = 0;index {\r\n return (\r\n \r\n {ResourceLang.devices}\r\n {renderDeviceItems()}\r\n {ResourceLang.data_update_apn}\r\n {renderApnSettings()}\r\n \r\n \r\n );\r\n }\r\n\r\n const renderDeviceItems = () => {\r\n const gridRowGetter = (index) => { return devices[index]; }\r\n const keys = Object.keys(devices[0]);\r\n var columns = keys.map(key => ({label: ResourceLang[key], dataKey:key}))\r\n .filter(x => x.dataKey === DeviceKeysEnum.SERIAL_NUMBER );\r\n \r\n return (\r\n \r\n
);\r\n }\r\n\r\n const renderApnSettings = () => {\r\n translateSettingsToTableRender(translatedSettings[0])\r\n const gridRowGetter = (index) => { return translatedSettings[index]; }\r\n const columns = [\r\n {\r\n columnWidth: 150,\r\n label: ResourceLang.name,\r\n dataKey: DEVICE_SETTINGS_KEYS.APN_NAME,\r\n disableSort: false,\r\n },\r\n {\r\n columnWidth: 75,\r\n label: ResourceLang.User,\r\n dataKey: DEVICE_SETTINGS_KEYS.APN_USER,\r\n disableSort: false,\r\n },\r\n {\r\n columnWidth: 75,\r\n label: ResourceLang.password,\r\n dataKey: DEVICE_SETTINGS_KEYS.APN_PWD,\r\n disableSort: false,\r\n },\r\n {\r\n columnWidth: 100,\r\n label: ResourceLang.Auth,\r\n dataKey: DEVICE_SETTINGS_KEYS.APN_AUTH_TYPE,\r\n disableSort: false\r\n }\r\n ];\r\n return (\r\n \r\n
);\r\n }\r\n\r\n\r\n return (<>{renderContent()}>)\r\n}\r\n\r\nUpdateAPNSettings.propTypes = {\r\n devices: PropTypes.array.isRequired,\r\n dataToBeUpdated: PropTypes.array.isRequired\r\n};\r\n\r\nexport default UpdateAPNSettings;","import React, { useEffect } from 'react';\r\nimport Button from '@material-ui/core/Button';\r\nimport ResourceLang from '../../../resources/Language';\r\nimport PropTypes from 'prop-types';\r\nimport DialogStepper from '../../stepper/DialogStepper'\r\nimport Grid from '@material-ui/core/Grid';\r\nimport Dialog from '../Dialog';\r\nimport SelectDeviceSettings from \"../../panels/settings/SelectDeviceSettings\";\r\nimport UpdateNTPSettingsReview from '../../panels/settings/UpdateNTPSettingsReview';\r\nimport UpdateAPNSettingsReview from '../../panels/settings/UpdateAPNSettingsReview';\r\nimport MessageSnackbar from '../../notifications/MessageSnackbar';\r\nimport { FirmwareAPI } from \"../../../utils/APIRequester\";\r\nimport {SETTINGS_TYPE_ENUM } from '../../../utils/Enums';\r\n\r\n\r\nfunction getSteps() {\r\n return [ResourceLang.select_devices,\r\n ResourceLang.review_and_confirmation];\r\n}\r\n\r\nconst SELECT_DEVICES_STEP = 0;\r\nconst REVIEW_STEP = 1;\r\n\r\nconst DeviceSettingsDialog = ({ isOpen, closeModal, settingsType, envId,\r\n deviceItemId, dataToBeUpdated }) => {\r\n const [ snackbar, setSnackbar] = React.useState({ open: false, variant: 'error', message: ''});\r\n const [ state, setState] = React.useState({\r\n devices: [],\r\n selectedDevices: [],\r\n activeStep: 0,\r\n name: undefined,\r\n description: undefined,\r\n disableNext: true,\r\n error: false,\r\n isLoading: true,\r\n selectedSds: []\r\n });\r\n const steps = getSteps();\r\n\r\n const getAllData = React.useCallback(() => {\r\n Promise.all([\r\n FirmwareAPI.getDevicesFamilyByDeviceId(envId, deviceItemId)\r\n ])\r\n .then(responses => {\r\n if (responses[0] && Array.isArray(responses[0])) {\r\n setState(prevState => ({\r\n ...prevState,\r\n isLoading: false,\r\n devices: responses[0]\r\n }));\r\n }\r\n }).catch(error => {\r\n setState((prevState) => ({\r\n ...prevState,\r\n isLoading: false,\r\n }));\r\n })\r\n },[envId, deviceItemId]);\r\n\r\n\r\n useEffect(() => {\r\n const load = async () => {\r\n getAllData()\r\n }\r\n if(isOpen){\r\n load();\r\n setState(prevState => ({\r\n ...prevState,\r\n isLoading: false\r\n }));\r\n }\r\n\r\n }, [isOpen, getAllData]);\r\n\r\n\r\n const handleClose = () => {\r\n setState((prevState) => ({\r\n ...prevState, \r\n activeStep: SELECT_DEVICES_STEP,\r\n devices: [],\r\n selectedDevices: [],\r\n disableNext: true\r\n }));\r\n closeModal()\r\n };\r\n\r\n function updateAPNSettingsIntoServer(deviceIds, dataToUpdate){\r\n const formData = new FormData();\r\n formData.append('gprs', JSON.stringify(dataToUpdate));\r\n formData.append('ids', JSON.stringify(deviceIds));\r\n FirmwareAPI.putGPRSSettingsInBatchByDevice(envId, formData)\r\n .then(response => {\r\n setSnackbar((prevState) => ({...prevState, \r\n open: true,\r\n variant: \"success\",\r\n message: ResourceLang.update_devices_with_success\r\n }));\r\n }).catch(error => {\r\n setSnackbar((prevState) => ({...prevState, \r\n open: true,\r\n variant: \"error\",\r\n message: ResourceLang.generic_error\r\n }));\r\n })\r\n }\r\n\r\n function updateNTPSettingsIntoServer(deviceIds,dataToUpdate ){\r\n const formData = new FormData();\r\n formData.append('ntp', JSON.stringify(dataToUpdate));\r\n formData.append('ids', JSON.stringify(deviceIds));\r\n FirmwareAPI.putNTPSettingsInBatchByDevice(envId, formData)\r\n .then(response => {\r\n setSnackbar((prevState) => ({...prevState, \r\n open: true,\r\n variant: \"success\",\r\n message: ResourceLang.update_devices_with_success\r\n }));\r\n }).catch(error => {\r\n setSnackbar((prevState) => ({...prevState, \r\n open: true,\r\n variant: \"error\",\r\n message: ResourceLang.generic_error\r\n }));\r\n })\r\n }\r\n\r\n function prepareItemsToUpdateOnServer(devices, dataToUpdate) {\r\n var deviceIds = []\r\n if(devices && dataToUpdate){\r\n devices.forEach(item => {\r\n deviceIds.push(item.device_id)\r\n });\r\n if(settingsType === SETTINGS_TYPE_ENUM.APN){\r\n updateAPNSettingsIntoServer(deviceIds, dataToUpdate)\r\n }\r\n else if (settingsType === SETTINGS_TYPE_ENUM.NTP){\r\n updateNTPSettingsIntoServer(deviceIds, dataToUpdate)\r\n }\r\n }\r\n }\r\n\r\n const submitUpdate = () => {\r\n prepareItemsToUpdateOnServer(state.selectedDevices, dataToBeUpdated[0])\r\n setState((prevState) => ({\r\n ...prevState, \r\n activeStep: SELECT_DEVICES_STEP,\r\n devices: [],\r\n selectedDevices: [],\r\n disableNext: true\r\n }));\r\n closeModal();\r\n }\r\n\r\n const handleNext = () => {\r\n if(state.activeStep === REVIEW_STEP){\r\n submitUpdate()\r\n }\r\n else{\r\n setState((prevState) => ({\r\n ...prevState, \r\n activeStep: state.activeStep + 1\r\n }));\r\n }\r\n };\r\n\r\n const handleBack = () => {\r\n if(state.activeStep === SELECT_DEVICES_STEP){\r\n setState((prevState) => ({\r\n ...prevState, \r\n activeStep: SELECT_DEVICES_STEP,\r\n devices: [],\r\n selectedDevices: [],\r\n disableNext: true\r\n }));\r\n closeModal();\r\n }\r\n else{\r\n setState((prevState) => ({\r\n ...prevState, \r\n activeStep: state.activeStep - 1\r\n }));\r\n }\r\n };\r\n\r\n const setDeviceSelected = (rowData, isChecked) => {\r\n var devices = state.selectedDevices;\r\n\r\n if (isChecked === true) {\r\n devices.push(rowData);\r\n } else {\r\n devices = state.selectedDevices.filter(function (device) {\r\n return device.device_id !== rowData.device_id;\r\n });\r\n }\r\n\r\n return devices;\r\n }\r\n\r\n\r\n const handleSelection = (rowData, isChecked) => {\r\n if (rowData !== undefined) {\r\n const devices = setDeviceSelected(rowData, isChecked)\r\n if(devices.length){\r\n setState((prevState) => ({\r\n ...prevState, \r\n selectedDevices: devices,\r\n disableNext: false\r\n }));\r\n }\r\n else{\r\n setState((prevState) => ({\r\n ...prevState, \r\n selectedDevices: devices,\r\n disableNext: true\r\n }));\r\n }\r\n }\r\n }\r\n\r\n const selectAllDevices = () =>{\r\n setState((prevState) => ({\r\n ...prevState, \r\n selectedDevices: state.devices,\r\n disableNext: false\r\n }));\r\n }\r\n\r\n const clearAllSelectedDevices = () =>{\r\n setState((prevState) => ({\r\n ...prevState, \r\n selectedDevices: [],\r\n disableNext:true\r\n }));\r\n }\r\n\r\n const renderBody = () => {\r\n if(state.devices !== undefined)\r\n {\r\n switch (state.activeStep) {\r\n case 0:\r\n return();\r\n case 1:\r\n if(settingsType === SETTINGS_TYPE_ENUM.APN){\r\n return(\r\n )\r\n }\r\n else if(settingsType === SETTINGS_TYPE_ENUM.NTP){\r\n return(\r\n )\r\n }\r\n break;\r\n \r\n default:\r\n return (<>>);\r\n }\r\n }\r\n }\r\n\r\n const renderTitle = () => {\r\n if(settingsType === SETTINGS_TYPE_ENUM.APN){\r\n return (\r\n <>{ResourceLang.device_settings_update} -\r\n {ResourceLang.Apn_Settings}>\r\n )\r\n }\r\n else if (settingsType === SETTINGS_TYPE_ENUM.NTP){\r\n return (\r\n <>{ResourceLang.device_settings_update} - \r\n {ResourceLang.ntp_settings}>\r\n )\r\n }\r\n else{\r\n return (\r\n <>{ResourceLang.device_settings_update} -\r\n {ResourceLang.unknowm}>\r\n )\r\n }\r\n }\r\n\r\n const renderContent = () => {\r\n return (\r\n \r\n \r\n {renderBody()}\r\n
\r\n )\r\n }\r\n\r\n const renderFooter = () => {\r\n return (\r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n )\r\n }\r\n\r\n const handleSnackbarClose = () =>{\r\n setSnackbar((prevState) => ({...prevState, \r\n open: false, \r\n }));\r\n }\r\n\r\n const renderSnackbar = () => {\r\n return ();\r\n }\r\n\r\n\r\n return (\r\n \r\n \r\n {renderSnackbar()}\r\n
\r\n );\r\n}\r\n\r\nDeviceSettingsDialog.propTypes = {\r\n isOpen: PropTypes.bool.isRequired,\r\n closeModal: PropTypes.func.isRequired,\r\n settingsType: PropTypes.number.isRequired,\r\n envId: PropTypes.string.isRequired,\r\n deviceItemId: PropTypes.string.isRequired,\r\n dataToBeUpdated: PropTypes.array.isRequired\r\n};\r\n\r\nexport default DeviceSettingsDialog;","import React, { useState } from 'react';\r\nimport PropTypes from 'prop-types';\r\nimport ResourceLang from '../../../resources/Language';\r\nimport InputPassword from '../../../components/inputs/InputPassword';\r\nimport {FirmwareAPI} from '../../../utils/APIRequester';\r\nimport { OvalButtonPrimary, useStyles as ovalByttonsStyleBase } from '../../../components/buttons/OvalButtons';\r\nimport { CircularButtonTransparent } from '../../../components/buttons/CircularButtons';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport { Row, Col, FormGroup, Label, Input } from 'reactstrap';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { faSignal } from '@fortawesome/free-solid-svg-icons';\r\nimport {SETTINGS_TYPE_ENUM } from '../../../utils/Enums';\r\nimport EditIcon from '@material-ui/icons/Edit';\r\nimport DeviceSettingsDialog from '../../../components/dialogs/add/DeviceSettingsDialog';\r\nimport MessageSnackbar from '../../../components/notifications/MessageSnackbar';\r\nimport CheckIcon from '@material-ui/icons/Check';\r\nimport CancelIcon from '@material-ui/icons/NotInterested';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Tooltip from '@material-ui/core/Tooltip';\r\nimport Divider from '@material-ui/core/Divider';\r\nimport Button from '@material-ui/core/Button';\r\nimport Typography from '@material-ui/core/Typography';\r\n\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n paper: {\r\n padding: theme.spacing(3),\r\n margin: theme.spacing(1),\r\n },\r\n button: {\r\n margin: theme.spacing(1),\r\n float:'right'\r\n },\r\n label_title: {\r\n color: \"#94A3A7\",\r\n fontWeight: 'bold',\r\n marginBottom: theme.spacing(0)\r\n },\r\n divider:{\r\n marginTop: theme.spacing(2),\r\n marginBottom: theme.spacing(1),\r\n }\r\n}));\r\n\r\n\r\nconst APNSettings = ({\r\n envId, interfaceGPRS, deviceItemId\r\n}) => {\r\n const classes = useStyles();\r\n const ovalButtonsStyle = ovalByttonsStyleBase();\r\n const [editMode, setEditMode] = useState(false);\r\n const [openApplyToDialog, setApplyToDialog] = useState(false);\r\n const [ snackbar, setSnackbar] = useState({ open: false, variant: 'error', message: ''});\r\n const [data, setData] = useState(interfaceGPRS);\r\n \r\n const readOnly = editMode ? '' : 'readonly';\r\n\r\n\r\n const handleEditClick = () => {\r\n setEditMode(!editMode);\r\n }\r\n\r\n const renderPanelHeader = () => {\r\n return (\r\n \r\n \r\n {ResourceLang.Apn_Settings} \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
);\r\n }\r\n\r\n const renderAuthInput = () => {\r\n const AUTH_OPTIONS = [\r\n {label: ResourceLang.NONE, value: 0},\r\n {label: ResourceLang.PAP, value: 1},\r\n {label: ResourceLang.CHAP, value: 2},\r\n {label: ResourceLang.PAP_OR_CHAP, value: 3},\r\n ]\r\n\r\n if(editMode) {\r\n return({\r\n const value = parseInt(event.target.value, 10);\r\n setData({...data, apn_auth_type: value});\r\n }}>\r\n {\r\n AUTH_OPTIONS.map(({value, label}) => \r\n \r\n )\r\n }\r\n );\r\n }\r\n else{\r\n let value = ResourceLang.NONE;\r\n\r\n if (data.apn_auth_type) {\r\n const target = AUTH_OPTIONS.find(x => x.value === data.apn_auth_type);\r\n if (target)\r\n value = target.label;\r\n }\r\n\r\n return(\r\n \r\n {value}\r\n \r\n );\r\n }\r\n }\r\n\r\n const renderNameField = () => {\r\n if (editMode === true)\r\n return (\r\n {\r\n setData({...data, apn_name: event.target.value});\r\n }}/>\r\n )\r\n else\r\n return (\r\n \r\n {data.apn_name}\r\n \r\n )\r\n\r\n }\r\n\r\n const renderUserField = () => {\r\n if (editMode === true)\r\n return (\r\n {\r\n setData({...data, apn_user: event.target.value});\r\n }}/>\r\n )\r\n else\r\n return(\r\n \r\n {data.apn_user}\r\n \r\n )\r\n }\r\n\r\n const renderPasswordField = () =>{\r\n let Password_Chars = \"\";\r\n if (editMode === true)\r\n return (\r\n {\r\n setData({...data, apn_pwd: event.target.value});\r\n }}/>\r\n )\r\n else\r\n Password_Chars=\"\";\r\n for(let index = 0;index\r\n {Password_Chars}\r\n \r\n )\r\n }\r\n\r\n const renderICCIDField = () => {\r\n return(\r\n \r\n {data.iccid ? data.iccid : ResourceLang.not_applicable}\r\n \r\n )\r\n }\r\n\r\n const renderCurrentIPField = () => {\r\n return(\r\n \r\n {data.current_ip ? data.current_ip : ResourceLang.not_applicable}\r\n \r\n )\r\n }\r\n\r\n const renderDialogApplyTo = () =>{\r\n var UpdateData = []\r\n UpdateData.push(data)\r\n return( setApplyToDialog(false)}\r\n settingsType={SETTINGS_TYPE_ENUM.APN}\r\n envId={envId}\r\n deviceItemId={deviceItemId}\r\n dataToBeUpdated={UpdateData}/>\r\n )\r\n }\r\n\r\n const enableDialogApplyTo = () =>{\r\n setApplyToDialog(true)\r\n }\r\n\r\n const renderPanelFields = () => {\r\n return (<>\r\n \r\n \r\n \r\n \r\n {renderNameField()}\r\n \r\n \r\n \r\n \r\n \r\n {renderAuthInput()}\r\n \r\n \r\n \r\n \r\n \r\n {renderICCIDField()}\r\n \r\n \r\n
\r\n \r\n \r\n \r\n \r\n {renderUserField()}\r\n \r\n \r\n \r\n \r\n \r\n {renderPasswordField()}\r\n \r\n \r\n \r\n \r\n \r\n {renderCurrentIPField()}\r\n \r\n \r\n {!editMode ? \r\n \r\n \r\n : null}\r\n \r\n
\r\n >)\r\n }\r\n\r\n const handleSnackbarClose = () =>{\r\n setSnackbar((prevState) => ({...prevState, \r\n open: false, \r\n }));\r\n }\r\n\r\n const renderSnackbar = () => {\r\n return ();\r\n }\r\n\r\n const renderButtons = () => {\r\n if(editMode === false)\r\n return null;\r\n \r\n return(\r\n \r\n {\r\n const formData = new FormData();\r\n formData.append('gprs', JSON.stringify(data));\r\n FirmwareAPI.putGPRSSettingsByDevice(envId, deviceItemId, formData)\r\n .then(response => {\r\n setEditMode(false);\r\n setSnackbar((prevState) => ({...prevState, \r\n open: true,\r\n variant: \"success\",\r\n message: ResourceLang.update_with_success\r\n }));\r\n }).catch(error => {\r\n setEditMode(true);\r\n setSnackbar((prevState) => ({...prevState, \r\n open: true,\r\n variant: \"success\",\r\n message: ResourceLang.update_with_success\r\n }));\r\n })\r\n }}>\r\n \r\n {ResourceLang.submit}\r\n \r\n {\r\n setData({...interfaceGPRS});\r\n setEditMode(false);\r\n }}>\r\n \r\n {ResourceLang.cancel}\r\n \r\n \r\n
);\r\n }\r\n \r\n return(\r\n {renderPanelHeader()}\r\n \r\n {renderPanelFields()}\r\n {renderButtons()}\r\n {renderDialogApplyTo()}\r\n {renderSnackbar()}\r\n );\r\n}\r\n\r\n\r\nAPNSettings.propTypes = {\r\n interfaceGPRS: PropTypes.shape({\r\n apn_name: PropTypes.string.isRequired,\r\n apn_auth_type: PropTypes.number.isRequired,\r\n apn_user: PropTypes.string.isRequired,\r\n apn_pwd: PropTypes.string.isRequired,\r\n iccid: PropTypes.string,\r\n current_ip: PropTypes.string\r\n }).isRequired\r\n}\r\n\r\nexport default APNSettings","import React, { useState } from 'react';\r\nimport PropTypes from 'prop-types';\r\nimport ResourceLang from '../../../resources/Language';\r\nimport {FirmwareAPI} from '../../../utils/APIRequester';\r\nimport { OvalButtonPrimary, useStyles as ovalByttonsStyleBase } from '../../../components/buttons/OvalButtons';\r\nimport { CircularButtonTransparent } from '../../../components/buttons/CircularButtons';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport { Row, Col, FormGroup, Label, Input } from 'reactstrap';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { faSignal } from '@fortawesome/free-solid-svg-icons';\r\nimport {SETTINGS_TYPE_ENUM } from '../../../utils/Enums';\r\nimport EditIcon from '@material-ui/icons/Edit';\r\nimport CheckIcon from '@material-ui/icons/Check';\r\nimport CancelIcon from '@material-ui/icons/NotInterested';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Button from '@material-ui/core/Button';\r\nimport Tooltip from '@material-ui/core/Tooltip';\r\nimport Divider from '@material-ui/core/Divider';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport DeviceSettingsDialog from '../../../components/dialogs/add/DeviceSettingsDialog';\r\nimport MessageSnackbar from '../../../components/notifications/MessageSnackbar';\r\n\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n paper: {\r\n padding: theme.spacing(3),\r\n margin: theme.spacing(1),\r\n },\r\n button: {\r\n margin: theme.spacing(1),\r\n float:'right'\r\n },\r\n label_title: {\r\n color: \"#94A3A7\",\r\n fontWeight: 'bold',\r\n marginBottom: theme.spacing(0)\r\n },\r\n divider:{\r\n marginTop: theme.spacing(2),\r\n marginBottom: theme.spacing(1),\r\n }\r\n}));\r\n\r\n\r\nconst NTPSettings = ({\r\n envId, interfaceNTP, deviceItemId\r\n}) => {\r\n const classes = useStyles();\r\n const ovalButtonsStyle = ovalByttonsStyleBase();\r\n const [editMode, setEditMode] = useState(false);\r\n const [openApplyToDialog, setApplyToDialog] = useState(false);\r\n const [data, setData] = useState(interfaceNTP);\r\n const [ snackbar, setSnackbar] = useState({ open: false, variant: 'error', message: ''});\r\n \r\n const readOnly = editMode ? '' : 'readonly';\r\n \r\n const handleEditClick = () => {\r\n setEditMode(!editMode);\r\n }\r\n\r\n const renderPanelHeader = () => {\r\n return (\r\n \r\n \r\n {ResourceLang.ntp_settings} \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
);\r\n }\r\n\r\n const renderTimeServerType = () => {\r\n const TIMESERVER_OPTIONS = [\r\n {label: ResourceLang.ntp, value: 0},\r\n {label: ResourceLang.htp, value: 1},\r\n {label: ResourceLang.deepgrid, value: 2}\r\n ]\r\n\r\n if(editMode) {\r\n return({\r\n const value = parseInt(event.target.value, 10);\r\n setData({...data, timeserver_type: value});\r\n }}>\r\n {\r\n TIMESERVER_OPTIONS.map(({value, label}) => \r\n \r\n )\r\n }\r\n );\r\n }\r\n else{\r\n let value = ResourceLang.NONE;\r\n if (data.timeserver_type !== undefined) {\r\n const target = TIMESERVER_OPTIONS.find(x => x.value === data.timeserver_type);\r\n if (target)\r\n value = target.label;\r\n }\r\n return(\r\n \r\n {value}\r\n \r\n );\r\n }\r\n }\r\n\r\n const renderTimeServerURL = () => {\r\n if (editMode === true)\r\n return (\r\n {\r\n setData({...data, timeserver_url: event.target.value});\r\n }}/>\r\n )\r\n else{\r\n if(data.timeserver_url){\r\n return (\r\n \r\n {data.timeserver_url}\r\n \r\n )\r\n }\r\n else{\r\n \r\n {ResourceLang.not_applicable}\r\n \r\n }\r\n \r\n }\r\n }\r\n\r\n const renderTimeServerPort = () => {\r\n if (editMode === true)\r\n return (\r\n {\r\n setData({...data, timeserver_port: event.target.value});\r\n }}/>\r\n )\r\n else {\r\n if(data.timeserver_port){\r\n return(\r\n \r\n {data.timeserver_port}\r\n \r\n )\r\n }\r\n else{\r\n return(\r\n \r\n {ResourceLang.not_applicable}\r\n \r\n )\r\n }\r\n }\r\n }\r\n\r\n const renderTimeServerProtocol = () =>{\r\n if (editMode === true)\r\n return (\r\n {\r\n setData({...data, timeserver_protocol: event.target.value});\r\n }}/>\r\n )\r\n else{\r\n if(data.timeserver_protocol){\r\n return(\r\n \r\n {data.timeserver_protocol}\r\n \r\n )\r\n }\r\n else{\r\n return(\r\n \r\n {ResourceLang.not_applicable}\r\n \r\n )\r\n }\r\n } \r\n }\r\n\r\n const renderDialogApplyTo = () =>{\r\n var UpdateData = []\r\n UpdateData.push(data)\r\n return( setApplyToDialog(false)}\r\n settingsType={SETTINGS_TYPE_ENUM.NTP}\r\n envId={envId}\r\n deviceItemId={deviceItemId}\r\n dataToBeUpdated={UpdateData}/>\r\n )\r\n }\r\n\r\n const enableDialogApplyTo = () =>{\r\n setApplyToDialog(true)\r\n }\r\n\r\n const renderPanelFields = () => {\r\n return (<>\r\n \r\n \r\n \r\n \r\n {renderTimeServerURL()}\r\n \r\n \r\n \r\n \r\n \r\n {renderTimeServerPort()}\r\n \r\n \r\n
\r\n \r\n \r\n \r\n \r\n {renderTimeServerType()}\r\n \r\n \r\n \r\n \r\n \r\n {renderTimeServerProtocol()}\r\n \r\n \r\n {!editMode ? \r\n \r\n \r\n : null}\r\n
\r\n \r\n >)\r\n }\r\n\r\n const handleSnackbarClose = () =>{\r\n setSnackbar((prevState) => ({...prevState, \r\n open: false, \r\n }));\r\n }\r\n\r\n const renderSnackbar = () => {\r\n return ();\r\n }\r\n\r\n const renderButtons = () => {\r\n if(editMode === false)\r\n return null;\r\n \r\n return(\r\n \r\n {\r\n const formData = new FormData();\r\n formData.append('ntp', JSON.stringify(data));\r\n FirmwareAPI.putNTPSettingsByDevice(envId, deviceItemId ,formData)\r\n .then(response => {\r\n setEditMode(false);\r\n setSnackbar((prevState) => ({...prevState, \r\n open: true,\r\n variant: \"success\",\r\n message: ResourceLang.update_with_success\r\n }));\r\n }).catch(error => {\r\n setEditMode(true);\r\n setSnackbar((prevState) => ({...prevState, \r\n open: true, \r\n variant: \"error\",\r\n message: ResourceLang.generic_error\r\n }));\r\n })\r\n }}>\r\n \r\n {ResourceLang.submit}\r\n \r\n {\r\n setData({...interfaceNTP});\r\n setEditMode(false);\r\n }}>\r\n \r\n {ResourceLang.cancel}\r\n \r\n \r\n
);\r\n }\r\n\r\n\r\n return(\r\n {renderPanelHeader()}\r\n \r\n {renderPanelFields()}\r\n {renderButtons()}\r\n {renderDialogApplyTo()}\r\n {renderSnackbar()}\r\n );\r\n}\r\n\r\n\r\nNTPSettings.propTypes = {\r\n interfaceNTP: PropTypes.shape({\r\n timeserver_url: PropTypes.string.isRequired,\r\n timeserver_port: PropTypes.number.isRequired,\r\n timeserver_protocol: PropTypes.string.isRequired,\r\n timeserver_type: PropTypes.number.isRequired\r\n }).isRequired\r\n}\r\n\r\nexport default NTPSettings;","import React , {useState, useEffect} from 'react'\r\nimport { withRouter } from \"react-router\";\r\nimport Toolbar from '@material-ui/core/Toolbar';\r\nimport { makeStyles } from '@material-ui/core/styles';\r\nimport ResourceLang from '../../resources/Language';\r\nimport MemoryIcon from '@material-ui/icons/Memory';\r\nimport {FirmwareAPI} from '../../utils/APIRequester';\r\nimport PageLoading from '../../components/loadings/PageLoading';\r\nimport { handleBodyResize } from '../../utils/BrowserServices';\r\nimport { Paper, Grid, Typography } from '@material-ui/core';\r\nimport APNSettings from './settings/APNSettingsPage';\r\nimport NTPSettings from './settings/NTPSettingsPage'; \r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n root: {\r\n width: '100%',\r\n height: '100%',\r\n },\r\n paper: {\r\n width: '100%',\r\n height: '100%',\r\n overflow: 'auto'\r\n },\r\n button: {\r\n margin: theme.spacing(1),\r\n float:'right'\r\n },\r\n headerTitle: {\r\n flexGrow: 1,\r\n marginLeft: theme.spacing(2)\r\n },\r\n tableContainer: {\r\n marginLeft: theme.spacing(1),\r\n marginRight: theme.spacing(1),\r\n },\r\n toolbar: {\r\n marginLeft: theme.spacing(2),\r\n marginRight: theme.spacing(1),\r\n },\r\n chip: {\r\n margin: theme.spacing(0.5),\r\n },\r\n}));\r\n\r\n\r\nconst EditDevicePage = ({match, location, history, ...props}) => {\r\n const classes = useStyles();\r\n const [state, setState] = useState({\r\n selected: undefined,\r\n deviceItem: undefined\r\n })\r\n\r\n const envId = match.params.envId;\r\n console.log(match.params)\r\n const deviceId = match.params.deviceId;\r\n \r\n useEffect(() => {\r\n if(!state.deviceItem)\r\n {\r\n FirmwareAPI.getGPRSSettingsByDevice(envId, deviceId).then(response => {\r\n setState((prevState) => ({\r\n ...prevState,\r\n deviceItem: response\r\n }));\r\n }).catch(error => {\r\n setState((prevState) => ({\r\n ...prevState, deviceItem: []\r\n }));\r\n })\r\n }\r\n\r\n window.addEventListener('resize', handleBodyResize, true);\r\n return () => {\r\n window.removeEventListener('resize', handleBodyResize, true);\r\n }\r\n }, [state.deviceItem, deviceId, envId]);\r\n\r\n handleBodyResize();\r\n const HEADER_HEIGHT = 64;\r\n const TOP_OFFSET = HEADER_HEIGHT;\r\n const renderPageHeader = () => {\r\n if(state.deviceItem !== undefined && state.deviceItem.devices)\r\n return(\r\n \r\n \r\n \r\n {ResourceLang.device} - {state.deviceItem.devices[0].serial_number}\r\n \r\n \r\n );\r\n }\r\n\r\n function getInterfaceGprs(interfaceItem){\r\n var interface_gprs={}\r\n interface_gprs.apn_name = interfaceItem.apn_name\r\n interface_gprs.apn_auth_type = interfaceItem.apn_auth_type\r\n interface_gprs.apn_user = interfaceItem.apn_user\r\n interface_gprs.apn_pwd = interfaceItem.apn_pwd\r\n interface_gprs.iccid = interfaceItem.iccid\r\n interface_gprs.current_ip = interfaceItem.current_ip\r\n return interface_gprs\r\n }\r\n\r\n function getInterfaceNTP(interfaceItem){\r\n var interface_ntp = {}\r\n interface_ntp.timeserver_url = interfaceItem.timeserver_url\r\n interface_ntp.timeserver_port = interfaceItem.timeserver_port\r\n interface_ntp.timeserver_protocol = interfaceItem.timeserver_protocol\r\n interface_ntp.timeserver_type = interfaceItem.timeserver_type\r\n return interface_ntp\r\n }\r\n\r\n const renderSettings = () =>{\r\n if(state.deviceItem !== undefined) {\r\n return(\r\n \r\n \r\n \r\n \r\n )\r\n }\r\n else{\r\n return<>>\r\n }\r\n }\r\n\r\n return(\r\n
\r\n \r\n \r\n {renderPageHeader()}\r\n \r\n \r\n \r\n {renderSettings()}\r\n \r\n \r\n {!state.deviceItem ?
: null}\r\n
);\r\n\r\n}\r\n\r\nexport default withRouter(EditDevicePage);\r\n","import React from 'react';\r\nimport { Route, Redirect } from \"react-router\";\r\nimport { connect } from 'react-redux';\r\nimport { setLoggedUser, SetUserData} from '../redux/actions/UserActions';\r\nimport SessionServices from '../utils/SessionServices';\r\nimport NavBar from '../components/navigation/NavBar';\r\nimport DashboardPage from '../pages/DashboardPage';\r\nimport EnvironmentPage from '../pages/EnvironmentPage';\r\nimport UploadFirmwarePage from '../pages/UploadFirmwarePage';\r\nimport UpdateFirmwarePage from '../pages/UpdateFirmwarePage';\r\nimport DevicePage from '../pages/devices/ListDevicePage';\r\nimport EditDevicePage from '../pages/devices/EditDevicePage';\r\n\r\nconst ProtectedRoutes = (props) => {\r\n const {isLoggedIn} = props;\r\n const {location} = props;\r\n\r\n const renderRoutes = () => {\r\n if (isLoggedIn) {\r\n return(<>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n >);\r\n }\r\n else {\r\n\r\n if (location && location.pathname) {\r\n const isLoginRoute = (location.pathname.toLowerCase().indexOf('login') >= 0);\r\n\r\n if (!isLoginRoute)\r\n SessionServices.saveRedirectTo(location.pathname);\r\n }\r\n\r\n return ;\r\n }\r\n };\r\n\r\n return(\r\n renderRoutes()\r\n )\r\n}\r\n\r\n\r\nconst mapStateToProps = (state, ownProps) => {\r\n return {\r\n isLoggedIn: state.userStatus,\r\n userData: state.userData\r\n }\r\n}\r\n\r\nconst mapDispatchToProps = (dispatch) => {\r\n return {\r\n setUserinStore: (user) => dispatch(setLoggedUser(user)),\r\n setUserData:(user) => dispatch(SetUserData(user)),\r\n };\r\n};\r\n\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(ProtectedRoutes);\r\n","import React from 'react';\r\nimport { Router, Switch, Route } from \"react-router\";\r\nimport LoginPage from '../pages/LoginPage';\r\nimport { createBrowserHistory } from 'history';\r\nimport ScrollToTop from './ScrollToTop';\r\nimport ProtectedRoutes from './ProtectedRoutes';\r\n\r\nconst history = createBrowserHistory();\r\n\r\nconst Routes = () => {\r\n return (\r\n \r\n \r\n \r\n } />\r\n \r\n \r\n \r\n \r\n );\r\n}\r\n\r\nexport default Routes","import React, {Component} from 'react';\r\nimport { Provider } from 'react-redux';\r\nimport { IntlProvider } from 'react-intl';\r\nimport storage from 'redux-persist/lib/storage';\r\nimport { createStore, applyMiddleware, compose } from 'redux';\r\nimport thunk from 'redux-thunk';\r\nimport { persistStore, persistReducer } from 'redux-persist';\r\nimport rootReducer from '../reducers/index';\r\nimport Routes from '../../routes/Routes';\r\n\r\nconst language=\"pt-PT\";\r\n\r\nconst persistConfig = {\r\n key: 'root',\r\n storage: storage,\r\n};\r\n\r\nconst persistedReducer = persistReducer(persistConfig, rootReducer);\r\nconst composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;\r\nexport const store = createStore(persistedReducer, {}, composeEnhancers(applyMiddleware(thunk)));\r\n\r\nexport var persistor;\r\nexport default class AppProvider extends Component {\r\n\r\n constructor() {\r\n super()\r\n this.state = { rehydrated: false }\r\n }\r\n\r\n componentDidMount(){\r\n\r\n window.addEventListener(\"click\", this.handleInteraction)\r\n window.addEventListener(\"mousemove\", this.handleInteraction)\r\n window.addEventListener(\"keypress\", this.handleInteraction)\r\n\r\n persistor = persistStore(store, {}, () => {\r\n this.setState({ rehydrated: true });\r\n });\r\n\r\n }\r\n\r\n handleInteraction = () =>{\r\n localStorage.lastInteraction = new Date().getTime();\r\n }\r\n\r\n componentWillUnmount(){\r\n window.removeEventListener(\"click\", this.handleInteraction)\r\n window.removeEventListener(\"mousemove\", this.handleInteraction)\r\n window.removeEventListener(\"keypress\", this.handleInteraction)\r\n }\r\n\r\n\r\n render() {\r\n if(!this.state.rehydrated){\r\n return (Loading...
);\r\n }\r\n else{\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n )\r\n }\r\n }\r\n}\r\n\r\n","import { createMuiTheme } from '@material-ui/core/styles';\r\n\r\n//see https://github.com/mui-org/material-ui/tree/master/packages/material-ui/src/styles\r\nexport const MuiTheme = createMuiTheme({\r\n palette: {\r\n primary: {\r\n main: '#2C4153',\r\n },\r\n secondary: {\r\n main: '#F1C419',\r\n },\r\n },\r\n});","import React from 'react';\r\nimport CacheBuster from './utils/CacheBuster';\r\nimport AppProvider from './redux/store/AppProvider';\r\nimport { ThemeProvider } from '@material-ui/core/styles';\r\nimport { MuiTheme } from './components/themes/MuiTheme';\r\n\r\n\r\nfunction App() {\r\n return(\r\n {({ loading, isLatestVersion, refreshCacheAndReload }) => {\r\n if (loading)\r\n return null;\r\n\r\n if (!loading && !isLatestVersion) {\r\n // You can decide how and when you want to force reload\r\n refreshCacheAndReload();\r\n }\r\n\r\n return (\r\n \r\n \r\n );\r\n }}\r\n );\r\n}\r\n\r\nexport default App;\r\n","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport './resources/css/index.css';\r\nimport 'bootstrap/dist/css/bootstrap.min.css';\r\nimport App from './App';\r\n\r\nReactDOM.render(, document.getElementById('root'));\r\n"],"sourceRoot":""}