diff --git a/netmanager/src/assets/css/copyable.css b/netmanager/src/assets/css/copyable.css index 1ee5979145..fbfe0e4106 100644 --- a/netmanager/src/assets/css/copyable.css +++ b/netmanager/src/assets/css/copyable.css @@ -12,3 +12,14 @@ .copyable-icon:hover { fill: #0366d6; } + +.copyable-scrollable-text { + overflow: auto; + scrollbar-width: none; + -ms-overflow-style: none; + font-family: monospace; +} + +.copyable-scrollable-text::-webkit-scrollbar { + display: none; +} diff --git a/netmanager/src/views/components/Copy/Copyable.js b/netmanager/src/views/components/Copy/Copyable.js index cf53e39cbb..4de6ffee0a 100644 --- a/netmanager/src/views/components/Copy/Copyable.js +++ b/netmanager/src/views/components/Copy/Copyable.js @@ -1,20 +1,20 @@ -import React, { useState, useRef } from "react"; -import { useDispatch } from "react-redux"; -import CopyIcon, { CopySuccessIcon } from "assets/img/CopyIcon"; -import { updateMainAlert } from "redux/MainAlert/operations"; -import { Button } from "@material-ui/core"; -import clsx from "clsx"; +import React, { useState, useRef } from 'react'; +import { useDispatch } from 'react-redux'; +import CopyIcon, { CopySuccessIcon } from 'assets/img/CopyIcon'; +import { updateMainAlert } from 'redux/MainAlert/operations'; +import { Button } from '@material-ui/core'; +import clsx from 'clsx'; -const Copyable = ({ value, className, width, format }) => { +const Copyable = ({ value, className, width, format, isScrollable = false }) => { const copyRef = useRef(); const [copied, setCopied] = useState(false); const dispatch = useDispatch(); - let isDisabled = value === "-"; + let isDisabled = value === '-'; const onClick = () => { // let comp = document.getElementById(componentID); let comp = copyRef.current; - let textArea = document.createElement("textarea"); + let textArea = document.createElement('textarea'); textArea.value = comp.textContent; document.body.appendChild(textArea); /* Select the text field */ @@ -22,16 +22,14 @@ const Copyable = ({ value, className, width, format }) => { textArea.setSelectionRange(0, 99999); /* For mobile devices */ /* Copy the text inside the text field */ - document.execCommand("copy"); + document.execCommand('copy'); textArea.remove(); setCopied(true); dispatch( updateMainAlert({ show: true, - message: `Successfully copied to clipboard. ${ - format ? "format - " + format : "" - }`, - severity: "info", + message: `Successfully copied to clipboard. ${format ? 'format - ' + format : ''}`, + severity: 'info' }) ); setTimeout(() => setCopied(false), 1000); @@ -39,29 +37,29 @@ const Copyable = ({ value, className, width, format }) => { return (
{value} {copied ? ( ) : ( - )}
diff --git a/netmanager/src/views/components/DataDisplay/DeviceView/DeviceOverview/DeviceDetails.js b/netmanager/src/views/components/DataDisplay/DeviceView/DeviceOverview/DeviceDetails.js index 51ef37e669..c536264d5a 100644 --- a/netmanager/src/views/components/DataDisplay/DeviceView/DeviceOverview/DeviceDetails.js +++ b/netmanager/src/views/components/DataDisplay/DeviceView/DeviceOverview/DeviceDetails.js @@ -1,13 +1,26 @@ import React, { useState, useEffect } from 'react'; -import { Paper, Table, TableBody, TableCell, TableContainer, TableRow } from '@material-ui/core'; +import { + Box, + Paper, + Table, + TableBody, + TableCell, + TableContainer, + TableRow +} from '@material-ui/core'; import Copyable from 'views/components/Copy/Copyable'; import { ChartContainer } from 'views/charts'; import { decryptKeyApi } from 'views/apis/deviceRegistry'; import { isEmpty } from 'underscore'; import format from 'date-fns/format'; +import { stripTrailingSlash } from '../../../../../config/utils'; +import HowToApiModal from '../../../HowToApiModal'; + +const BASE_ANALYTICS_URL = stripTrailingSlash(process.env.REACT_APP_BASE_URL_V2); const DeviceDetails = ({ deviceData }) => { const BLANK_PLACE_HOLDER = '-'; + const [openModal, setOpenModal] = useState(false); const [readKey, setReadKey] = useState(''); const [writeKey, setWriteKey] = useState(''); @@ -157,9 +170,60 @@ const DeviceDetails = ({ deviceData }) => { + {deviceData._id && ( + + + Historical measurements API + + + + + + )} + {deviceData._id && ( + + + Recent measurements API + + + + + + )} + + setOpenModal(true)} + > +

How to use the API

+
+ setOpenModal(false)} /> ); }; diff --git a/netmanager/src/views/components/HowToApiModal/index.js b/netmanager/src/views/components/HowToApiModal/index.js new file mode 100644 index 0000000000..69ee01f727 --- /dev/null +++ b/netmanager/src/views/components/HowToApiModal/index.js @@ -0,0 +1,40 @@ +import React from 'react'; +import { Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@material-ui/core'; + +const HowToApiModal = ({ open, onClose }) => { + return ( + + How to the use the API + +
    +
  1. To use an API, you'll need to add an access token
  2. +
  3. Go to the Settings page.
  4. +
  5. Find the Client section and create a registered client if you don't have one yet.
  6. +
  7. Click on the "Generate Token" button.
  8. +
  9. Copy the generated API token.
  10. +
  11. + Paste the API token in your API requests. For example: +
    + + https://example.com/api/v2/devices?token=YOUR_API_TOKEN + +
  12. +
+
+ + + +
+ ); +}; + +export default HowToApiModal; diff --git a/netmanager/src/views/pages/CohortsRegistry/CohortDetails.jsx b/netmanager/src/views/pages/CohortsRegistry/CohortDetails.jsx index f14a61c28b..67349f0b92 100644 --- a/netmanager/src/views/pages/CohortsRegistry/CohortDetails.jsx +++ b/netmanager/src/views/pages/CohortsRegistry/CohortDetails.jsx @@ -35,6 +35,11 @@ import { updateMainAlert } from 'redux/MainAlert/operations'; import OutlinedSelect from '../../components/CustomSelects/OutlinedSelect'; import { createAlertBarExtraContent } from '../../../utils/objectManipulators'; import { LargeCircularLoader } from '../../components/Loader/CircularLoader'; +import { stripTrailingSlash } from '../../../config/utils'; +import Copyable from '../../components/Copy/Copyable'; +import HowToApiModal from '../../components/HowToApiModal'; + +const BASE_ANALYTICS_URL = stripTrailingSlash(process.env.REACT_APP_BASE_URL_V2); const gridItemStyle = { padding: '5px', @@ -185,6 +190,7 @@ const CohortForm = ({ cohort }) => { }; const [form, setState] = useState(initialState); const [loading, setLoading] = useState(false); + const [openAPIModal, setOpenAPIModal] = useState(false); const clearState = () => { setState({ ...initialState }); }; @@ -337,28 +343,90 @@ const CohortForm = ({ cohort }) => { + + + + + + + + + + + + - - - +

How to use the API

+
+ + + + + @@ -368,6 +436,7 @@ const CohortForm = ({ cohort }) => { open={openDrawer} handleClose={handleCloseDrawer} /> + setOpenAPIModal(false)} /> ); }; diff --git a/netmanager/src/views/pages/GridsRegistry/GridsDetails.js b/netmanager/src/views/pages/GridsRegistry/GridsDetails.js index 443b751d9c..6707988d1f 100644 --- a/netmanager/src/views/pages/GridsRegistry/GridsDetails.js +++ b/netmanager/src/views/pages/GridsRegistry/GridsDetails.js @@ -30,6 +30,11 @@ import { updateGridApi } from '../../apis/deviceRegistry'; import { withPermission } from '../../containers/PageAccess'; import { LargeCircularLoader } from '../../components/Loader/CircularLoader'; import { AirQloudView } from '../../components/AirQlouds'; +import HowToApiModal from '../../components/HowToApiModal'; +import { stripTrailingSlash } from '../../../config/utils'; +import Copyable from '../../components/Copy/Copyable'; + +const BASE_ANALYTICS_URL = stripTrailingSlash(process.env.REACT_APP_BASE_URL_V2); const gridItemStyle = { padding: '5px', @@ -47,6 +52,8 @@ const GridForm = ({ grid }) => { description: '' }; const [form, setState] = useState(initialState); + const [openAPIModal, setOpenAPIModal] = useState(false); + const [loading, setLoading] = useState(false); const clearState = () => { setState({ ...initialState }); @@ -229,6 +236,44 @@ const GridForm = ({ grid }) => { onChange={onChangeInputField} /> + + + + + + + + + + + + { xs={12} style={{ margin: '10px 0' }} > - + setOpenAPIModal(true)} + > +

How to use the API

+
- + + + +
+ setOpenAPIModal(false)} /> ); };