diff --git a/package-lock.json b/package-lock.json index 7251cb4..a92a661 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,6 @@ "react-dom": "^17.0.2", "react-i18next": "^11.11.0", "react-paginate": "^7.1.3", - "react-redux": "^7.2.4", "react-router-dom": "^5.2.0", "react-scripts": "^4.0.3", "react-select": "^4.3.1", @@ -3210,15 +3209,6 @@ "@types/node": "*" } }, - "node_modules/@types/hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", - "dependencies": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - } - }, "node_modules/@types/html-minifier-terser": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", @@ -3300,17 +3290,6 @@ "csstype": "^3.0.2" } }, - "node_modules/@types/react-redux": { - "version": "7.1.16", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.16.tgz", - "integrity": "sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw==", - "dependencies": { - "@types/hoist-non-react-statics": "^3.3.0", - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0", - "redux": "^4.0.0" - } - }, "node_modules/@types/react-transition-group": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.1.tgz", @@ -16717,30 +16696,6 @@ "react": "^16.0.0 || ^17.0.0" } }, - "node_modules/react-redux": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.4.tgz", - "integrity": "sha512-hOQ5eOSkEJEXdpIKbnRyl04LhaWabkDPV+Ix97wqQX3T3d2NQ8DUblNXXtNMavc7DpswyQM6xfaN4HQDKNY2JA==", - "dependencies": { - "@babel/runtime": "^7.12.1", - "@types/react-redux": "^7.1.16", - "hoist-non-react-statics": "^3.3.2", - "loose-envify": "^1.4.0", - "prop-types": "^15.7.2", - "react-is": "^16.13.1" - }, - "peerDependencies": { - "react": "^16.8.3 || ^17" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - }, - "react-native": { - "optional": true - } - } - }, "node_modules/react-refresh": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", @@ -24519,15 +24474,6 @@ "@types/node": "*" } }, - "@types/hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", - "requires": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - } - }, "@types/html-minifier-terser": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", @@ -24609,17 +24555,6 @@ "csstype": "^3.0.2" } }, - "@types/react-redux": { - "version": "7.1.16", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.16.tgz", - "integrity": "sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw==", - "requires": { - "@types/hoist-non-react-statics": "^3.3.0", - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0", - "redux": "^4.0.0" - } - }, "@types/react-transition-group": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.1.tgz", @@ -35151,19 +35086,6 @@ "prop-types": "^15.6.1" } }, - "react-redux": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.4.tgz", - "integrity": "sha512-hOQ5eOSkEJEXdpIKbnRyl04LhaWabkDPV+Ix97wqQX3T3d2NQ8DUblNXXtNMavc7DpswyQM6xfaN4HQDKNY2JA==", - "requires": { - "@babel/runtime": "^7.12.1", - "@types/react-redux": "^7.1.16", - "hoist-non-react-statics": "^3.3.2", - "loose-envify": "^1.4.0", - "prop-types": "^15.7.2", - "react-is": "^16.13.1" - } - }, "react-refresh": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", diff --git a/package.json b/package.json index b10918b..6a74b69 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,6 @@ "react-dom": "^17.0.2", "react-i18next": "^11.11.0", "react-paginate": "^7.1.3", - "react-redux": "^7.2.4", "react-router-dom": "^5.2.0", "react-scripts": "^4.0.3", "react-select": "^4.3.1", diff --git a/public/locales/de/translation.json b/public/locales/de/translation.json index 3f34dc2..471edcd 100644 --- a/public/locales/de/translation.json +++ b/public/locales/de/translation.json @@ -195,7 +195,7 @@ "trace": { "choose_network": "Netzwerk auswählen", "directions": "Starten Sie eine Tcpdump auf diesem Geräts für eine bestimmte Dauer oder eine Anzahl von Paketen", - "download_trace": "Klicke hier zum herunterladen", + "download_trace": "Trace-Datei herunterladen", "packets": "Pakete", "title": "Tcpdump", "trace": "Spur", diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index d10ce47..803c3f8 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -195,7 +195,7 @@ "trace": { "choose_network": "Choose network", "directions": "Launch a remote trace of this device for either a specific duration or a number of packets", - "download_trace": "Click here to download", + "download_trace": "Download Trace File", "packets": "Packets", "title": "Trace", "trace": "Trace", diff --git a/public/locales/es/translation.json b/public/locales/es/translation.json index 894d388..ed0248e 100644 --- a/public/locales/es/translation.json +++ b/public/locales/es/translation.json @@ -195,7 +195,7 @@ "trace": { "choose_network": "Elija la red", "directions": "Lanzar un rastreo remoto de este dispositivo por una duración específica o por una cantidad de paquetes", - "download_trace": "Haga click aquí para descargar", + "download_trace": "Descargar archivo de seguimiento", "packets": "Paquetes", "title": "Rastro", "trace": "Rastro", diff --git a/public/locales/fr/translation.json b/public/locales/fr/translation.json index 04b5faa..7d00e6c 100644 --- a/public/locales/fr/translation.json +++ b/public/locales/fr/translation.json @@ -195,7 +195,7 @@ "trace": { "choose_network": "Choisir le réseau", "directions": "Lancer une trace à distance de cet appareil pour une durée spécifique ou un nombre de paquets", - "download_trace": "Cliquez ici pour télécharger", + "download_trace": "Télécharger le fichier de trace", "packets": "Paquets", "title": "Trace", "trace": "Trace", diff --git a/public/locales/pt/translation.json b/public/locales/pt/translation.json index c5641f9..bc0025c 100644 --- a/public/locales/pt/translation.json +++ b/public/locales/pt/translation.json @@ -195,7 +195,7 @@ "trace": { "choose_network": "Escolha a rede", "directions": "Lançar um rastreamento remoto deste dispositivo para uma duração específica ou um número de pacotes", - "download_trace": "Clique aqui para baixar", + "download_trace": "Baixar arquivo de rastreamento", "packets": "Pacotes", "title": "Vestígio", "trace": "Vestígio", diff --git a/src/App.js b/src/App.js index 985f39e..32f0cad 100644 --- a/src/App.js +++ b/src/App.js @@ -1,7 +1,8 @@ -import React, { useEffect } from 'react'; -import { HashRouter, Route, Switch } from 'react-router-dom'; +import React from 'react'; +import { HashRouter, Switch } from 'react-router-dom'; import 'scss/style.scss'; -import { useSelector, useDispatch } from 'react-redux'; +import Router from 'router'; +import { AuthProvider } from 'contexts/AuthProvider'; const loading = (
@@ -9,32 +10,19 @@ const loading = (
); -const TheLayout = React.lazy(() => import('layout')); -const Login = React.lazy(() => import('pages/LoginPage')); - const App = () => { - const isLoggedIn = useSelector((state) => state.connected); - const dispatch = useDispatch(); - - useEffect(() => { - const token = sessionStorage.getItem('access_token'); - if (token !== undefined && token !== null) { - dispatch({ type: 'set', connected: true }); - } - }, [dispatch]); + const storageToken = sessionStorage.getItem('access_token'); return ( - - - - (isLoggedIn ? : )} - /> - - - + + + + + + + + + ); }; diff --git a/src/components/BlinkModal/index.js b/src/components/BlinkModal/index.js index 67937bf..3780f7a 100644 --- a/src/components/BlinkModal/index.js +++ b/src/components/BlinkModal/index.js @@ -16,10 +16,10 @@ import React, { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import DatePicker from 'react-widgets/DatePicker'; import PropTypes from 'prop-types'; -import { useSelector } from 'react-redux'; import { dateToUnix } from 'utils/helper'; import 'react-widgets/styles.css'; -import { getToken } from 'utils/authHelper'; +import { useAuth } from 'contexts/AuthProvider'; +import { useDevice } from 'contexts/DeviceProvider'; import axiosInstance from 'utils/axiosInstance'; import eventBus from 'utils/eventBus'; import SuccessfulActionModalBody from 'components/SuccessfulActionModalBody'; @@ -29,12 +29,13 @@ import styles from './index.module.scss'; const BlinkModal = ({ show, toggleModal }) => { const { t } = useTranslation(); + const { currentToken } = useAuth(); + const { deviceSerialNumber } = useDevice(); const [isNow, setIsNow] = useState(false); const [waiting, setWaiting] = useState(false); const [chosenDate, setChosenDate] = useState(new Date().toString()); const [chosenPattern, setPattern] = useState('on'); const [result, setResult] = useState(null); - const selectedDeviceId = useSelector((state) => state.selectedDeviceId); const toggleNow = () => { setIsNow(!isNow); @@ -57,12 +58,10 @@ const BlinkModal = ({ show, toggleModal }) => { const doAction = () => { setWaiting(true); - - const token = getToken(); const utcDate = new Date(chosenDate); const parameters = { - serialNumber: selectedDeviceId, + serialNumber: deviceSerialNumber, when: isNow ? 0 : dateToUnix(utcDate), pattern: chosenPattern, duration: 30, @@ -70,11 +69,11 @@ const BlinkModal = ({ show, toggleModal }) => { const headers = { Accept: 'application/json', - Authorization: `Bearer ${token}`, + Authorization: `Bearer ${currentToken}`, }; axiosInstance - .post(`/device/${encodeURIComponent(selectedDeviceId)}/leds`, parameters, { headers }) + .post(`/device/${encodeURIComponent(deviceSerialNumber)}/leds`, parameters, { headers }) .then(() => { setResult('success'); }) @@ -102,42 +101,42 @@ const BlinkModal = ({ show, toggleModal }) => { {t('blink.pattern')} - setPattern('on')} inline> - - - {t('common.on')} - - - setPattern('off')} inline> - - - {t('common.off')} - - - setPattern('blink')} inline> - - - {t('blink.blink')} - - + setPattern('on')} inline> + + + {t('common.on')} + + + setPattern('off')} inline> + + + {t('common.off')} + + + setPattern('blink')} inline> + + + {t('blink.blink')} + + diff --git a/src/components/CommandHistory/index.js b/src/components/CommandHistory/index.js index f48fda1..d4bd7d9 100644 --- a/src/components/CommandHistory/index.js +++ b/src/components/CommandHistory/index.js @@ -14,10 +14,10 @@ import { import CIcon from '@coreui/icons-react'; import DatePicker from 'react-widgets/DatePicker'; import { cilCloudDownload, cilSync, cilCalendarCheck } from '@coreui/icons'; -import PropTypes from 'prop-types'; import { prettyDate, dateToUnix } from 'utils/helper'; import axiosInstance from 'utils/axiosInstance'; -import { getToken } from 'utils/authHelper'; +import { useAuth } from 'contexts/AuthProvider'; +import { useDevice } from 'contexts/DeviceProvider'; import eventBus from 'utils/eventBus'; import ConfirmModal from 'components/ConfirmModal'; import LoadingButton from 'components/LoadingButton'; @@ -25,8 +25,10 @@ import WifiScanResultModalWidget from 'components/WifiScanResultModal'; import DeviceCommandsCollapse from './DeviceCommandsCollapse'; import styles from './index.module.scss'; -const DeviceCommands = ({ selectedDeviceId }) => { +const DeviceCommands = () => { const { t } = useTranslation(); + const { currentToken } = useAuth(); + const { deviceSerialNumber } = useDevice(); // Wifiscan result related const [chosenWifiScan, setChosenWifiScan] = useState(null); const [showScanModal, setShowScanModal] = useState(false); @@ -90,7 +92,7 @@ const DeviceCommands = ({ selectedDeviceId }) => { const options = { headers: { Accept: 'application/json', - Authorization: `Bearer ${getToken()}`, + Authorization: `Bearer ${currentToken}`, }, params: { limit: commandLimit, @@ -107,7 +109,10 @@ const DeviceCommands = ({ selectedDeviceId }) => { } axiosInstance - .get(`/commands?serialNumber=${encodeURIComponent(selectedDeviceId)}${extraParams}`, options) + .get( + `/commands?serialNumber=${encodeURIComponent(deviceSerialNumber)}${extraParams}`, + options, + ) .then((response) => { setCommands(response.data.commands); }) @@ -122,13 +127,13 @@ const DeviceCommands = ({ selectedDeviceId }) => { const options = { headers: { Accept: 'application/octet-stream', - Authorization: `Bearer ${getToken()}`, + Authorization: `Bearer ${currentToken}`, }, responseType: 'arraybuffer', }; axiosInstance - .get(`/file/${uuid}?serialNumber=${selectedDeviceId}`, options) + .get(`/file/${uuid}?serialNumber=${deviceSerialNumber}`, options) .then((response) => { const blob = new Blob([response.data], { type: 'application/octet-stream' }); const link = document.createElement('a'); @@ -145,7 +150,7 @@ const DeviceCommands = ({ selectedDeviceId }) => { const options = { headers: { Accept: 'application/json', - Authorization: `Bearer ${getToken()}`, + Authorization: `Bearer ${currentToken}`, }, }; return axiosInstance @@ -231,12 +236,12 @@ const DeviceCommands = ({ selectedDeviceId }) => { ]; useEffect(() => { - if (selectedDeviceId && start !== '' && end !== '') { + if (deviceSerialNumber && start !== '' && end !== '') { getCommands(); - } else if (selectedDeviceId && start === '' && end === '') { + } else if (deviceSerialNumber && start === '' && end === '') { getCommands(); } - }, [selectedDeviceId, start, end]); + }, [deviceSerialNumber, start, end]); useEffect(() => { eventBus.on('actionCompleted', () => refreshCommands()); @@ -247,7 +252,7 @@ const DeviceCommands = ({ selectedDeviceId }) => { }, []); useEffect(() => { - if (selectedDeviceId) { + if (deviceSerialNumber) { setCommandLimit(25); setLoadingMore(false); setShowLoadingMore(true); @@ -255,7 +260,7 @@ const DeviceCommands = ({ selectedDeviceId }) => { setEnd(''); getCommands(); } - }, [selectedDeviceId]); + }, [deviceSerialNumber]); useEffect(() => { if (commandLimit !== 25) { @@ -446,8 +451,4 @@ const DeviceCommands = ({ selectedDeviceId }) => { ); }; -DeviceCommands.propTypes = { - selectedDeviceId: PropTypes.string.isRequired, -}; - export default DeviceCommands; diff --git a/src/components/ConfigureModal/index.js b/src/components/ConfigureModal/index.js index dcb7396..e588d4d 100644 --- a/src/components/ConfigureModal/index.js +++ b/src/components/ConfigureModal/index.js @@ -16,9 +16,9 @@ import { import React, { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import PropTypes from 'prop-types'; -import { useSelector } from 'react-redux'; import 'react-widgets/styles.css'; -import { getToken } from 'utils/authHelper'; +import { useAuth } from 'contexts/AuthProvider'; +import { useDevice } from 'contexts/DeviceProvider'; import { checkIfJson } from 'utils/helper'; import axiosInstance from 'utils/axiosInstance'; import eventBus from 'utils/eventBus'; @@ -27,6 +27,8 @@ import styles from './index.module.scss'; const ConfigureModal = ({ show, toggleModal }) => { const { t } = useTranslation(); + const { currentToken } = useAuth(); + const { deviceSerialNumber } = useDevice(); const [hadSuccess, setHadSuccess] = useState(false); const [hadFailure, setHadFailure] = useState(false); const [doingNow, setDoingNow] = useState(false); @@ -36,7 +38,7 @@ const ConfigureModal = ({ show, toggleModal }) => { const [checkingIfSure, setCheckingIfSure] = useState(false); const [errorJson, setErrorJson] = useState(false); const [inputKey, setInputKey] = useState(0); - const selectedDeviceId = useSelector((state) => state.selectedDeviceId); + let fileReader; const confirmingIfSure = () => { @@ -69,10 +71,8 @@ const ConfigureModal = ({ show, toggleModal }) => { setHadSuccess(false); setWaiting(true); - const token = getToken(); - const parameters = { - serialNumber: selectedDeviceId, + serialNumber: deviceSerialNumber, when: 0, UUID: 1, configuration: JSON.parse(newConfig), @@ -80,11 +80,11 @@ const ConfigureModal = ({ show, toggleModal }) => { const headers = { Accept: 'application/json', - Authorization: `Bearer ${token}`, + Authorization: `Bearer ${currentToken}`, }; axiosInstance - .post(`/device/${encodeURIComponent(selectedDeviceId)}/configure`, parameters, { headers }) + .post(`/device/${encodeURIComponent(deviceSerialNumber)}/configure`, parameters, { headers }) .then(() => { setHadSuccess(true); }) diff --git a/src/components/DeleteLogModal/index.js b/src/components/DeleteLogModal/index.js index 8f2b704..25bc76f 100644 --- a/src/components/DeleteLogModal/index.js +++ b/src/components/DeleteLogModal/index.js @@ -6,12 +6,15 @@ import PropTypes from 'prop-types'; import ConfirmFooter from 'components/ConfirmFooter'; import { dateToUnix } from 'utils/helper'; import axiosInstance from 'utils/axiosInstance'; -import { getToken } from 'utils/authHelper'; +import { useDevice } from 'contexts/DeviceProvider'; +import { useAuth } from 'contexts/AuthProvider'; import eventBus from 'utils/eventBus'; import styles from './index.module.scss'; -const DeleteLogModal = ({ serialNumber, show, toggle, object }) => { +const DeleteLogModal = ({ show, toggle, object }) => { const { t } = useTranslation(); + const { currentToken } = useAuth(); + const { deviceSerialNumber } = useDevice(); const [loading, setLoading] = useState(false); const [maxDate, setMaxDate] = useState(new Date().toString()); @@ -27,14 +30,14 @@ const DeleteLogModal = ({ serialNumber, show, toggle, object }) => { const options = { headers: { Accept: 'application/json', - Authorization: `Bearer ${getToken()}`, + Authorization: `Bearer ${currentToken}`, }, params: { endDate: dateToUnix(maxDate), }, }; return axiosInstance - .delete(`/device/${serialNumber}/${object}`, options) + .delete(`/device/${deviceSerialNumber}/${object}`, options) .then(() => {}) .catch(() => {}) .finally(() => { @@ -94,7 +97,6 @@ DeleteLogModal.propTypes = { show: PropTypes.bool.isRequired, toggle: PropTypes.func.isRequired, object: PropTypes.string.isRequired, - serialNumber: PropTypes.string.isRequired, }; export default DeleteLogModal; diff --git a/src/components/DeviceActionCard/index.js b/src/components/DeviceActionCard/index.js index 93c86a3..f0b17f9 100644 --- a/src/components/DeviceActionCard/index.js +++ b/src/components/DeviceActionCard/index.js @@ -1,9 +1,9 @@ import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; -import PropTypes from 'prop-types'; import { CButton, CCard, CCardHeader, CCardBody, CRow, CCol } from '@coreui/react'; import axiosInstance from 'utils/axiosInstance'; -import { getToken } from 'utils/authHelper'; +import { useAuth } from 'contexts/AuthProvider'; +import { useDevice } from 'contexts/DeviceProvider'; import LoadingButton from 'components/LoadingButton'; import RebootModal from 'components/RebootModal'; import FirmwareUpgradeModal from 'components/FirmwareUpgradeModal'; @@ -15,8 +15,10 @@ import FactoryResetModal from 'components/FactoryResetModal'; import styles from './index.module.scss'; -const DeviceActions = ({ selectedDeviceId }) => { +const DeviceActions = () => { const { t } = useTranslation(); + const { currentToken } = useAuth(); + const { deviceSerialNumber } = useDevice(); const [showRebootModal, setShowRebootModal] = useState(false); const [showBlinkModal, setShowBlinkModal] = useState(false); const [showUpgradeModal, setShowUpgradeModal] = useState(false); @@ -59,12 +61,12 @@ const DeviceActions = ({ selectedDeviceId }) => { const options = { headers: { Accept: 'application/json', - Authorization: `Bearer ${getToken()}`, + Authorization: `Bearer ${currentToken}`, }, }; axiosInstance - .get(`/device/${encodeURIComponent(selectedDeviceId)}/rtty`, options) + .get(`/device/${encodeURIComponent(deviceSerialNumber)}/rtty`, options) .then((response) => { const url = `https://${response.data.server}:${response.data.viewport}/connect/${response.data.connectionId}`; const newWindow = window.open(url, '_blank', 'noopener,noreferrer'); @@ -145,8 +147,4 @@ const DeviceActions = ({ selectedDeviceId }) => { ); }; -DeviceActions.propTypes = { - selectedDeviceId: PropTypes.string.isRequired, -}; - export default DeviceActions; diff --git a/src/components/DeviceConfiguration/index.js b/src/components/DeviceConfiguration/index.js index 8df373d..b448438 100644 --- a/src/components/DeviceConfiguration/index.js +++ b/src/components/DeviceConfiguration/index.js @@ -14,17 +14,19 @@ import { CPopover, } from '@coreui/react'; import CIcon from '@coreui/icons-react'; -import PropTypes from 'prop-types'; import { cilWindowMaximize } from '@coreui/icons'; import { prettyDate } from 'utils/helper'; import axiosInstance from 'utils/axiosInstance'; -import { getToken } from 'utils/authHelper'; +import { useAuth } from 'contexts/AuthProvider'; +import { useDevice } from 'contexts/DeviceProvider'; import CopyToClipboardButton from 'components/CopyToClipboardButton'; import DeviceConfigurationModal from './DeviceConfigurationModal'; import styles from './index.module.scss'; -const DeviceConfiguration = ({ selectedDeviceId }) => { +const DeviceConfiguration = () => { const { t } = useTranslation(); + const { currentToken } = useAuth(); + const { deviceSerialNumber } = useDevice(); const [collapse, setCollapse] = useState(false); const [showModal, setShowModal] = useState(false); const [device, setDevice] = useState(null); @@ -42,12 +44,12 @@ const DeviceConfiguration = ({ selectedDeviceId }) => { const options = { headers: { Accept: 'application/json', - Authorization: `Bearer ${getToken()}`, + Authorization: `Bearer ${currentToken}`, }, }; axiosInstance - .get(`/device/${encodeURIComponent(selectedDeviceId)}`, options) + .get(`/device/${encodeURIComponent(deviceSerialNumber)}`, options) .then((response) => { setDevice(response.data); }) @@ -55,8 +57,8 @@ const DeviceConfiguration = ({ selectedDeviceId }) => { }; useEffect(() => { - if (selectedDeviceId) getDevice(); - }, [selectedDeviceId]); + if (deviceSerialNumber) getDevice(); + }, [deviceSerialNumber]); if (device) { return ( @@ -206,8 +208,4 @@ const DeviceConfiguration = ({ selectedDeviceId }) => { ); }; -DeviceConfiguration.propTypes = { - selectedDeviceId: PropTypes.string.isRequired, -}; - export default DeviceConfiguration; diff --git a/src/components/DeviceHealth/index.js b/src/components/DeviceHealth/index.js index 0d8851e..2743191 100644 --- a/src/components/DeviceHealth/index.js +++ b/src/components/DeviceHealth/index.js @@ -15,17 +15,19 @@ import { import CIcon from '@coreui/icons-react'; import { useTranslation } from 'react-i18next'; import DatePicker from 'react-widgets/DatePicker'; -import PropTypes from 'prop-types'; import { prettyDate, dateToUnix } from 'utils/helper'; +import { useAuth } from 'contexts/AuthProvider'; +import { useDevice } from 'contexts/DeviceProvider'; import axiosInstance from 'utils/axiosInstance'; -import { getToken } from 'utils/authHelper'; import eventBus from 'utils/eventBus'; import LoadingButton from 'components/LoadingButton'; import DeleteLogModal from 'components/DeleteLogModal'; import styles from './index.module.scss'; -const DeviceHealth = ({ selectedDeviceId }) => { +const DeviceHealth = () => { const { t } = useTranslation(); + const { currentToken } = useAuth(); + const { deviceSerialNumber } = useDevice(); const [collapse, setCollapse] = useState(false); const [details, setDetails] = useState([]); const [loading, setLoading] = useState(false); @@ -68,7 +70,7 @@ const DeviceHealth = ({ selectedDeviceId }) => { const options = { headers: { Accept: 'application/json', - Authorization: `Bearer ${getToken()}`, + Authorization: `Bearer ${currentToken}`, }, params: { limit: logLimit, @@ -85,7 +87,7 @@ const DeviceHealth = ({ selectedDeviceId }) => { } axiosInstance - .get(`/device/${encodeURIComponent(selectedDeviceId)}/healthchecks${extraParams}`, options) + .get(`/device/${encodeURIComponent(deviceSerialNumber)}/healthchecks${extraParams}`, options) .then((response) => { setHealthChecks(response.data.values); }) @@ -128,7 +130,7 @@ const DeviceHealth = ({ selectedDeviceId }) => { ]; useEffect(() => { - if (selectedDeviceId) { + if (deviceSerialNumber) { setLogLimit(25); setLoadingMore(false); setShowLoadingMore(true); @@ -136,7 +138,7 @@ const DeviceHealth = ({ selectedDeviceId }) => { setEnd(''); getDeviceHealth(); } - }, [selectedDeviceId]); + }, [deviceSerialNumber]); useEffect(() => { if (logLimit !== 25) { @@ -168,12 +170,12 @@ const DeviceHealth = ({ selectedDeviceId }) => { }, [healthChecks]); useEffect(() => { - if (selectedDeviceId && start !== '' && end !== '') { + if (deviceSerialNumber && start !== '' && end !== '') { getDeviceHealth(); - } else if (selectedDeviceId && start === '' && end === '') { + } else if (deviceSerialNumber && start === '' && end === '') { getDeviceHealth(); } - }, [start, end, selectedDeviceId]); + }, [start, end, deviceSerialNumber]); useEffect(() => { eventBus.on('deletedHealth', () => getDeviceHealth()); @@ -281,7 +283,7 @@ const DeviceHealth = ({ selectedDeviceId }) => { /> { ); }; -DeviceHealth.propTypes = { - selectedDeviceId: PropTypes.string.isRequired, -}; - export default DeviceHealth; diff --git a/src/components/DeviceListTable/index.js b/src/components/DeviceListTable/index.js index dfd36e4..4a74939 100644 --- a/src/components/DeviceListTable/index.js +++ b/src/components/DeviceListTable/index.js @@ -17,7 +17,7 @@ import Select from 'react-select'; import PropTypes from 'prop-types'; import { cilSync, cilInfo, cilBadge, cilBan } from '@coreui/icons'; import CIcon from '@coreui/icons-react'; -import { getToken } from 'utils/authHelper'; +import { useAuth } from 'contexts/AuthProvider'; import axiosInstance from 'utils/axiosInstance'; import { cleanBytesString } from 'utils/helper'; import meshIcon from 'assets/icons/Mesh.png'; @@ -29,6 +29,7 @@ import styles from './index.module.scss'; const DeviceList = () => { const { t } = useTranslation(); + const { currentToken } = useAuth(); const [loadedSerials, setLoadedSerials] = useState(false); const [serialNumbers, setSerialNumbers] = useState([]); const [page, setPage] = useState(0); @@ -38,12 +39,11 @@ const DeviceList = () => { const [loading, setLoading] = useState(true); const getSerialNumbers = () => { - const token = getToken(); setLoading(true); const headers = { Accept: 'application/json', - Authorization: `Bearer ${token}`, + Authorization: `Bearer ${currentToken}`, }; axiosInstance @@ -60,12 +60,11 @@ const DeviceList = () => { }; const getDeviceInformation = () => { - const token = getToken(); setLoading(true); const headers = { Accept: 'application/json', - Authorization: `Bearer ${token}`, + Authorization: `Bearer ${currentToken}`, }; const startIndex = page * devicesPerPage; @@ -89,12 +88,11 @@ const DeviceList = () => { }; const refreshDevice = (serialNumber) => { - const token = getToken(); setLoading(true); const headers = { Accept: 'application/json', - Authorization: `Bearer ${token}`, + Authorization: `Bearer ${currentToken}`, }; axiosInstance diff --git a/src/components/DeviceLogs/index.js b/src/components/DeviceLogs/index.js index 8050f54..e41f71f 100644 --- a/src/components/DeviceLogs/index.js +++ b/src/components/DeviceLogs/index.js @@ -14,17 +14,19 @@ import { import CIcon from '@coreui/icons-react'; import { useTranslation } from 'react-i18next'; import DatePicker from 'react-widgets/DatePicker'; -import PropTypes from 'prop-types'; import { prettyDate, dateToUnix } from 'utils/helper'; import axiosInstance from 'utils/axiosInstance'; -import { getToken } from 'utils/authHelper'; +import { useAuth } from 'contexts/AuthProvider'; +import { useDevice } from 'contexts/DeviceProvider'; import eventBus from 'utils/eventBus'; import LoadingButton from 'components/LoadingButton'; import DeleteLogModal from 'components/DeleteLogModal'; import styles from './index.module.scss'; -const DeviceLogs = ({ selectedDeviceId }) => { +const DeviceLogs = () => { const { t } = useTranslation(); + const { currentToken } = useAuth(); + const { deviceSerialNumber } = useDevice(); const [collapse, setCollapse] = useState(false); const [details, setDetails] = useState([]); const [loading, setLoading] = useState(false); @@ -65,7 +67,7 @@ const DeviceLogs = ({ selectedDeviceId }) => { const options = { headers: { Accept: 'application/json', - Authorization: `Bearer ${getToken()}`, + Authorization: `Bearer ${currentToken}`, }, params: { limit: logLimit, @@ -82,7 +84,7 @@ const DeviceLogs = ({ selectedDeviceId }) => { } axiosInstance - .get(`/device/${encodeURIComponent(selectedDeviceId)}/logs${extraParams}`, options) + .get(`/device/${encodeURIComponent(deviceSerialNumber)}/logs${extraParams}`, options) .then((response) => { setLogs(response.data.values); }) @@ -125,7 +127,7 @@ const DeviceLogs = ({ selectedDeviceId }) => { ]; useEffect(() => { - if (selectedDeviceId) { + if (deviceSerialNumber) { setLogLimit(25); setLoadingMore(false); setShowLoadingMore(true); @@ -133,7 +135,7 @@ const DeviceLogs = ({ selectedDeviceId }) => { setEnd(''); getLogs(); } - }, [selectedDeviceId]); + }, [deviceSerialNumber]); useEffect(() => { if (logLimit !== 25) { @@ -150,12 +152,12 @@ const DeviceLogs = ({ selectedDeviceId }) => { }, [logs]); useEffect(() => { - if (selectedDeviceId && start !== '' && end !== '') { + if (deviceSerialNumber && start !== '' && end !== '') { getLogs(); - } else if (selectedDeviceId && start === '' && end === '') { + } else if (deviceSerialNumber && start === '' && end === '') { getLogs(); } - }, [start, end, selectedDeviceId]); + }, [start, end, deviceSerialNumber]); useEffect(() => { eventBus.on('deletedLogs', () => getLogs()); @@ -258,7 +260,7 @@ const DeviceLogs = ({ selectedDeviceId }) => { } /> { ); }; -DeviceLogs.propTypes = { - selectedDeviceId: PropTypes.string.isRequired, -}; - export default DeviceLogs; diff --git a/src/components/DeviceStatusCard/index.js b/src/components/DeviceStatusCard/index.js index df96a2b..7e151d2 100644 --- a/src/components/DeviceStatusCard/index.js +++ b/src/components/DeviceStatusCard/index.js @@ -13,18 +13,20 @@ import { CSpinner, } from '@coreui/react'; import CIcon from '@coreui/icons-react'; +import { useAuth } from 'contexts/AuthProvider'; +import { useDevice } from 'contexts/DeviceProvider'; import { cilSync } from '@coreui/icons'; import { useTranslation } from 'react-i18next'; -import PropTypes from 'prop-types'; import axiosInstance from 'utils/axiosInstance'; -import { getToken } from 'utils/authHelper'; import { prettyDate, secondsToDetailed } from 'utils/helper'; import MemoryBar from './MemoryBar'; import styles from './index.module.scss'; -const DeviceStatusCard = ({ selectedDeviceId }) => { +const DeviceStatusCard = () => { const { t } = useTranslation(); + const { currentToken } = useAuth(); + const { deviceSerialNumber } = useDevice(); const [lastStats, setLastStats] = useState(null); const [status, setStatus] = useState(null); const [error, setError] = useState(false); @@ -40,16 +42,16 @@ const DeviceStatusCard = ({ selectedDeviceId }) => { const options = { headers: { Accept: 'application/json', - Authorization: `Bearer ${getToken()}`, + Authorization: `Bearer ${currentToken}`, }, }; const lastStatsRequest = axiosInstance.get( - `/device/${encodeURIComponent(selectedDeviceId)}/statistics?lastOnly=true`, + `/device/${encodeURIComponent(deviceSerialNumber)}/statistics?lastOnly=true`, options, ); const statusRequest = axiosInstance.get( - `/device/${encodeURIComponent(selectedDeviceId)}/status`, + `/device/${encodeURIComponent(deviceSerialNumber)}/status`, options, ); @@ -68,8 +70,8 @@ const DeviceStatusCard = ({ selectedDeviceId }) => { useEffect(() => { setError(false); - if (selectedDeviceId) getData(); - }, [selectedDeviceId]); + if (deviceSerialNumber) getData(); + }, [deviceSerialNumber]); if (!error) { return ( @@ -78,7 +80,7 @@ const DeviceStatusCard = ({ selectedDeviceId }) => {
- {t('status.title', { serialNumber: selectedDeviceId })} + {t('status.title', { serialNumber: deviceSerialNumber })}
@@ -152,10 +154,14 @@ const DeviceStatusCard = ({ selectedDeviceId }) => {
{t('status.memory')} : - + @@ -172,7 +178,7 @@ const DeviceStatusCard = ({ selectedDeviceId }) => {
- {t('status.title', { serialNumber: selectedDeviceId })} + {t('status.title', { serialNumber: deviceSerialNumber })}
@@ -186,8 +192,4 @@ const DeviceStatusCard = ({ selectedDeviceId }) => { ); }; -DeviceStatusCard.propTypes = { - selectedDeviceId: PropTypes.string.isRequired, -}; - export default React.memo(DeviceStatusCard); diff --git a/src/components/FactoryResetModal/index.js b/src/components/FactoryResetModal/index.js index 61f09f1..978f0b4 100644 --- a/src/components/FactoryResetModal/index.js +++ b/src/components/FactoryResetModal/index.js @@ -14,15 +14,17 @@ import { import React, { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import PropTypes from 'prop-types'; -import { useSelector } from 'react-redux'; import 'react-widgets/styles.css'; -import { getToken } from 'utils/authHelper'; +import { useAuth } from 'contexts/AuthProvider'; +import { useDevice } from 'contexts/DeviceProvider'; import axiosInstance from 'utils/axiosInstance'; import SuccessfulActionModalBody from 'components/SuccessfulActionModalBody'; import styles from './index.module.scss'; const ConfigureModal = ({ show, toggleModal }) => { const { t } = useTranslation(); + const { currentToken } = useAuth(); + const { deviceSerialNumber } = useDevice(); const [hadSuccess, setHadSuccess] = useState(false); const [hadFailure, setHadFailure] = useState(false); const [doingNow, setDoingNow] = useState(false); @@ -30,7 +32,6 @@ const ConfigureModal = ({ show, toggleModal }) => { const [keepRedirector, setKeepRedirector] = useState(true); const [responseBody, setResponseBody] = useState(''); const [checkingIfSure, setCheckingIfSure] = useState(false); - const selectedDeviceId = useSelector((state) => state.selectedDeviceId); const toggleRedirector = () => { setKeepRedirector(!keepRedirector); @@ -54,17 +55,17 @@ const ConfigureModal = ({ show, toggleModal }) => { setWaiting(true); const parameters = { - serialNumber: selectedDeviceId, + serialNumber: deviceSerialNumber, keepRedirector, }; const headers = { Accept: 'application/json', - Authorization: `Bearer ${getToken()}`, + Authorization: `Bearer ${currentToken}`, }; axiosInstance - .post(`/device/${encodeURIComponent(selectedDeviceId)}/factory`, parameters, { headers }) + .post(`/device/${encodeURIComponent(deviceSerialNumber)}/factory`, parameters, { headers }) .then(() => { setHadSuccess(true); }) diff --git a/src/components/FirmwareUpgradeModal/UpgradeWaitingBody.js b/src/components/FirmwareUpgradeModal/UpgradeWaitingBody.js index b94ad25..4df7abe 100644 --- a/src/components/FirmwareUpgradeModal/UpgradeWaitingBody.js +++ b/src/components/FirmwareUpgradeModal/UpgradeWaitingBody.js @@ -3,11 +3,12 @@ import { useTranslation } from 'react-i18next'; import PropTypes from 'prop-types'; import { CModalBody } from '@coreui/react'; import { v4 as createUuid } from 'uuid'; -import { getToken } from 'utils/authHelper'; +import { useAuth } from 'contexts/AuthProvider'; import axiosInstance from 'utils/axiosInstance'; const UpgradeWaitingBody = ({ serialNumber }) => { const { t } = useTranslation(); + const { currentToken } = useAuth(); const [currentStep, setCurrentStep] = useState(0); const [secondsElapsed, setSecondsElapsed] = useState(0); const [labelsToShow, setLabelsToShow] = useState(['upgrade.command_submitted']); @@ -16,7 +17,7 @@ const UpgradeWaitingBody = ({ serialNumber }) => { const options = { headers: { Accept: 'application/json', - Authorization: `Bearer ${getToken()}`, + Authorization: `Bearer ${currentToken}`, }, }; @@ -30,7 +31,7 @@ const UpgradeWaitingBody = ({ serialNumber }) => { const options = { headers: { Accept: 'application/json', - Authorization: `Bearer ${getToken()}`, + Authorization: `Bearer ${currentToken}`, }, }; diff --git a/src/components/FirmwareUpgradeModal/index.js b/src/components/FirmwareUpgradeModal/index.js index b8ee19b..97b27dc 100644 --- a/src/components/FirmwareUpgradeModal/index.js +++ b/src/components/FirmwareUpgradeModal/index.js @@ -15,10 +15,10 @@ import React, { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import DatePicker from 'react-widgets/DatePicker'; import PropTypes from 'prop-types'; -import { useSelector } from 'react-redux'; import { dateToUnix } from 'utils/helper'; import 'react-widgets/styles.css'; -import { getToken } from 'utils/authHelper'; +import { useAuth } from 'contexts/AuthProvider'; +import { useDevice } from 'contexts/DeviceProvider'; import axiosInstance from 'utils/axiosInstance'; import eventBus from 'utils/eventBus'; import getDeviceConnection from 'utils/deviceHelper'; @@ -28,6 +28,8 @@ import UpgradeWaitingBody from './UpgradeWaitingBody'; const FirmwareUpgradeModal = ({ show, toggleModal }) => { const { t } = useTranslation(); + const { currentToken } = useAuth(); + const { deviceSerialNumber } = useDevice(); const [isNow, setIsNow] = useState(true); const [waitForUpgrade, setWaitForUpgrade] = useState(false); const [date, setDate] = useState(new Date().toString()); @@ -39,7 +41,6 @@ const FirmwareUpgradeModal = ({ show, toggleModal }) => { const [waitingForUpgrade, setWaitingForUpgrade] = useState(false); const [showWaitingConsole, setShowWaitingConsole] = useState(false); const [deviceConnected, setDeviceConnected] = useState(true); - const selectedDeviceId = useSelector((state) => state.selectedDeviceId); const toggleNow = () => { if (isNow) { @@ -81,9 +82,9 @@ const FirmwareUpgradeModal = ({ show, toggleModal }) => { }, [firmware, date]); useEffect(() => { - if (selectedDeviceId !== null && show) { + if (deviceSerialNumber !== null && show) { const asyncGet = async () => { - const isConnected = await getDeviceConnection(selectedDeviceId); + const isConnected = await getDeviceConnection(deviceSerialNumber, currentToken); setDisableWaiting(!isConnected); setDeviceConnected(isConnected); }; @@ -97,17 +98,17 @@ const FirmwareUpgradeModal = ({ show, toggleModal }) => { setBlockFields(true); const headers = { Accept: 'application/json', - Authorization: `Bearer ${getToken()}`, - serialNumber: selectedDeviceId, + Authorization: `Bearer ${currentToken}`, + serialNumber: deviceSerialNumber, }; const parameters = { - serialNumber: selectedDeviceId, + serialNumber: deviceSerialNumber, when: isNow ? 0 : dateToUnix(date), uri: firmware, }; axiosInstance - .post(`/device/${encodeURIComponent(selectedDeviceId)}/upgrade`, parameters, { headers }) + .post(`/device/${encodeURIComponent(deviceSerialNumber)}/upgrade`, parameters, { headers }) .then(() => { if (waitForUpgrade) { setShowWaitingConsole(true); @@ -129,7 +130,7 @@ const FirmwareUpgradeModal = ({ show, toggleModal }) => { {t('upgrade.title')} - + diff --git a/src/components/InterfaceStatistics/LatestStatisticsModal.js b/src/components/InterfaceStatistics/LatestStatisticsModal.js index ae66563..4552554 100644 --- a/src/components/InterfaceStatistics/LatestStatisticsModal.js +++ b/src/components/InterfaceStatistics/LatestStatisticsModal.js @@ -10,23 +10,26 @@ import { import PropTypes from 'prop-types'; import { useTranslation } from 'react-i18next'; import axiosInstance from 'utils/axiosInstance'; -import { getToken } from 'utils/authHelper'; +import { useAuth } from 'contexts/AuthProvider'; +import { useDevice } from 'contexts/DeviceProvider'; import styles from './index.module.scss'; -const LatestStatisticsModal = ({ show, toggle, serialNumber }) => { +const LatestStatisticsModal = ({ show, toggle }) => { const { t } = useTranslation(); + const { currentToken } = useAuth(); + const { deviceSerialNumber } = useDevice(); const [latestStats, setLatestStats] = useState(''); const getLatestStats = () => { const options = { headers: { Accept: 'application/json', - Authorization: `Bearer ${getToken()}`, + Authorization: `Bearer ${currentToken}`, }, }; axiosInstance - .get(`/device/${serialNumber}/statistics?lastOnly=true`, options) + .get(`/device/${deviceSerialNumber}/statistics?lastOnly=true`, options) .then((response) => { setLatestStats(response.data); }) @@ -57,7 +60,6 @@ const LatestStatisticsModal = ({ show, toggle, serialNumber }) => { }; LatestStatisticsModal.propTypes = { - serialNumber: PropTypes.string.isRequired, toggle: PropTypes.func.isRequired, show: PropTypes.bool.isRequired, }; diff --git a/src/components/InterfaceStatistics/StatisticsChartList.js b/src/components/InterfaceStatistics/StatisticsChartList.js index 80b8518..74229a5 100644 --- a/src/components/InterfaceStatistics/StatisticsChartList.js +++ b/src/components/InterfaceStatistics/StatisticsChartList.js @@ -1,15 +1,17 @@ import React, { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; -import PropTypes from 'prop-types'; import { v4 as createUuid } from 'uuid'; import axiosInstance from 'utils/axiosInstance'; -import { getToken } from 'utils/authHelper'; +import { useAuth } from 'contexts/AuthProvider'; +import { useDevice } from 'contexts/DeviceProvider'; import { unixToTime, capitalizeFirstLetter } from 'utils/helper'; import eventBus from 'utils/eventBus'; import DeviceStatisticsChart from './DeviceStatisticsChart'; -const StatisticsChartList = ({ selectedDeviceId }) => { +const StatisticsChartList = () => { const { t } = useTranslation(); + const { currentToken } = useAuth(); + const { deviceSerialNumber } = useDevice(); const [statOptions, setStatOptions] = useState({ interfaceList: [], settings: {}, @@ -118,7 +120,7 @@ const StatisticsChartList = ({ selectedDeviceId }) => { const options = { headers: { Accept: 'application/json', - Authorization: `Bearer ${getToken()}`, + Authorization: `Bearer ${currentToken}`, }, params: { serialNumber: '24f5a207a130', @@ -126,7 +128,7 @@ const StatisticsChartList = ({ selectedDeviceId }) => { }; axiosInstance - .get(`/device/${selectedDeviceId}/statistics?newest=true&limit=50`, options) + .get(`/device/${deviceSerialNumber}/statistics?newest=true&limit=50`, options) .then((response) => { transformIntoDataset(response.data.data); }) @@ -134,10 +136,10 @@ const StatisticsChartList = ({ selectedDeviceId }) => { }; useEffect(() => { - if (selectedDeviceId) { + if (deviceSerialNumber) { getStatistics(); } - }, [selectedDeviceId]); + }, [deviceSerialNumber]); useEffect(() => { eventBus.on('refreshInterfaceStatistics', () => getStatistics()); @@ -173,8 +175,4 @@ const StatisticsChartList = ({ selectedDeviceId }) => { ); }; -StatisticsChartList.propTypes = { - selectedDeviceId: PropTypes.string.isRequired, -}; - export default React.memo(StatisticsChartList); diff --git a/src/components/InterfaceStatistics/index.js b/src/components/InterfaceStatistics/index.js index 644f902..6383de4 100644 --- a/src/components/InterfaceStatistics/index.js +++ b/src/components/InterfaceStatistics/index.js @@ -1,6 +1,5 @@ import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; -import PropTypes from 'prop-types'; import { CDropdown, CDropdownToggle, @@ -19,7 +18,7 @@ import StatisticsChartList from './StatisticsChartList'; import LatestStatisticsModal from './LatestStatisticsModal'; import styles from './index.module.scss'; -const DeviceStatisticsCard = ({ selectedDeviceId }) => { +const DeviceStatisticsCard = () => { const { t } = useTranslation(); const [showLatestModal, setShowLatestModal] = useState(false); @@ -57,20 +56,12 @@ const DeviceStatisticsCard = ({ selectedDeviceId }) => {
- + - + ); }; -DeviceStatisticsCard.propTypes = { - selectedDeviceId: PropTypes.string.isRequired, -}; - export default DeviceStatisticsCard; diff --git a/src/components/RebootModal/index.js b/src/components/RebootModal/index.js index 622084d..3d3175f 100644 --- a/src/components/RebootModal/index.js +++ b/src/components/RebootModal/index.js @@ -13,10 +13,10 @@ import React, { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import DatePicker from 'react-widgets/DatePicker'; import PropTypes from 'prop-types'; -import { useSelector } from 'react-redux'; import { dateToUnix } from 'utils/helper'; import 'react-widgets/styles.css'; -import { getToken } from 'utils/authHelper'; +import { useAuth } from 'contexts/AuthProvider'; +import { useDevice } from 'contexts/DeviceProvider'; import axiosInstance from 'utils/axiosInstance'; import eventBus from 'utils/eventBus'; import LoadingButton from 'components/LoadingButton'; @@ -25,11 +25,12 @@ import styles from './index.module.scss'; const ActionModal = ({ show, toggleModal }) => { const { t } = useTranslation(); + const { currentToken } = useAuth(); + const { deviceSerialNumber } = useDevice(); const [waiting, setWaiting] = useState(false); const [result, setResult] = useState(null); const [chosenDate, setChosenDate] = useState(new Date().toString()); const [isNow, setIsNow] = useState(false); - const selectedDeviceId = useSelector((state) => state.selectedDeviceId); const toggleNow = () => { setIsNow(!isNow); @@ -52,21 +53,20 @@ const ActionModal = ({ show, toggleModal }) => { const doAction = () => { setWaiting(true); - const token = getToken(); const utcDate = new Date(chosenDate); const parameters = { - serialNumber: selectedDeviceId, + serialNumber: deviceSerialNumber, when: isNow ? 0 : dateToUnix(utcDate), }; const headers = { Accept: 'application/json', - Authorization: `Bearer ${token}`, + Authorization: `Bearer ${currentToken}`, }; axiosInstance - .post(`/device/${encodeURIComponent(selectedDeviceId)}/reboot`, parameters, { headers }) + .post(`/device/${encodeURIComponent(deviceSerialNumber)}/reboot`, parameters, { headers }) .then(() => { setResult('success'); }) diff --git a/src/components/TraceModal/WaitingForTraceBody.js b/src/components/TraceModal/WaitingForTraceBody.js index 7195f2e..a472944 100644 --- a/src/components/TraceModal/WaitingForTraceBody.js +++ b/src/components/TraceModal/WaitingForTraceBody.js @@ -2,13 +2,14 @@ import React, { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import PropTypes from 'prop-types'; import { CModalBody, CButton, CSpinner, CModalFooter } from '@coreui/react'; -import { getToken } from 'utils/authHelper'; +import { useAuth } from 'contexts/AuthProvider'; import axiosInstance from 'utils/axiosInstance'; import styles from './index.module.scss'; const WaitingForTraceBody = ({ serialNumber, commandUuid, toggle }) => { const { t } = useTranslation(); + const { currentToken } = useAuth(); const [secondsElapsed, setSecondsElapsed] = useState(0); const [waitingForFile, setWaitingForFile] = useState(true); @@ -16,7 +17,7 @@ const WaitingForTraceBody = ({ serialNumber, commandUuid, toggle }) => { const options = { headers: { Accept: 'application/json', - Authorization: `Bearer ${getToken()}`, + Authorization: `Bearer ${currentToken}`, }, }; @@ -34,7 +35,7 @@ const WaitingForTraceBody = ({ serialNumber, commandUuid, toggle }) => { const options = { headers: { Accept: 'application/octet-stream', - Authorization: `Bearer ${getToken()}`, + Authorization: `Bearer ${currentToken}`, }, responseType: 'arraybuffer', }; diff --git a/src/components/TraceModal/index.js b/src/components/TraceModal/index.js index 1060120..e47875d 100644 --- a/src/components/TraceModal/index.js +++ b/src/components/TraceModal/index.js @@ -17,9 +17,9 @@ import { import React, { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import PropTypes from 'prop-types'; -import { useSelector } from 'react-redux'; import 'react-widgets/styles.css'; -import { getToken } from 'utils/authHelper'; +import { useAuth } from 'contexts/AuthProvider'; +import { useDevice } from 'contexts/DeviceProvider'; import axiosInstance from 'utils/axiosInstance'; import eventBus from 'utils/eventBus'; import getDeviceConnection from 'utils/deviceHelper'; @@ -30,6 +30,8 @@ import styles from './index.module.scss'; const TraceModal = ({ show, toggleModal }) => { const { t } = useTranslation(); + const { currentToken } = useAuth(); + const { deviceSerialNumber } = useDevice(); const [hadSuccess, setHadSuccess] = useState(false); const [hadFailure, setHadFailure] = useState(false); const [blockFields, setBlockFields] = useState(false); @@ -43,8 +45,6 @@ const TraceModal = ({ show, toggleModal }) => { const [waitingForTrace, setWaitingForTrace] = useState(false); const [commandUuid, setCommandUuid] = useState(null); - const selectedDeviceId = useSelector((state) => state.selectedDeviceId); - const toggleWaitForTrace = () => { setWaitForTrace(!waitForTrace); }; @@ -65,10 +65,8 @@ const TraceModal = ({ show, toggleModal }) => { setHadFailure(false); setHadSuccess(false); - const token = getToken(); - const parameters = { - serialNumber: selectedDeviceId, + serialNumber: deviceSerialNumber, when: 0, network: chosenInterface, }; @@ -81,11 +79,11 @@ const TraceModal = ({ show, toggleModal }) => { const headers = { Accept: 'application/json', - Authorization: `Bearer ${token}`, + Authorization: `Bearer ${currentToken}`, }; axiosInstance - .post(`/device/${encodeURIComponent(selectedDeviceId)}/trace`, parameters, { headers }) + .post(`/device/${encodeURIComponent(deviceSerialNumber)}/trace`, parameters, { headers }) .then((response) => { setHadSuccess(true); if (waitForTrace) { @@ -105,9 +103,9 @@ const TraceModal = ({ show, toggleModal }) => { }; useEffect(() => { - if (selectedDeviceId !== null && show) { + if (deviceSerialNumber !== null && show) { const asyncGet = async () => { - const isConnected = await getDeviceConnection(selectedDeviceId); + const isConnected = await getDeviceConnection(deviceSerialNumber, currentToken); setIsDeviceConnected(isConnected); }; asyncGet(); @@ -119,7 +117,7 @@ const TraceModal = ({ show, toggleModal }) => { return ( ); diff --git a/src/components/WifiScanModal/index.js b/src/components/WifiScanModal/index.js index 738285a..fa59949 100644 --- a/src/components/WifiScanModal/index.js +++ b/src/components/WifiScanModal/index.js @@ -13,9 +13,9 @@ import { } from '@coreui/react'; import React, { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; -import { useSelector } from 'react-redux'; import PropTypes from 'prop-types'; -import { getToken } from 'utils/authHelper'; +import { useAuth } from 'contexts/AuthProvider'; +import { useDevice } from 'contexts/DeviceProvider'; import axiosInstance from 'utils/axiosInstance'; import eventBus from 'utils/eventBus'; import LoadingButton from 'components/LoadingButton'; @@ -25,6 +25,8 @@ import styles from './index.module.scss'; const WifiScanModal = ({ show, toggleModal }) => { const { t } = useTranslation(); + const { currentToken } = useAuth(); + const { deviceSerialNumber } = useDevice(); const [hadSuccess, setHadSuccess] = useState(false); const [hadFailure, setHadFailure] = useState(false); const [waiting, setWaiting] = useState(false); @@ -32,7 +34,6 @@ const WifiScanModal = ({ show, toggleModal }) => { const [activeScan, setActiveScan] = useState(false); const [hideOptions, setHideOptions] = useState(false); const [channelList, setChannelList] = useState([]); - const selectedDeviceId = useSelector((state) => state.selectedDeviceId); const toggleVerbose = () => { setVerbose(!choseVerbose); @@ -88,20 +89,18 @@ const WifiScanModal = ({ show, toggleModal }) => { setHadSuccess(false); setWaiting(true); - const token = getToken(); - const parameters = { - serialNumber: selectedDeviceId, + serialNumber: deviceSerialNumber, verbose: choseVerbose, activeScan, }; const headers = { Accept: 'application/json', - Authorization: `Bearer ${token}`, + Authorization: `Bearer ${currentToken}`, }; axiosInstance - .post(`/device/${encodeURIComponent(selectedDeviceId)}/wifiscan`, parameters, { headers }) + .post(`/device/${encodeURIComponent(deviceSerialNumber)}/wifiscan`, parameters, { headers }) .then((response) => { const scanList = response?.data?.results?.status?.scan; diff --git a/src/contexts/AuthProvider/index.js b/src/contexts/AuthProvider/index.js new file mode 100644 index 0000000..195fdba --- /dev/null +++ b/src/contexts/AuthProvider/index.js @@ -0,0 +1,21 @@ +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; + +const AuthContext = React.createContext(); + +export const AuthProvider = ({ token, children }) => { + const [currentToken, setCurrentToken] = useState(token); + + return ( + + {children} + + ); +}; + +AuthProvider.propTypes = { + token: PropTypes.string.isRequired, + children: PropTypes.node.isRequired, +}; + +export const useAuth = () => React.useContext(AuthContext); diff --git a/src/contexts/DeviceProvider/index.js b/src/contexts/DeviceProvider/index.js new file mode 100644 index 0000000..3194d65 --- /dev/null +++ b/src/contexts/DeviceProvider/index.js @@ -0,0 +1,21 @@ +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; + +const DeviceContext = React.createContext(); + +export const DeviceProvider = ({ serialNumber, children }) => { + const [deviceSerialNumber, setDeviceSerialNumber] = useState(serialNumber); + + return ( + + {children} + + ); +}; + +DeviceProvider.propTypes = { + serialNumber: PropTypes.string.isRequired, + children: PropTypes.node.isRequired, +}; + +export const useDevice = () => React.useContext(DeviceContext); diff --git a/src/index.js b/src/index.js index 8f47296..78079d7 100644 --- a/src/index.js +++ b/src/index.js @@ -1,9 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import 'index.css'; -import { Provider } from 'react-redux'; import App from 'App'; -import store from 'store'; import { icons } from 'assets/icons'; import 'i18n'; @@ -11,9 +9,7 @@ React.icons = icons; ReactDOM.render( - - - + , document.getElementById('root'), ); diff --git a/src/layout/Header/index.js b/src/layout/Header/index.js index 19e733f..7dbbbf3 100644 --- a/src/layout/Header/index.js +++ b/src/layout/Header/index.js @@ -1,5 +1,4 @@ import React, { useState, useEffect } from 'react'; -import { useSelector, useDispatch } from 'react-redux'; import { useTranslation } from 'react-i18next'; import { CHeader, @@ -11,26 +10,25 @@ import { CLink, CPopover, } from '@coreui/react'; +import PropTypes from 'prop-types'; import CIcon from '@coreui/icons-react'; import { cilAccountLogout } from '@coreui/icons'; import { logout } from 'utils/authHelper'; import routes from 'routes'; import LanguageSwitcher from 'components/LanguageSwitcher'; -const TheHeader = () => { +const TheHeader = ({ showSidebar, setShowSidebar }) => { const { t, i18n } = useTranslation(); - const dispatch = useDispatch(); const [translatedRoutes, setTranslatedRoutes] = useState(routes); - const sidebarShow = useSelector((state) => state.sidebarShow); const toggleSidebar = () => { - const val = [true, 'responsive'].includes(sidebarShow) ? false : 'responsive'; - dispatch({ type: 'set', sidebarShow: val }); + const val = [true, 'responsive'].includes(showSidebar) ? false : 'responsive'; + setShowSidebar(val); }; const toggleSidebarMobile = () => { - const val = [false, 'responsive'].includes(sidebarShow) ? true : 'responsive'; - dispatch({ type: 'set', sidebarShow: val }); + const val = [false, 'responsive'].includes(showSidebar) ? true : 'responsive'; + setShowSidebar(val); }; useEffect(() => { @@ -69,4 +67,9 @@ const TheHeader = () => { ); }; +TheHeader.propTypes = { + showSidebar: PropTypes.string.isRequired, + setShowSidebar: PropTypes.func.isRequired, +}; + export default TheHeader; diff --git a/src/layout/Sidebar/index.js b/src/layout/Sidebar/index.js index 90b59ab..3a647fd 100644 --- a/src/layout/Sidebar/index.js +++ b/src/layout/Sidebar/index.js @@ -1,5 +1,4 @@ import React from 'react'; -import { useSelector, useDispatch } from 'react-redux'; import { CCreateElement, CSidebar, @@ -11,14 +10,13 @@ import { CSidebarNavDropdown, CSidebarNavItem, } from '@coreui/react'; +import PropTypes from 'prop-types'; import { useTranslation } from 'react-i18next'; import logoBar from 'assets/OpenWiFi_LogoLockup_WhiteColour.svg'; import styles from './index.module.scss'; -const TheSidebar = () => { +const TheSidebar = ({ showSidebar, setShowSidebar }) => { const { t } = useTranslation(); - const dispatch = useDispatch(); - const show = useSelector((state) => state.sidebarShow); const navigation = [ { @@ -30,7 +28,7 @@ const TheSidebar = () => { ]; return ( - dispatch({ type: 'set', sidebarShow: val })}> + setShowSidebar(val)}> { ); }; +TheSidebar.propTypes = { + showSidebar: PropTypes.string.isRequired, + setShowSidebar: PropTypes.func.isRequired, +}; + export default React.memo(TheSidebar); diff --git a/src/layout/index.js b/src/layout/index.js index d5599d8..32de36e 100644 --- a/src/layout/index.js +++ b/src/layout/index.js @@ -1,21 +1,17 @@ -import React from 'react'; -import { useSelector } from 'react-redux'; -import PropTypes from 'prop-types'; +import React, { useState } from 'react'; import TheContent from './Content'; import TheSidebar from './Sidebar'; import TheFooter from './Footer'; import TheHeader from './Header'; -const TheLayout = (props) => { - const { isLoggedIn } = useSelector((state) => state.connected); - if (isLoggedIn) { - return
{props.children}
; - } +const TheLayout = () => { + const [showSidebar, setShowSidebar] = useState('responsive'); + return (
- +
- +
@@ -25,12 +21,4 @@ const TheLayout = (props) => { ); }; -TheLayout.propTypes = { - children: PropTypes.instanceOf(Object), -}; - -TheLayout.defaultProps = { - children: {}, -}; - export default TheLayout; diff --git a/src/pages/DevicePage/index.js b/src/pages/DevicePage/index.js index 293dcf9..01a870f 100644 --- a/src/pages/DevicePage/index.js +++ b/src/pages/DevicePage/index.js @@ -1,5 +1,4 @@ -import React, { useEffect } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import React from 'react'; import { useParams } from 'react-router-dom'; import { CRow, CCol } from '@coreui/react'; import DeviceHealth from 'components/DeviceHealth'; @@ -9,40 +8,33 @@ import DeviceLogs from 'components/DeviceLogs'; import DeviceStatisticsCard from 'components/InterfaceStatistics'; import DeviceActionCard from 'components/DeviceActionCard'; import DeviceStatusCard from 'components/DeviceStatusCard'; +import { DeviceProvider } from 'contexts/DeviceProvider'; const DevicePage = () => { - const dispatch = useDispatch(); - const { deviceId } = useParams(); - const previouslySelectedDeviceId = useSelector((state) => state.selectedDeviceId); - - useEffect(() => { - if (deviceId && deviceId !== previouslySelectedDeviceId) - dispatch({ type: 'set', selectedDeviceId: deviceId }); - }, [deviceId]); return ( - <> -
+
+ - - + + - - - + + + - - + + -
- + +
); }; diff --git a/src/pages/LoginPage/index.js b/src/pages/LoginPage/index.js index a94a0ff..37120f1 100644 --- a/src/pages/LoginPage/index.js +++ b/src/pages/LoginPage/index.js @@ -18,8 +18,8 @@ import { CInvalidFeedback, } from '@coreui/react'; import CIcon from '@coreui/icons-react'; +import { useAuth } from 'contexts/AuthProvider'; import { cilUser, cilLockLocked, cilLink } from '@coreui/icons'; -import { useDispatch } from 'react-redux'; import axiosInstance from 'utils/axiosInstance'; import logo from 'assets/OpenWiFi_LogoLockup_DarkGreyColour.svg'; import LanguageSwitcher from 'components/LanguageSwitcher'; @@ -27,7 +27,7 @@ import styles from './index.module.scss'; const Login = () => { const { t } = useTranslation(); - const dispatch = useDispatch(); + const { setCurrentToken } = useAuth(); const [userId, setUsername] = useState(''); const [password, setPassword] = useState(''); const [gatewayUrl, setGatewayUrl] = useState(''); @@ -87,7 +87,7 @@ const Login = () => { .then((response) => { sessionStorage.setItem('gw_url', `${gatewayUrlToUse}/api/v1`); sessionStorage.setItem('access_token', response.data.access_token); - dispatch({ type: 'set', connected: true }); + setCurrentToken(response.data.access_token); }) .catch(() => { setHadError(true); diff --git a/src/router/index.js b/src/router/index.js new file mode 100644 index 0000000..dae0eda --- /dev/null +++ b/src/router/index.js @@ -0,0 +1,20 @@ +import { useAuth } from 'contexts/AuthProvider'; +import { Route } from 'react-router-dom'; +import React from 'react'; + +const TheLayout = React.lazy(() => import('layout')); +const Login = React.lazy(() => import('pages/LoginPage')); + +const Routes = () => { + const { currentToken } = useAuth(); + + return ( + (currentToken !== '' ? : )} + /> + ); +}; + +export default Routes; diff --git a/src/routes.js b/src/routes.js index 9cf19d4..345e867 100644 --- a/src/routes.js +++ b/src/routes.js @@ -3,9 +3,7 @@ import React from 'react'; const DevicePage = React.lazy(() => import('pages/DevicePage')); const DeviceListPage = React.lazy(() => import('pages/DeviceListPage')); -const routes = [ +export default [ { path: '/devices', exact: true, name: 'common.devices', component: DeviceListPage }, { path: '/devices/:deviceId', name: 'common.device_page', component: DevicePage }, ]; - -export default routes; diff --git a/src/store.js b/src/store.js deleted file mode 100644 index cc7b3fd..0000000 --- a/src/store.js +++ /dev/null @@ -1,19 +0,0 @@ -import { createStore } from 'redux'; - -const initialState = { - sidebarShow: 'responsive', - connected: false, - selectedDeviceId: null, -}; - -const changeState = (state = initialState, { type, ...rest }) => { - switch (type) { - case 'set': - return { ...state, ...rest }; - default: - return state; - } -}; - -const store = createStore(changeState); -export default store; diff --git a/src/utils/deviceHelper.js b/src/utils/deviceHelper.js index 7fd318d..44f755f 100644 --- a/src/utils/deviceHelper.js +++ b/src/utils/deviceHelper.js @@ -1,11 +1,10 @@ -import { getToken } from 'utils/authHelper'; import axiosInstance from 'utils/axiosInstance'; -export default async (deviceId) => { +export default async (deviceId, token) => { const options = { headers: { Accept: 'application/json', - Authorization: `Bearer ${getToken()}`, + Authorization: `Bearer ${token}`, }, };