import type React from 'react';
import type { FC, ReactNode } from 'react';
import { Box, Button, styled, Tooltip, Typography } from '@mui/material';
import { Tab, Tabs, TabsList, TabPanel } from '@mui/base';
import BlockIcon from '@mui/icons-material/Block';
import TrackChangesIcon from '@mui/icons-material/TrackChanges';
import {
StrategyDiff,
StrategyTooltipLink,
} from '../../StrategyTooltipLink/StrategyTooltipLink.tsx';
import { StrategyExecution } from 'component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/StrategyExecution';
import type {
ChangeRequestState,
IChangeRequestAddStrategy,
IChangeRequestDeleteStrategy,
IChangeRequestUpdateStrategy,
} from 'component/changeRequest/changeRequest.types';
import { useCurrentStrategy } from './hooks/useCurrentStrategy.ts';
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';
import { ChangeOverwriteWarning } from './ChangeOverwriteWarning/ChangeOverwriteWarning.tsx';
import type { IFeatureStrategy } from 'interfaces/strategy';
export const ChangeItemWrapper = styled(Box)({
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
});
const ChangeItemCreateEditDeleteWrapper = styled(Box)(({ theme }) => ({
display: 'flex',
justifyContent: 'space-between',
gap: theme.spacing(1),
alignItems: 'center',
width: '100%',
}));
const ChangeItemInfo: FC<{ children?: React.ReactNode }> = styled(Box)(
({ theme }) => ({
display: 'grid',
gridTemplateColumns: '150px auto',
gridAutoFlow: 'column',
alignItems: 'center',
flexGrow: 1,
gap: theme.spacing(1),
}),
);
const StyledBox: FC<{ children?: React.ReactNode }> = styled(Box)(
({ theme }) => ({
marginTop: theme.spacing(2),
}),
);
const StyledTypography: FC<{ children?: React.ReactNode }> = styled(Typography)(
({ theme }) => ({
margin: `${theme.spacing(1)} 0`,
}),
);
const DisabledEnabledState: FC<{ show?: boolean; disabled: boolean }> = ({
show = true,
disabled,
}) => {
if (!show) {
return null;
}
if (disabled) {
return (
}>
Disabled
);
}
return (
}>
Enabled
);
};
const EditHeader: FC<{
wasDisabled?: boolean;
willBeDisabled?: boolean;
}> = ({ wasDisabled = false, willBeDisabled = false }) => {
if (wasDisabled && willBeDisabled) {
return (
Editing strategy:
);
}
if (!wasDisabled && willBeDisabled) {
return Editing strategy:;
}
if (wasDisabled && !willBeDisabled) {
return Editing strategy:;
}
return Editing strategy:;
};
const hasDiff = (object: unknown, objectToCompare: unknown) =>
JSON.stringify(object) !== JSON.stringify(objectToCompare);
const DeleteStrategy: FC<{
change: IChangeRequestDeleteStrategy;
changeRequestState: ChangeRequestState;
currentStrategy: IFeatureStrategy | undefined;
actions?: ReactNode;
}> = ({ change, changeRequestState, currentStrategy, actions }) => {
const name =
changeRequestState === 'Applied'
? change.payload?.snapshot?.name
: currentStrategy?.name;
const title =
changeRequestState === 'Applied'
? change.payload?.snapshot?.title
: currentStrategy?.title;
const referenceStrategy =
changeRequestState === 'Applied'
? change.payload.snapshot
: currentStrategy;
return (
<>
({
color: theme.palette.error.main,
})}
>
- Deleting strategy:
{actions}
{referenceStrategy && (
)}
>
);
};
const RightHandSide = styled('div')(({ theme }) => ({
display: 'flex',
gap: theme.spacing(1),
alignItems: 'center',
}));
const StyledTabList = styled(TabsList)(({ theme }) => ({
display: 'inline-flex',
flexDirection: 'row',
gap: theme.spacing(0.5),
}));
const StyledButton = styled(Button)(({ theme }) => ({
whiteSpace: 'nowrap',
color: theme.palette.text.secondary,
fontWeight: 'normal',
'&[aria-selected="true"]': {
fontWeight: 'bold',
color: theme.palette.primary.main,
background: theme.palette.background.elevation1,
},
}));
const UpdateStrategy: FC<{
change: IChangeRequestUpdateStrategy;
changeRequestState: ChangeRequestState;
currentStrategy: IFeatureStrategy | undefined;
actions?: ReactNode;
}> = ({ change, changeRequestState, currentStrategy, actions }) => {
const previousTitle =
changeRequestState === 'Applied'
? change.payload.snapshot?.title
: currentStrategy?.title;
const referenceStrategy =
changeRequestState === 'Applied'
? change.payload.snapshot
: currentStrategy;
const hasVariantDiff = hasDiff(
referenceStrategy?.variants || [],
change.payload.variants || [],
);
return (
value={0}
slots={{ root: StyledButton }}
>
Change
value={1}
slots={{ root: StyledButton }}
>
View diff
{actions}
theme.spacing(2),
marginBottom: (theme) => theme.spacing(2),
...flexRow,
gap: (theme) => theme.spacing(1),
}}
>
This strategy will be{' '}
}
/>
{hasVariantDiff ? (
{change.payload.variants?.length ? (
<>
{currentStrategy?.variants?.length
? 'Updating strategy variants to:'
: 'Adding strategy variants:'}
>
) : (
Removed all strategy variants.
)}
) : null}
);
};
const AddStrategy: FC<{
change: IChangeRequestAddStrategy;
actions?: ReactNode;
}> = ({ change, actions }) => (
<>
+ Adding strategy:
{actions}
{change.payload.variants?.length ? (
Adding strategy variants:
) : null}
>
);
export const DiffableChange: FC<{
actions?: ReactNode;
change:
| IChangeRequestAddStrategy
| IChangeRequestDeleteStrategy
| IChangeRequestUpdateStrategy;
environmentName: string;
featureName: string;
projectId: string;
changeRequestState: ChangeRequestState;
}> = ({
actions,
change,
featureName,
environmentName,
projectId,
changeRequestState,
}) => {
const currentStrategy = useCurrentStrategy(
change,
projectId,
featureName,
environmentName,
);
return (
<>
{change.action === 'addStrategy' && (
)}
{change.action === 'deleteStrategy' && (
)}
{change.action === 'updateStrategy' && (
)}
>
);
};