diff --git a/src/components/DeviceCommands.js b/src/components/DeviceCommands.js new file mode 100644 index 0000000..73d5780 --- /dev/null +++ b/src/components/DeviceCommands.js @@ -0,0 +1,183 @@ +/* eslint-disable-rule prefer-destructuring */ +import React, { useState, useEffect } from 'react'; +import { + CWidgetDropdown, + CRow, + CCol, + CCollapse, + CButton, + CDataTable, + CCard, + CCardBody, +} from '@coreui/react'; +import CIcon from '@coreui/icons-react'; +import { useSelector } from 'react-redux'; +import DatePicker from 'react-widgets/DatePicker'; +import { cleanTimestamp, addDays } from '../utils/helper'; +import axiosInstance from '../utils/axiosInstance'; +import { getToken } from '../utils/authHelper'; + +const DeviceCommands = () => { + const [collapse, setCollapse] = useState(false); + const [details, setDetails] = useState([]); + const [commands, setCommands] = useState([]); + const [loading, setLoading] = useState(false); + const [start, setStart] = useState(addDays(new Date(), -3).toString()); + const [end, setEnd] = useState(new Date().toString()); + const selectedDeviceId = useSelector((state) => state.selectedDeviceId); + + const toggle = (e) => { + setCollapse(!collapse); + e.preventDefault(); + }; + + const getCommands = () => { + setLoading(true); + const utcStart = new Date(start).toISOString(); + const utcEnd = new Date(end).toISOString(); + + const options = { + headers: { + Accept: 'application/json', + Authorization: `Bearer ${getToken()}`, + }, + params: { + startDate: utcStart, + endDate: utcEnd, + }, + }; + + axiosInstance + .get(`/commands?serialNumber=${selectedDeviceId}`, options) + .then((response) => { + setCommands(response.data.commands); + }) + .catch((error) => { + console.log(error); + console.log(error.response); + }) + .finally(() => { + setLoading(false); + }); + }; + + const toggleDetails = (index) => { + const position = details.indexOf(index); + let newDetails = details.slice(); + + if (position !== -1) { + newDetails.splice(position, 1); + } else { + newDetails = [...details, index]; + } + setDetails(newDetails); + }; + + const columns = [ + { key: 'UUID', label: 'Id' }, + { key: 'command' }, + { key: 'completed' }, + { + key: 'show_details', + label: '', + _style: { width: '1%' }, + sorter: false, + filter: false, + }, + ]; + + useEffect(() => { + getCommands(); + setStart(addDays(new Date(), -3).toString()); + setEnd(new Date().toString()); + }, []); + + useEffect(() => { + getCommands(); + }, [start, end]); + + return ( + + + + + setStart(date)} + /> + + + setEnd(date)} + /> + + + +
+ {cleanTimestamp(item.completed)}, + show_details: (item, index) => ( + + { + toggleDetails(index); + }} + > + {details.includes(index) ? 'Hide' : 'Show'} + + + ), + details: (item, index) => ( + + +
Details
+
+
{JSON.stringify(item.details, null, 4)}
+
+
+
+ ), + }} + /> +
+
+
+ + + + + } + > + +
+ ); +}; + +export default DeviceCommands; diff --git a/src/components/DeviceHealth.js b/src/components/DeviceHealth.js index 734beeb..b31a9f8 100644 --- a/src/components/DeviceHealth.js +++ b/src/components/DeviceHealth.js @@ -1,6 +1,15 @@ /* eslint-disable-rule prefer-destructuring */ import React, { useState, useEffect } from 'react'; -import { CWidgetProgress, CCollapse, CButton, CDataTable, CCard, CCardBody, CRow, CCol } from '@coreui/react'; +import { + CWidgetProgress, + CCollapse, + CButton, + CDataTable, + CCard, + CCardBody, + CRow, + CCol, +} from '@coreui/react'; import CIcon from '@coreui/icons-react'; import { useSelector } from 'react-redux'; import DatePicker from 'react-widgets/DatePicker'; @@ -11,6 +20,7 @@ import { getToken } from '../utils/authHelper'; const DeviceHealth = () => { const [collapse, setCollapse] = useState(false); const [details, setDetails] = useState([]); + const [loading, setLoading] = useState(false); const [healthChecks, setHealthChecks] = useState([]); const [start, setStart] = useState(addDays(new Date(), -3).toString()); const [end, setEnd] = useState(new Date().toString()); @@ -24,6 +34,7 @@ const DeviceHealth = () => { }; const getDeviceHealth = () => { + setLoading(true); const utcStart = new Date(start).toISOString(); const utcEnd = new Date(end).toISOString(); @@ -32,10 +43,10 @@ const DeviceHealth = () => { Accept: 'application/json', Authorization: `Bearer ${getToken()}`, }, - params : { + params: { startDate: utcStart, - endDate: utcEnd - } + endDate: utcEnd, + }, }; axiosInstance @@ -46,6 +57,9 @@ const DeviceHealth = () => { .catch((error) => { console.log(error); console.log(error.response); + }) + .finally(() => { + setLoading(false); }); }; @@ -80,7 +94,7 @@ const DeviceHealth = () => { setStart(addDays(new Date(), -3).toString()); setEnd(new Date().toString()); }, []); - + useEffect(() => { getDeviceHealth(); }, [start, end]); @@ -102,15 +116,15 @@ const DeviceHealth = () => { footer={
- + setStart(date)} - /> + selected={start === '' ? new Date() : new Date(start)} + value={start === '' ? new Date() : new Date(start)} + includeTime + selectTime + onChange={(date) => setStart(date)} + /> { items={healthChecks ?? []} fields={columns} style={{ color: 'white' }} + loading={loading} + border sorterValue={{ column: 'recorded', desc: 'true' }} scopedSlots={{ recorded: (item) => {cleanTimestamp(item.recorded)}, diff --git a/src/components/DeviceList.js b/src/components/DeviceList.js index 6ba29c2..02e08ed 100644 --- a/src/components/DeviceList.js +++ b/src/components/DeviceList.js @@ -187,7 +187,7 @@ const DeviceListDisplay = ({ devices, loading, updateDevicesPerPage, pageCount, { + const [collapse, setCollapse] = useState(false); + const [details, setDetails] = useState([]); + const [loading, setLoading] = useState(false); + const [logs, setLogs] = useState([]); + const [start, setStart] = useState(addDays(new Date(), -3).toString()); + const [end, setEnd] = useState(new Date().toString()); + const selectedDeviceId = useSelector((state) => state.selectedDeviceId); + + const toggle = (e) => { + setCollapse(!collapse); + e.preventDefault(); + }; + + const getLogs = () => { + setLoading(true); + const utcStart = new Date(start).toISOString(); + const utcEnd = new Date(end).toISOString(); + + const options = { + headers: { + Accept: 'application/json', + Authorization: `Bearer ${getToken()}`, + }, + params: { + startDate: utcStart, + endDate: utcEnd, + }, + }; + + axiosInstance + .get(`/device/${selectedDeviceId}/logs`, options) + .then((response) => { + setLogs(response.data.values); + }) + .catch((error) => { + console.log(error); + console.log(error.response); + }) + .finally(() => { + setLoading(false); + }); + }; + + const toggleDetails = (index) => { + const position = details.indexOf(index); + let newDetails = details.slice(); + + if (position !== -1) { + newDetails.splice(position, 1); + } else { + newDetails = [...details, index]; + } + setDetails(newDetails); + }; + + const columns = [ + { key: 'log' }, + { key: 'severity' }, + { key: 'recorded' }, + { + key: 'show_details', + label: '', + _style: { width: '1%' }, + sorter: false, + filter: false, + }, + ]; + + useEffect(() => { + getLogs(); + setStart(addDays(new Date(), -3).toString()); + setEnd(new Date().toString()); + }, []); + + useEffect(() => { + getLogs(); + }, [start, end]); + + return ( + + + + + setStart(date)} + /> + + + setEnd(date)} + /> + + + +
+ {cleanTimestamp(item.recorded)}, + show_details: (item, index) => ( + + { + toggleDetails(index); + }} + > + {details.includes(index) ? 'Hide' : 'Show'} + + + ), + details: (item, index) => ( + + +
Details
+
+
{JSON.stringify(item, null, 4)}
+
+
+
+ ), + }} + /> +
+
+
+ + + +
+ } + > + + + ); +}; + +export default DeviceLogs; diff --git a/src/components/FirmwareUpgradeModal.js b/src/components/FirmwareUpgradeModal.js index 3d940dc..eb4a91e 100644 --- a/src/components/FirmwareUpgradeModal.js +++ b/src/components/FirmwareUpgradeModal.js @@ -39,9 +39,9 @@ const FirmwareUpgradeModal = ({ show, toggleModal }) => { valid = false; } - if (chosenDate.trim() === ''){ + if (chosenDate.trim() === '') { setValidDate(false); - valid = false + valid = false; } return valid; }; @@ -105,7 +105,7 @@ const FirmwareUpgradeModal = ({ show, toggleModal }) => { const parameters = { serialNumber: selectedDeviceId, - when: utcDateString, + when: utcDateString, uri: firmware, }; axiosInstance @@ -163,9 +163,7 @@ const FirmwareUpgradeModal = ({ show, toggleModal }) => { You need a date... -
- Firmware URI: -
+
Firmware URI:
{ const newDate = new Date(date); newDate.setDate(date.getDate() + days); return newDate; -} \ No newline at end of file +}; diff --git a/src/views/pages/DevicePage.js b/src/views/pages/DevicePage.js index aa5f516..2545140 100644 --- a/src/views/pages/DevicePage.js +++ b/src/views/pages/DevicePage.js @@ -5,6 +5,8 @@ import { CRow, CCol } from '@coreui/react'; import DeviceHealth from '../../components/DeviceHealth'; import DeviceConfiguration from '../../components/DeviceConfiguration'; import DeviceActions from '../../components/DeviceActions'; +import DeviceCommands from '../../components/DeviceCommands'; +import DeviceLogs from '../../components/DeviceLogs'; const DevicePage = () => { const dispatch = useDispatch(); @@ -27,9 +29,11 @@ const DevicePage = () => {
+ + diff --git a/src/widgets/ActionModalWidget.js b/src/widgets/ActionModalWidget.js index 828d384..a5afb76 100644 --- a/src/widgets/ActionModalWidget.js +++ b/src/widgets/ActionModalWidget.js @@ -9,7 +9,7 @@ import { CBadge, CCol, CRow, - CInvalidFeedback + CInvalidFeedback, } from '@coreui/react'; import React, { useState, useEffect } from 'react'; import DatePicker from 'react-widgets/DatePicker'; @@ -19,14 +19,7 @@ import 'react-widgets/styles.css'; import { getToken } from '../utils/authHelper'; import axiosInstance from '../utils/axiosInstance'; -const ActionModalWidget = ({ - show, - toggleModal, - title, - directions, - action, - extraParameters, -}) => { +const ActionModalWidget = ({ show, toggleModal, title, directions, action, extraParameters }) => { const [hadSuccess, setHadSuccess] = useState(false); const [hadFailure, setHadFailure] = useState(false); const [waiting, setWaiting] = useState(false); @@ -37,7 +30,7 @@ const ActionModalWidget = ({ const selectedDeviceId = useSelector((state) => state.selectedDeviceId); const formValidation = () => { - if(chosenDate === ''){ + if (chosenDate === '') { setValidDate(false); return false; } @@ -89,15 +82,18 @@ const ActionModalWidget = ({ const utcDate = new Date(chosenDate); const utcDateString = utcDate.toISOString(); - const parameters = { ...{ - serialNumber: selectedDeviceId, - when: utcDateString - }, ...extraParameters} + const parameters = { + ...{ + serialNumber: selectedDeviceId, + when: utcDateString, + }, + ...extraParameters, + }; const headers = { Accept: 'application/json', - Authorization: `Bearer ${token}` - } + Authorization: `Bearer ${token}`, + }; axiosInstance .post(`/device/${selectedDeviceId}/${action}`, parameters, { headers })