Skip to content
This repository has been archived by the owner on Oct 27, 2022. It is now read-only.

Commit

Permalink
refactor strategy item component for reuse
Browse files Browse the repository at this point in the history
Co-authored-by: Fredrik Strand Oseberg <fredrik.no@gmail.com>
  • Loading branch information
Tymek and FredrikOseberg committed Aug 8, 2022
1 parent 334ea57 commit 5a59a1d
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 88 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { DragEventHandler, FC, ReactNode } from 'react';
import { DragIndicator } from '@mui/icons-material';
import { styled, IconButton, Box } from '@mui/material';
import classNames from 'classnames';
import { IFeatureStrategy } from 'interfaces/strategy';
import {
getFeatureStrategyIcon,
formatStrategyName,
} from 'utils/strategyNames';
import StringTruncator from 'component/common/StringTruncator/StringTruncator';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { useStyles } from './StrategyItemContainer.styles';

interface IStrategyItemContainerProps {
strategy: IFeatureStrategy;
onDragStart?: DragEventHandler<HTMLButtonElement>;
onDragEnd?: DragEventHandler<HTMLButtonElement>;
actions?: ReactNode;
orderNumber?: number;
}

const DragIcon = styled(IconButton)(({ theme }) => ({
padding: 0,
cursor: 'inherit',
transition: 'color 0.2s ease-in-out',
}));

const StyledIndexLabel = styled('div')(({ theme }) => ({
fontSize: theme.typography.fontSize,
color: theme.palette.text.secondary,
position: 'absolute',
display: 'none',
right: 'calc(100% + 6px)',
top: theme.spacing(2.5),
[theme.breakpoints.up('md')]: {
display: 'block',
},
}));

export const StrategyItemContainer: FC<IStrategyItemContainerProps> = ({
strategy,
onDragStart,
onDragEnd,
actions,
children,
orderNumber,
}) => {
const { classes: styles } = useStyles();
const Icon = getFeatureStrategyIcon(strategy.name);

return (
<Box sx={{ position: 'relative' }}>
<ConditionallyRender
condition={orderNumber !== undefined}
show={<StyledIndexLabel>{orderNumber}</StyledIndexLabel>}
/>

<div className={styles.container}>
<div
className={classNames(styles.header, {
[styles.headerDraggable]: Boolean(onDragStart),
})}
>
<ConditionallyRender
condition={Boolean(onDragStart)}
show={() => (
<DragIcon
draggable
disableRipple
size="small"
onDragStart={onDragStart}
onDragEnd={onDragEnd}
sx={{ cursor: 'move' }}
>
<DragIndicator
titleAccess="Drag to reorder"
cursor="grab"
sx={{ color: 'neutral.main' }}
/>
</DragIcon>
)}
/>
<Icon className={styles.icon} />
<StringTruncator
maxWidth="150"
maxLength={15}
text={formatStrategyName(strategy.name)}
/>
<div className={styles.actions}>{actions}</div>
</div>
<div className={styles.body}>{children}</div>
</div>
</Box>
);
};
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Box, styled } from '@mui/material';
import { DragEventHandler, RefObject, useRef } from 'react';
import { Box } from '@mui/material';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator';
import { IFeatureEnvironment } from 'interfaces/featureToggle';
import { IFeatureStrategy } from 'interfaces/strategy';
import { DragEventHandler, RefObject, useRef } from 'react';
import { StrategyItem } from './StrategyItem/StrategyItem';

interface IStrategyDraggableItemProps {
Expand All @@ -22,19 +22,6 @@ interface IStrategyDraggableItemProps {
) => DragEventHandler<HTMLDivElement>;
onDragEnd: () => void;
}

const StyledIndexLabel = styled('div')(({ theme }) => ({
fontSize: theme.typography.fontSize,
color: theme.palette.text.secondary,
position: 'absolute',
display: 'none',
right: 'calc(100% + 6px)',
top: theme.spacing(2.5),
[theme.breakpoints.up('md')]: {
display: 'block',
},
}));

