diff --git a/netmanager/src/__tests__/RecallDevice.test.js b/netmanager/src/__tests__/RecallDevice.test.js new file mode 100644 index 0000000000..65f4836577 --- /dev/null +++ b/netmanager/src/__tests__/RecallDevice.test.js @@ -0,0 +1,19 @@ +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import DeviceDeployStatus from '../views/components/DataDisplay/DeviceView/DeviceDeployStatus'; + +jest.mock('react-redux', () => ({ + useDispatch: () => jest.fn(), + })); + + // i have used the DeviceDeployStatus for the tests because all the functions for the recall an deploy are in + // this component + + describe('RecallDevice', () => { + it('renders without errors', () => { + const { asFragment } = render( + + ); + expect(asFragment()).toMatchSnapshot(); + }); + }); diff --git a/netmanager/src/__tests__/__snapshots__/RecallDevice.test.js.snap b/netmanager/src/__tests__/__snapshots__/RecallDevice.test.js.snap new file mode 100644 index 0000000000..b463955846 --- /dev/null +++ b/netmanager/src/__tests__/__snapshots__/RecallDevice.test.js.snap @@ -0,0 +1,502 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`RecallDevice renders without errors 1`] = ` + +
+
+ + + + Deploy status + + + + not deployed + + +
+ + +
+
+
+
+
+
+
+
+
+
+ + Site + +
+
+
+
+ +
+
+
+
+
+ + +
+
+
+
+
+
+ +
+ + +
+
+
+ +
+ + + +
+
+
+ +
+ + + +
+
+
+ +
+ + +
+
+
+
+ + +
+ +
+
+
+
+ + + + +
+
+
+ +`; diff --git a/netmanager/src/assets/css/dropdown.css b/netmanager/src/assets/css/dropdown.css index 7a041d22da..c47138fccc 100644 --- a/netmanager/src/assets/css/dropdown.css +++ b/netmanager/src/assets/css/dropdown.css @@ -7,6 +7,24 @@ } +.dropdown-rapper-recall { + /* display: flex; */ + /* align-items: center; */ + border: #175df5; + border-radius: 5px; + max-width: 200px; + font-weight: #175df5; + margin-bottom: 5px; + + +} + +.select-recall-type { + justify-content: center; + max-width: 90%; + font-weight: #175df5; +} + .select { color: #175df5; diff --git a/netmanager/src/views/apis/deviceRegistry.js b/netmanager/src/views/apis/deviceRegistry.js index c6e6aaef97..23a2365596 100644 --- a/netmanager/src/views/apis/deviceRegistry.js +++ b/netmanager/src/views/apis/deviceRegistry.js @@ -64,9 +64,10 @@ export const addMaintenanceLogApi = async (deviceName, logData) => { .then((response) => response.data); }; -export const recallDeviceApi = async (deviceName) => { +export const recallDeviceApi = async (deviceName, requestData) => { + return await axios - .post(RECALL_DEVICE_URI, {}, { params: { deviceName, token: BASE_AUTH_TOKEN } }) + .post(RECALL_DEVICE_URI, requestData, { params: { deviceName, token: BASE_AUTH_TOKEN } }) .then((response) => response.data); }; diff --git a/netmanager/src/views/components/DataDisplay/DeviceView/DeviceDeployStatus.js b/netmanager/src/views/components/DataDisplay/DeviceView/DeviceDeployStatus.js index ec7c1b57eb..dedbb533b3 100644 --- a/netmanager/src/views/components/DataDisplay/DeviceView/DeviceDeployStatus.js +++ b/netmanager/src/views/components/DataDisplay/DeviceView/DeviceDeployStatus.js @@ -1,7 +1,13 @@ import React, { useState, useEffect } from 'react'; import { useDispatch } from 'react-redux'; import PropTypes from 'prop-types'; -import { Button, CircularProgress, Grid, Paper, TextField } from '@material-ui/core'; +import Select from 'react-select'; +import { + Button, + Grid, + Paper, + TextField, +} from '@material-ui/core'; import Tooltip from '@material-ui/core/Tooltip'; import CheckBoxIcon from '@material-ui/icons/CheckBox'; import CancelIcon from '@material-ui/icons/Cancel'; @@ -32,6 +38,21 @@ import { purple } from '@material-ui/core/colors'; // horizontal loader import HorizontalLoader from 'views/components/HorizontalLoader/HorizontalLoader'; +import 'assets/css/dropdown.css'; + +const customStyles = { + control: (baseStyles, state) => ({ + ...baseStyles, + borderColor: '#175df5' + }), + singleValue: (provided) => ({ + ...provided, + color: '#0560c9', + fontWeight: 'bold', // Increase the font weight + textAlign: 'center', + justifyContent: 'center' + }) +}; const DEPLOYMENT_STATUSES = { deployed: 'deployed', @@ -144,7 +165,8 @@ const EmptyDeviceTest = ({ loading, onClick }) => { color="primary" disabled={loading} onClick={onClick} - style={{ textTransform: 'lowercase' }}> + style={{ textTransform: 'lowercase' }} + > run {' '} to initiate the test @@ -158,26 +180,6 @@ EmptyDeviceTest.propTypes = { onClick: PropTypes.func.isRequired }; -const RecallDevice = ({ deviceData, handleRecall, open, toggleOpen }) => { - return ( - - ); -}; - -RecallDevice.propTypes = { - deviceData: PropTypes.object.isRequired, - handleRecall: PropTypes.func.isRequired, - open: PropTypes.bool.isRequired, - toggleOpen: PropTypes.func.isRequired -}; - const DeviceRecentFeedView = ({ recentFeed, runReport }) => { const classes = useStyles(); const feedKeys = Object.keys( @@ -201,13 +203,15 @@ const DeviceRecentFeedView = ({ recentFeed, runReport }) => { justifyContent: 'center', width: '100%', marginBottom: '30px' - }}> + }} + > Device last pushed data{' '} {isDateInPast(recentFeed.created_at) ? ( <> elapseLimit ? classes.error : classes.root}> + className={elapsedDurationSeconds > elapseLimit ? classes.error : classes.root} + > {getFirstNDurations(elapsedDurationMapper, 2)} {' '} ago. @@ -230,7 +234,8 @@ const DeviceRecentFeedView = ({ recentFeed, runReport }) => { alignItems: 'center', margin: '10px 30px', color: elapsedDurationSeconds > elapseLimit ? 'grey' : 'inherit' - }}> + }} + > {feedKeys.map((key, index) => (
{isValidSensorValue( @@ -270,7 +275,8 @@ const DeviceRecentFeedView = ({ recentFeed, runReport }) => { margin: '10px 30px', height: '70%', color: 'red' - }}> + }} + > Device test has failed, please cross check the functionality of device
@@ -284,13 +290,83 @@ DeviceRecentFeedView.propTypes = { runReport: PropTypes.object.isRequired }; -export default function DeviceDeployStatus({ deviceData, siteOptions }) { +export default function DeviceDeployStatus({ deviceData, handleRecall, siteOptions }) { const dispatch = useDispatch(); const [height, setHeight] = useState((deviceData.height && String(deviceData.height)) || ''); const [power, setPower] = useState(capitalize(deviceData.powerType || '')); const [installationType, setInstallationType] = useState(deviceData.mountType || ''); const [deploymentDate, setDeploymentDate] = useState(getDateString(deviceData.deployment_date)); const [primaryChecked, setPrimaryChecked] = useState(deviceData.isPrimaryInLocation || false); + const [isLoading, setIsLoading] = useState(false); + const RecallButton = ({ handleRecall, recallLoading }) => { + const [selectedRecallType, setSelectedRecallType] = useState(''); + const [selectVisible, setSelectVisible] = useState(false); + + const options = [ + { value: 'errors', label: 'Errors' }, + { value: 'disconnected', label: 'Disconnected' }, + ]; + + const handleRecallChange = (selectedOption) => { + setSelectedRecallType(selectedOption); + }; + + const handleRecallClick = async () => { + setSelectVisible(true); + if (selectedRecallType) { + setSelectVisible(false); + setrecallLoading(true); + await handleRecall(selectedRecallType); + window.location.reload(); + setrecallLoading(false); + setSelectedRecallType(''); + } + }; + + return ( +
+
+ {selectVisible && ( // Only render the select when selectVisible is true +