1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-09-19 17:52:45 +02:00
unleash.unleash/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/StrategyChange.tsx
Nuno Góis 4167a60588
feat: biome lint frontend (#4903)
Follows up on https://github.com/Unleash/unleash/pull/4853 to add Biome
to the frontend as well.


![image](https://github.com/Unleash/unleash/assets/14320932/1906faf1-fc29-4172-a4d4-b2716d72cd65)

Added a few `biome-ignore` to speed up the process but we may want to
check and fix them in the future.
2023-10-02 13:25:46 +01:00

249 lines
9.1 KiB
TypeScript

import { VFC, FC, ReactNode } from 'react';
import { Box, styled, Tooltip, Typography } from '@mui/material';
import BlockIcon from '@mui/icons-material/Block';
import TrackChangesIcon from '@mui/icons-material/TrackChanges';
import {
StrategyDiff,
StrategyTooltipLink,
} from '../../StrategyTooltipLink/StrategyTooltipLink';
import { StrategyExecution } from 'component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/StrategyExecution';
import {
IChangeRequestAddStrategy,
IChangeRequestDeleteStrategy,
IChangeRequestUpdateStrategy,
} from 'component/changeRequest/changeRequest.types';
import { useCurrentStrategy } from './hooks/useCurrentStrategy';
import { Badge } from 'component/common/Badge/Badge';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { flexRow } from 'themes/themeStyles';
import { EnvironmentVariantsTable } from 'component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsTable/EnvironmentVariantsTable';
export const ChangeItemWrapper = styled(Box)({
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
});
const ChangeItemCreateEditWrapper = styled(Box)(({ theme }) => ({
display: 'grid',
gridTemplateColumns: 'auto auto',
justifyContent: 'space-between',
gap: theme.spacing(1),
alignItems: 'center',
marginBottom: theme.spacing(2),
width: '100%',
}));
const ChangeItemInfo: FC = styled(Box)(({ theme }) => ({
display: 'grid',
gridTemplateColumns: '150px auto',
gridAutoFlow: 'column',
alignItems: 'center',
flexGrow: 1,
gap: theme.spacing(1),
}));
const StyledBox: FC = styled(Box)(({ theme }) => ({
marginTop: theme.spacing(2),
}));
const StyledTypography: FC = styled(Typography)(({ theme }) => ({
margin: `${theme.spacing(1)} 0`,
}));
const hasNameField = (payload: unknown): payload is { name: string } =>
typeof payload === 'object' && payload !== null && 'name' in payload;
const DisabledEnabledState: VFC<{ show?: boolean; disabled: boolean }> = ({
show = true,
disabled,
}) => {
if (!show) {
return null;
}
if (disabled) {
return (
<Tooltip
title='This strategy will not be taken into account when evaluating feature toggle.'
arrow
sx={{ cursor: 'pointer' }}
>
<Badge color='disabled' icon={<BlockIcon />}>
Disabled
</Badge>
</Tooltip>
);
}
return (
<Tooltip
title='This was disabled before and with this change it will be taken into account when evaluating feature toggle.'
arrow
sx={{ cursor: 'pointer' }}
>
<Badge color='success' icon={<TrackChangesIcon />}>
Enabled
</Badge>
</Tooltip>
);
};
const EditHeader: VFC<{
wasDisabled?: boolean;
willBeDisabled?: boolean;
}> = ({ wasDisabled = false, willBeDisabled = false }) => {
if (wasDisabled && willBeDisabled) {
return (
<Typography color='action.disabled'>Editing strategy:</Typography>
);
}
if (!wasDisabled && willBeDisabled) {
return <Typography color='error.dark'>Editing strategy:</Typography>;
}
if (wasDisabled && !willBeDisabled) {
return <Typography color='success.dark'>Editing strategy:</Typography>;
}
return <Typography>Editing strategy:</Typography>;
};
export const StrategyChange: VFC<{
actions?: ReactNode;
change:
| IChangeRequestAddStrategy
| IChangeRequestDeleteStrategy
| IChangeRequestUpdateStrategy;
environmentName: string;
featureName: string;
projectId: string;
}> = ({ actions, change, featureName, environmentName, projectId }) => {
const currentStrategy = useCurrentStrategy(
change,
projectId,
featureName,
environmentName,
);
const isStrategyAction =
change.action === 'addStrategy' || change.action === 'updateStrategy';
const featureStrategyVariantsDisplay =
isStrategyAction &&
change.payload.variants &&
change.payload.variants.length > 0 ? (
<StyledBox>
<StyledTypography>
Updating feature variants to:
</StyledTypography>
<EnvironmentVariantsTable variants={change.payload.variants} />
</StyledBox>
) : null;
return (
<>
{change.action === 'addStrategy' && (
<>
<ChangeItemCreateEditWrapper>
<ChangeItemInfo>
<Typography
color={
change.payload?.disabled
? 'action.disabled'
: 'success.dark'
}
>
+ Adding strategy:
</Typography>
<StrategyTooltipLink change={change}>
<StrategyDiff
change={change}
currentStrategy={currentStrategy}
/>
</StrategyTooltipLink>
<div>
<DisabledEnabledState
disabled
show={change.payload?.disabled === true}
/>
</div>
</ChangeItemInfo>
<div>{actions}</div>
</ChangeItemCreateEditWrapper>
<StrategyExecution strategy={change.payload} />
{featureStrategyVariantsDisplay}
</>
)}
{change.action === 'deleteStrategy' && (
<ChangeItemWrapper>
<ChangeItemInfo>
<Typography
sx={(theme) => ({
color: theme.palette.error.main,
})}
>
- Deleting strategy:
</Typography>
{hasNameField(change.payload) && (
<StrategyTooltipLink change={change}>
<StrategyDiff
change={change}
currentStrategy={currentStrategy}
/>
</StrategyTooltipLink>
)}
</ChangeItemInfo>
<div>{actions}</div>
</ChangeItemWrapper>
)}
{change.action === 'updateStrategy' && (
<>
<ChangeItemCreateEditWrapper>
<ChangeItemInfo>
<EditHeader
wasDisabled={currentStrategy?.disabled}
willBeDisabled={change.payload?.disabled}
/>
<StrategyTooltipLink
change={change}
previousTitle={currentStrategy?.title}
>
<StrategyDiff
change={change}
currentStrategy={currentStrategy}
/>
</StrategyTooltipLink>
</ChangeItemInfo>
<div>{actions}</div>
</ChangeItemCreateEditWrapper>
<ConditionallyRender
condition={
change.payload?.disabled !==
currentStrategy?.disabled
}
show={
<Typography
sx={{
marginTop: (theme) => theme.spacing(2),
marginBottom: (theme) => theme.spacing(2),
...flexRow,
gap: (theme) => theme.spacing(1),
}}
>
This strategy will be{' '}
<DisabledEnabledState
disabled={change.payload?.disabled || false}
/>
</Typography>
}
/>
<StrategyExecution strategy={change.payload} />
{featureStrategyVariantsDisplay}
</>
)}
</>
);
};