Skip to content

Commit

Permalink
feat: add copy button for Device Identifier in Grower Details (#207)
Browse files Browse the repository at this point in the history
* fix: add copy button to grower detail > device identifier

* fix: move copyButton and copyNotification to common components folder
  • Loading branch information
tranquanghuy0801 authored Nov 28, 2021
1 parent 9056e44 commit 7a0037d
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 58 deletions.
11 changes: 8 additions & 3 deletions pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
## Description
_[Add a description of the changes]_

_[Add a description of the changes]_

**Issue(s) addressed**

- Resolves #_[insert ID of the issue addressed]_

**What kind of change(s) does this PR introduce?**
**What kind of change(s) does this PR introduce?**

- [ ] Enhancement
- [ ] Bug fix
- [ ] Refactor

**Please check if the PR fulfills these requirements**

- [ ] The commit message follows our guidelines
- [ ] Tests for the changes have been added (for bug fixes / features)
- [ ] Docs have been added / updated (for bug fixes / features)
Expand All @@ -21,6 +25,7 @@ _[Add a description of the changes]_
**What is the new behavior?**

## Breaking change
**Does this PR introduce a breaking change?**

**Does this PR introduce a breaking change?**

## Other useful information
65 changes: 11 additions & 54 deletions src/components/CaptureDetailDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,15 @@ import Grid from '@material-ui/core/Grid';
import Divider from '@material-ui/core/Divider';
import Chip from '@material-ui/core/Chip';
import IconButton from '@material-ui/core/IconButton';
import Snackbar from '@material-ui/core/Snackbar';
import Drawer from '@material-ui/core/Drawer';
import Box from '@material-ui/core/Box';
import Close from '@material-ui/icons/Close';

import FileCopy from '@material-ui/icons/FileCopy';
import CloseIcon from '@material-ui/icons/Close';
import OptimizedImage from './OptimizedImage';
import LinkToWebmap from './common/LinkToWebmap';
import { verificationStates } from '../common/variables';
import { CaptureDetailContext } from '../context/CaptureDetailContext';
import CopyNotification from './common/CopyNotification';
import { CopyButton } from './common/CopyButton';

const useStyles = makeStyles((theme) => ({
chipRoot: {
Expand Down Expand Up @@ -47,9 +45,6 @@ const useStyles = makeStyles((theme) => ({
fontWeight: 700,
fontSize: '0.8em',
},
copyButton: {
margin: theme.spacing(-2, 0),
},
subtitle: {
...theme.typography.button,
fontSize: '0.8em',
Expand Down Expand Up @@ -132,30 +127,6 @@ function CaptureDetailDialog(props) {
setSnackbarOpen(true);
}

function handleSnackbarClose(event, reason) {
if (reason === 'clickaway') {
return;
}
setSnackbarOpen(false);
}

function CopyButton(props) {
const { value, label } = props;

return (
<IconButton
className={classes.copyButton}
title="Copy to clipboard"
onClick={() => {
navigator.clipboard.writeText(value);
confirmCopy(label);
}}
>
<FileCopy fontSize="small" />
</IconButton>
);
}

return (
<Grid container direction="column">
<Grid item>
Expand Down Expand Up @@ -207,7 +178,11 @@ function CaptureDetailDialog(props) {
item.value || '---'
)}
{item.value && item.copy && (
<CopyButton label={item.label} value={item.value} />
<CopyButton
label={item.label}
value={item.value}
confirmCopy={confirmCopy}
/>
)}
</Typography>
</Grid>
Expand Down Expand Up @@ -267,28 +242,10 @@ function CaptureDetailDialog(props) {
{getTokenStatus(capture.tokenId)}
</Typography>
</Grid>
<Snackbar
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
key={snackbarLabel.length ? snackbarLabel : undefined}
open={snackbarOpen}
autoHideDuration={2000}
onClose={handleSnackbarClose}
message={`${snackbarLabel} copied to clipboard`}
color="primary"
action={
<>
<IconButton
size="small"
aria-label="close"
onClick={handleSnackbarClose}
>
<CloseIcon fontSize="small" />
</IconButton>
</>
}
<CopyNotification
snackbarLabel={snackbarLabel}
snackbarOpen={snackbarOpen}
setSnackbarOpen={setSnackbarOpen}
/>
</Grid>
);
Expand Down
26 changes: 25 additions & 1 deletion src/components/GrowerDetail.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import { GrowerContext } from '../context/GrowerContext';
import EditGrower from './EditGrower';
import OptimizedImage from './OptimizedImage';
import LinkToWebmap from './common/LinkToWebmap';
import { CopyButton } from './common/CopyButton';
import CopyNotification from './common/CopyNotification';

const GROWER_IMAGE_SIZE = 441;

Expand Down Expand Up @@ -66,6 +68,8 @@ const GrowerDetail = (props) => {
const [editDialogOpen, setEditDialogOpen] = useState(false);
const [grower, setGrower] = useState({});
const [deviceIdentifiers, setDeviceIdentifiers] = useState([]);
const [snackbarOpen, setSnackbarOpen] = useState(false);
const [snackbarLabel, setSnackbarLabel] = useState('');

useEffect(() => {
async function loadGrowerDetail() {
Expand Down Expand Up @@ -126,6 +130,14 @@ const GrowerDetail = (props) => {

function handleEditClose() {
setEditDialogOpen(false);
setSnackbarOpen(false);
setSnackbarLabel('');
}

function confirmCopy(label) {
setSnackbarOpen(false);
setSnackbarLabel(label);
setSnackbarOpen(true);
}

return (
Expand Down Expand Up @@ -259,7 +271,14 @@ const GrowerDetail = (props) => {
{deviceIdentifiers.map((device, i) => (
<tr key={i}>
<td>
<Typography variant="body1">{device.id}</Typography>
<Typography variant="body1">
{device.id}
<CopyButton
label={'Device Identifier'}
value={device.id}
confirmCopy={confirmCopy}
/>
</Typography>
</td>
<td>
<Typography variant="body1">({device.os})</Typography>
Expand All @@ -273,6 +292,11 @@ const GrowerDetail = (props) => {
</Grid>
</Grid>
</Drawer>
<CopyNotification
snackbarLabel={snackbarLabel}
snackbarOpen={snackbarOpen}
setSnackbarOpen={setSnackbarOpen}
/>
<EditGrower
isOpen={editDialogOpen}
grower={grower}
Expand Down
28 changes: 28 additions & 0 deletions src/components/common/CopyButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import { IconButton } from '@material-ui/core';
import FileCopy from '@material-ui/icons/FileCopy';
import { makeStyles } from '@material-ui/core/styles';

const useStyles = makeStyles((theme) => ({
copyButton: {
margin: theme.spacing(-2, 0),
},
}));

export function CopyButton(props) {
const { value, label, confirmCopy } = props;
const classes = useStyles();

return (
<IconButton
className={classes.copyButton}
title="Copy to clipboard"
onClick={() => {
navigator.clipboard.writeText(value);
confirmCopy(label);
}}
>
<FileCopy fontSize="small" />
</IconButton>
);
}
45 changes: 45 additions & 0 deletions src/components/common/CopyNotification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import { Snackbar } from '@material-ui/core';
import { IconButton } from '@material-ui/core';
import CloseIcon from '@material-ui/icons/Close';

const CopyNotification = (props) => {
const { snackbarLabel, snackbarOpen, setSnackbarOpen } = props;

function handleSnackbarClose(event, reason) {
if (reason === 'clickaway') {
return;
}
setSnackbarOpen(false);
}

return (
<>
<Snackbar
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
key={snackbarLabel.length ? snackbarLabel : undefined}
open={snackbarOpen}
autoHideDuration={2000}
onClose={handleSnackbarClose}
message={`${snackbarLabel} copied to clipboard`}
color="primary"
action={
<>
<IconButton
size="small"
aria-label="close"
onClick={handleSnackbarClose}
>
<CloseIcon fontSize="small" />
</IconButton>
</>
}
/>
</>
);
};

export default CopyNotification;

0 comments on commit 7a0037d

Please sign in to comment.