Skip to content

Commit

Permalink
feat: add copy button to feature flag name (#4098) (#5031)
Browse files Browse the repository at this point in the history
In ActionsCell.tsx file, 'Copy' with FileCopy icon is changed to 'Clone'
with 'LibraryAdd' icon as this feature is used to clone a new feature
from existing one. Upon copying the icon and text will change to 'Check'
icon with 'Copied!' for one sec and closes automatically.
  • Loading branch information
mohanrajnambe committed Oct 30, 2023
1 parent df79e0b commit 0c43089
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 6 deletions.
62 changes: 58 additions & 4 deletions frontend/src/component/feature/FeatureView/FeatureView.tsx
@@ -1,6 +1,20 @@
import { useState } from 'react';
import { styled, Tab, Tabs, useMediaQuery } from '@mui/material';
import { Archive, FileCopy, Label, WatchLater } from '@mui/icons-material';
import {
IconButton,
styled,
Tab,
Tabs,
Tooltip,
useMediaQuery,
} from '@mui/material';
import {
Archive,
FileCopy,
Label,
WatchLater,
LibraryAdd,
Check,
} from '@mui/icons-material';
import {
Link,
Route,
Expand Down Expand Up @@ -36,6 +50,8 @@ import { ReactComponent as ChildLinkIcon } from 'assets/icons/link-child.svg';
import { ReactComponent as ParentLinkIcon } from 'assets/icons/link-parent.svg';
import { ChildrenTooltip } from './FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelDetails/ChildrenTooltip';
import { useUiFlag } from 'hooks/useUiFlag';
import copy from 'copy-to-clipboard';
import useToast from 'hooks/useToast';

const StyledHeader = styled('div')(({ theme }) => ({
backgroundColor: theme.palette.background.paper,
Expand Down Expand Up @@ -128,10 +144,12 @@ export const FeatureView = () => {
const { favorite, unfavorite } = useFavoriteFeaturesApi();
const { refetchFeature } = useFeature(projectId, featureId);
const dependentFeatures = useUiFlag('dependentFeatures');
const { setToastData } = useToast();

const [openTagDialog, setOpenTagDialog] = useState(false);
const [showDelDialog, setShowDelDialog] = useState(false);
const [openStaleDialog, setOpenStaleDialog] = useState(false);
const [isFeatureNameCopied, setIsFeatureNameCopied] = useState(false);
const smallScreen = useMediaQuery(`(max-width:${500}px)`);

const { feature, loading, error, status } = useFeature(
Expand Down Expand Up @@ -185,6 +203,21 @@ export const FeatureView = () => {
return <div ref={ref} />;
}

const handleCopyToClipboard = () => {
try {
copy(feature.name);
setIsFeatureNameCopied(true);
setTimeout(() => {
setIsFeatureNameCopied(false);
}, 3000);
} catch (error: unknown) {
setToastData({
type: 'error',
title: 'Could not copy feature name',
});
}
};

return (
<div ref={ref}>
<StyledHeader>
Expand All @@ -199,6 +232,27 @@ export const FeatureView = () => {
<StyledFeatureViewHeader data-loading>
{feature.name}{' '}
</StyledFeatureViewHeader>
<Tooltip
title={
isFeatureNameCopied
? 'Copied!'
: 'Copy name'
}
arrow
>
<IconButton
onClick={handleCopyToClipboard}
style={{ marginLeft: 8 }}
>
{isFeatureNameCopied ? (
<Check style={{ fontSize: 16 }} />
) : (
<FileCopy
style={{ fontSize: 16 }}
/>
)}
</IconButton>
</Tooltip>
<ConditionallyRender
condition={!smallScreen}
show={
Expand Down Expand Up @@ -250,10 +304,10 @@ export const FeatureView = () => {
component={Link}
to={`/projects/${projectId}/features/${featureId}/copy`}
tooltipProps={{
title: 'Copy feature toggle',
title: 'Clone',
}}
>
<FileCopy />
<LibraryAdd />
</PermissionIconButton>
<PermissionIconButton
permission={DELETE_FEATURE}
Expand Down
Expand Up @@ -14,6 +14,8 @@ import {
import { Link as RouterLink } from 'react-router-dom';
import MoreVertIcon from '@mui/icons-material/MoreVert';
import FileCopyIcon from '@mui/icons-material/FileCopy';
import LibraryAddIcon from '@mui/icons-material/LibraryAdd';
import CheckIcon from '@mui/icons-material/Check';
import ArchiveIcon from '@mui/icons-material/Archive';
import WatchLaterIcon from '@mui/icons-material/WatchLater';
import { PermissionHOC } from 'component/common/PermissionHOC/PermissionHOC';
Expand All @@ -23,6 +25,8 @@ import {
UPDATE_FEATURE,
} from 'component/providers/AccessProvider/permissions';
import { defaultBorderRadius } from 'themes/themeStyles';
import copy from 'copy-to-clipboard';
import useToast from 'hooks/useToast';

const StyledBoxCell = styled(Box)(({ theme }) => ({
display: 'flex',
Expand All @@ -49,6 +53,8 @@ export const ActionsCell: VFC<IActionsCellProps> = ({
onOpenStaleDialog,
}) => {
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const [isFeatureNameCopied, setIsFeatureNameCopied] = useState(false);
const { setToastData } = useToast();
const {
original: { name: featureId, stale },
} = row;
Expand All @@ -63,6 +69,23 @@ export const ActionsCell: VFC<IActionsCellProps> = ({
const id = `feature-${featureId}-actions`;
const menuId = `${id}-menu`;

const handleCopyToClipboard = () => {
try {
copy(featureId);
setIsFeatureNameCopied(true);

setTimeout(() => {
handleClose();
setIsFeatureNameCopied(false);
}, 1000);
} catch (error: unknown) {
setToastData({
type: 'error',
title: 'Could not copy feature name',
});
}
};

return (
<StyledBoxCell>
<Tooltip title='Feature toggle actions' arrow describeChild>
Expand Down Expand Up @@ -93,6 +116,23 @@ export const ActionsCell: VFC<IActionsCellProps> = ({
}}
>
<MenuList aria-labelledby={id}>
<MenuItem
sx={defaultBorderRadius}
onClick={handleCopyToClipboard}
>
<ListItemIcon>
{isFeatureNameCopied ? (
<CheckIcon />
) : (
<FileCopyIcon />
)}
</ListItemIcon>
<ListItemText>
<Typography variant='body2'>
{isFeatureNameCopied ? 'Copied!' : 'Copy Name'}
</Typography>
</ListItemText>
</MenuItem>
<PermissionHOC
projectId={projectId}
permission={CREATE_FEATURE}
Expand All @@ -106,11 +146,11 @@ export const ActionsCell: VFC<IActionsCellProps> = ({
to={`/projects/${projectId}/features/${featureId}/copy`}
>
<ListItemIcon>
<FileCopyIcon />
<LibraryAddIcon />
</ListItemIcon>
<ListItemText>
<Typography variant='body2'>
Copy
Clone
</Typography>
</ListItemText>
</MenuItem>
Expand Down

0 comments on commit 0c43089

Please sign in to comment.