export const StrategyDraggableItem = ({
strategy,
index,
Expand All @@ -58,16 +45,15 @@ export const StrategyDraggableItem = ({
condition={index > 0}
show={<StrategySeparator text="OR" />}
/>
<Box sx={{ position: 'relative' }}>
<StyledIndexLabel>{index + 1}</StyledIndexLabel>
<StrategyItem
strategy={strategy}
environmentId={environmentName}
otherEnvironments={otherEnvironments}
onDragStart={onDragStartRef(ref, index)}
onDragEnd={onDragEnd}
/>
</Box>

<StrategyItem
strategy={strategy}
environmentId={environmentName}
otherEnvironments={otherEnvironments}
onDragStart={onDragStartRef(ref, index)}
onDragEnd={onDragEnd}
orderNumber={index + 1}
/>
</Box>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import StringTruncator from 'component/common/StringTruncator/StringTruncator';

interface IStrategyExecutionProps {
strategy: IFeatureStrategy;
percentageFill?: string;
}

const NoItems: VFC = () => (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,51 +1,37 @@
import { DragEventHandler } from 'react';
import { DragIndicator, Edit } from '@mui/icons-material';
import { styled, useTheme, IconButton } from '@mui/material';
import { DragEventHandler, VFC } from 'react';
import { Edit } from '@mui/icons-material';
import { Link } from 'react-router-dom';
import classNames from 'classnames';
import { IFeatureEnvironment } from 'interfaces/featureToggle';
import { IFeatureStrategy } from 'interfaces/strategy';
import {
getFeatureStrategyIcon,
formatStrategyName,
} from 'utils/strategyNames';
import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton';
import { UPDATE_FEATURE_STRATEGY } from 'component/providers/AccessProvider/permissions';
import { formatEditStrategyPath } from 'component/feature/FeatureStrategy/FeatureStrategyEdit/FeatureStrategyEdit';
import { FeatureStrategyRemove } from 'component/feature/FeatureStrategy/FeatureStrategyRemove/FeatureStrategyRemove';
import StringTruncator from 'component/common/StringTruncator/StringTruncator';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import { StrategyExecution } from './StrategyExecution/StrategyExecution';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { CopyStrategyIconMenu } from './CopyStrategyIconMenu/CopyStrategyIconMenu';
import { useStyles } from './StrategyItem.styles';
import { StrategyItemContainer } from 'component/common/StrategyItemContainer/StrategyItemContainer';

interface IStrategyItemProps {
environmentId: string;
strategy: IFeatureStrategy;
onDragStart?: DragEventHandler<HTMLButtonElement>;
onDragEnd?: DragEventHandler<HTMLButtonElement>;
otherEnvironments?: IFeatureEnvironment['name'][];
orderNumber?: number;
}

const DragIcon = styled(IconButton)(({ theme }) => ({
padding: 0,
cursor: 'inherit',
transition: 'color 0.2s ease-in-out',
}));

export const StrategyItem = ({
export const StrategyItem: VFC<IStrategyItemProps> = ({
environmentId,
strategy,
onDragStart,
onDragEnd,
otherEnvironments,
}: IStrategyItemProps) => {
orderNumber,
}) => {
const projectId = useRequiredPathParam('projectId');
const featureId = useRequiredPathParam('featureId');
const theme = useTheme();
const { classes: styles } = useStyles();
const Icon = getFeatureStrategyIcon(strategy.name);

const editStrategyPath = formatEditStrategyPath(
projectId,
Expand All @@ -55,38 +41,13 @@ export const StrategyItem = ({
);

return (
<div className={styles.container}>
<div
className={classNames(styles.header, {
[styles.headerDraggable]: Boolean(onDragStart),
})}
>
<ConditionallyRender
condition={Boolean(onDragStart)}
show={() => (
<DragIcon
draggable
disableRipple
size="small"
onDragStart={onDragStart}
onDragEnd={onDragEnd}
sx={{ cursor: 'move' }}
>
<DragIndicator
titleAccess="Drag to reorder"
cursor="grab"
sx={{ color: 'neutral.main' }}
/>
</DragIcon>
)}
/>
<Icon className={styles.icon} />
<StringTruncator
maxWidth="150"
maxLength={15}
text={formatStrategyName(strategy.name)}
/>
<div className={styles.actions}>
<StrategyItemContainer
strategy={strategy}
onDragStart={onDragStart}
onDragEnd={onDragEnd}
orderNumber={orderNumber}
actions={
<>
<ConditionallyRender
condition={Boolean(
otherEnvironments && otherEnvironments?.length > 0
Expand Down Expand Up @@ -115,14 +76,10 @@ export const StrategyItem = ({
strategyId={strategy.id}
icon
/>
</div>
</div>
<div className={styles.body}>
<StrategyExecution
strategy={strategy}
percentageFill={theme.palette.grey[200]}
/>
</div>
</div>
</>
}
>
<StrategyExecution strategy={strategy} />
</StrategyItemContainer>
);
};

0 comments on commit 5a59a1d

Please sign in to comment.