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 })