Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Netmanager] Added measurements api section for user to copy #1741

Merged
merged 5 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions netmanager/src/assets/css/copyable.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
48 changes: 23 additions & 25 deletions netmanager/src/views/components/Copy/Copyable.js
Original file line number Diff line number Diff line change
@@ -1,67 +1,65 @@
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 */
textArea.select();
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);
};
return (
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between'
}}
>
<span
ref={copyRef}
style={{
width: width || "200px",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
overflow: "hidden",
width: width || '200px',
textOverflow: isScrollable ? 'none' : 'ellipsis',
whiteSpace: 'nowrap',
overflow: isScrollable ? 'auto' : 'hidden'
}}
className={isScrollable ? 'copyable-scrollable-text' : ''}
title={isScrollable ? 'Scroll left to view' : ''}
>
{value}
</span>
{copied ? (
<CopySuccessIcon />
) : (
<Button disabled={value === "-"} onClick={onClick}>
<CopyIcon
className={clsx(isDisabled && "disabled-copyable-icon", className)}
/>
<Button disabled={value === '-'} onClick={onClick}>
<CopyIcon className={clsx(isDisabled && 'disabled-copyable-icon', className)} />
</Button>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -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('');

Expand Down Expand Up @@ -157,9 +170,60 @@ const DeviceDetails = ({ deviceData }) => {
<Copyable value={writeKey || BLANK_PLACE_HOLDER} />
</TableCell>
</TableRow>
{deviceData._id && (
<TableRow>
<TableCell>
<b>Historical measurements API</b>
</TableCell>
<TableCell>
<Copyable
value={
`${stripTrailingSlash(BASE_ANALYTICS_URL)}/devices/measurements/devices/${
deviceData._id
}/historical` || BLANK_PLACE_HOLDER
}
isScrollable
/>
</TableCell>
</TableRow>
)}
{deviceData._id && (
<TableRow>
<TableCell>
<b>Recent measurements API</b>
</TableCell>
<TableCell>
<Copyable
value={
`${stripTrailingSlash(BASE_ANALYTICS_URL)}/devices/measurements/devices/${
deviceData._id
}` || BLANK_PLACE_HOLDER
}
isScrollable
/>
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>

<Box
style={{
display: 'flex',
flex: 1,
width: '100%',
justifyContent: 'flex-end',
textDecoration: 'underline',
padding: '10px',
fontWeight: 'bold',
cursor: 'pointer'
}}
onClick={() => setOpenModal(true)}
>
<p style={{ width: '100%', textAlign: 'right' }}>How to use the API</p>
</Box>
<HowToApiModal open={openModal} onClose={() => setOpenModal(false)} />
</ChartContainer>
);
};
Expand Down
40 changes: 40 additions & 0 deletions netmanager/src/views/components/HowToApiModal/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react';
import { Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@material-ui/core';

const HowToApiModal = ({ open, onClose }) => {
return (
<Dialog open={open} onClose={onClose} style={{ padding: '20px' }}>
<DialogTitle>How to the use the API</DialogTitle>
<DialogContent>
<ol>
<li>To use an API, you'll need to add an access token</li>
<li>Go to the Settings page.</li>
<li>Find the Client section and create a registered client if you don't have one yet.</li>
<li>Click on the "Generate Token" button.</li>
<li>Copy the generated API token.</li>
<li>
Paste the API token in your API requests. For example:
<br />
<span
style={{
backgroundColor: '#f0f0f0',
padding: '5px',
borderRadius: '5px',
fontFamily: 'monospace'
}}
>
https://example.com/api/v2/devices?token=YOUR_API_TOKEN
</span>
</li>
</ol>
</DialogContent>
<DialogActions>
<Button onClick={onClose} color="primary">
Close
</Button>
</DialogActions>
</Dialog>
);
};

export default HowToApiModal;
99 changes: 84 additions & 15 deletions netmanager/src/views/pages/CohortsRegistry/CohortDetails.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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 });
};
Expand Down Expand Up @@ -337,28 +343,90 @@ const CohortForm = ({ cohort }) => {
<option value={false}>False</option>
</TextField>
</Grid>
<Grid items xs={12} sm={6} style={gridItemStyle}>
<label style={{ textAlign: 'left' }}>Recent Measurements API</label>
<Box
style={{
backgroundColor: '#f0f0f0',
padding: '5px',
borderRadius: '5px',
fontFamily: 'monospace'
}}
>
<Copyable
width="100%"
value={`${stripTrailingSlash(BASE_ANALYTICS_URL)}/devices/measurements/cohorts/${
cohort._id
}`}
isScrollable
/>
</Box>
</Grid>
<Grid items xs={12} sm={6} style={gridItemStyle}>
<label style={{ textAlign: 'left' }}>Historical Measurements API</label>
<Box
style={{
backgroundColor: '#f0f0f0',
padding: '5px',
borderRadius: '5px',
fontFamily: 'monospace'
}}
>
<Copyable
width="100%"
value={`${stripTrailingSlash(BASE_ANALYTICS_URL)}/devices/measurements/cohorts/${
cohort._id
}/historical`}
isScrollable
/>
</Box>
</Grid>

<Grid
container
alignItems="flex-end"
alignContent="flex-end"
justify="flex-end"
alignItems="center"
alignContent="center"
justify="space-between"
xs={12}
style={{ margin: '10px 0' }}
>
<Button variant="contained" onClick={handleCancel} disabled={loading}>
Reset
</Button>

<Button
variant="contained"
color="primary"
onClick={handleSubmit}
style={{ marginLeft: '10px' }}
disabled={loading}
<Grid
items
xs={12}
sm={6}
style={{
textDecoration: 'underline',
padding: '10px',
fontWeight: 'bold',
cursor: 'pointer'
}}
onClick={() => setOpenAPIModal(true)}
>
{loading ? 'Laoding...' : 'Save Changes'}
</Button>
<p style={{ width: '100%', textAlign: 'left' }}>How to use the API</p>
</Grid>
<Grid
items
xs={12}
sm={6}
style={{
display: 'flex',
justifyContent: 'flex-end'
}}
>
<Button variant="contained" onClick={handleCancel} disabled={loading}>
Reset
</Button>

<Button
variant="contained"
color="primary"
onClick={handleSubmit}
style={{ marginLeft: '10px' }}
disabled={loading}
>
{loading ? 'Loading...' : 'Save Changes'}
</Button>
</Grid>
</Grid>
</Grid>

Expand All @@ -368,6 +436,7 @@ const CohortForm = ({ cohort }) => {
open={openDrawer}
handleClose={handleCloseDrawer}
/>
<HowToApiModal open={openAPIModal} onClose={() => setOpenAPIModal(false)} />
</Paper>
);
};
Expand Down
Loading
Loading