mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	chore: add newStrategyModal flag (#10629)
https://linear.app/unleash/issue/2-3865/add-newstrategymodal-feature-flag Adds `newStrategyModal` feature flag. The approach here is to duplicate the existing `FeatureStrategyMenuCards` into a `LegacyFeatureStrategyMenuCards`. We'll continue working on the `FeatureStrategyMenuCards` component while leaving `LegacyFeatureStrategyMenuCards` untouched. Once we're done with the implementation and remove the flag we can drop the legacy file. I think it's easier to reduce our add strategy buttons to a single one right away (like we did with the `addConfiguration` flag in https://github.com/Unleash/unleash/pull/10420). This allows us to focus on the end result instead of having to implement things like "clicking the 'add release template' button should show the modal filtered to only release templates". <img width="735" height="126" alt="image" src="https://github.com/user-attachments/assets/6d10fab2-d091-40f3-9c36-05a6f28f7dda" /> <img width="995" height="742" alt="image" src="https://github.com/user-attachments/assets/a0fb9366-89b5-44e1-a684-47ee30d6d36c" />
This commit is contained in:
		
							parent
							
								
									9540ed6e3d
								
							
						
					
					
						commit
						b8cdd1d004
					
				@ -6,7 +6,7 @@ import PermissionButton, {
 | 
			
		||||
} from 'component/common/PermissionButton/PermissionButton';
 | 
			
		||||
import { CREATE_FEATURE_STRATEGY } from 'component/providers/AccessProvider/permissions';
 | 
			
		||||
import { Dialog, styled } from '@mui/material';
 | 
			
		||||
import { FeatureStrategyMenuCards } from './FeatureStrategyMenuCards/FeatureStrategyMenuCards.tsx';
 | 
			
		||||
import { LegacyFeatureStrategyMenuCards } from './LegacyFeatureStrategyMenuCards/LegacyFeatureStrategyMenuCards.tsx';
 | 
			
		||||
import { formatCreateStrategyPath } from '../FeatureStrategyCreate/FeatureStrategyCreate.tsx';
 | 
			
		||||
import MoreVert from '@mui/icons-material/MoreVert';
 | 
			
		||||
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
 | 
			
		||||
@ -20,6 +20,8 @@ import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
 | 
			
		||||
import { formatUnknownError } from 'utils/formatUnknownError';
 | 
			
		||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
 | 
			
		||||
import { ReleasePlanReviewDialog } from '../../FeatureView/FeatureOverview/ReleasePlan/ReleasePlanReviewDialog.tsx';
 | 
			
		||||
import { FeatureStrategyMenuCards } from './FeatureStrategyMenuCards/FeatureStrategyMenuCards.tsx';
 | 
			
		||||
import { useUiFlag } from 'hooks/useUiFlag.ts';
 | 
			
		||||
 | 
			
		||||
interface IFeatureStrategyMenuProps {
 | 
			
		||||
    label: string;
 | 
			
		||||
@ -77,6 +79,7 @@ export const FeatureStrategyMenu = ({
 | 
			
		||||
    const { isEnterprise } = useUiConfig();
 | 
			
		||||
    const displayReleasePlanButton = isEnterprise();
 | 
			
		||||
    const crProtected = isChangeRequestConfigured(environmentId);
 | 
			
		||||
    const newStrategyModalEnabled = useUiFlag('newStrategyModal');
 | 
			
		||||
 | 
			
		||||
    const onClose = () => {
 | 
			
		||||
        setIsStrategyMenuDialogOpen(false);
 | 
			
		||||
@ -158,32 +161,13 @@ export const FeatureStrategyMenu = ({
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <StyledStrategyMenu onClick={(event) => event.stopPropagation()}>
 | 
			
		||||
            <>
 | 
			
		||||
                {displayReleasePlanButton ? (
 | 
			
		||||
                    <PermissionButton
 | 
			
		||||
                        data-testid='ADD_TEMPLATE_BUTTON'
 | 
			
		||||
                        permission={CREATE_FEATURE_STRATEGY}
 | 
			
		||||
                        projectId={projectId}
 | 
			
		||||
                        environmentId={environmentId}
 | 
			
		||||
                        onClick={openReleasePlans}
 | 
			
		||||
                        aria-labelledby={dialogId}
 | 
			
		||||
                        variant='outlined'
 | 
			
		||||
                        sx={{ minWidth: matchWidth ? '282px' : 'auto' }}
 | 
			
		||||
                        disabled={Boolean(disableReason)}
 | 
			
		||||
                        tooltipProps={{
 | 
			
		||||
                            title: disableReason ? disableReason : undefined,
 | 
			
		||||
                        }}
 | 
			
		||||
                    >
 | 
			
		||||
                        Use template
 | 
			
		||||
                    </PermissionButton>
 | 
			
		||||
                ) : null}
 | 
			
		||||
 | 
			
		||||
            {newStrategyModalEnabled ? (
 | 
			
		||||
                <PermissionButton
 | 
			
		||||
                    data-testid='ADD_STRATEGY_BUTTON'
 | 
			
		||||
                    permission={CREATE_FEATURE_STRATEGY}
 | 
			
		||||
                    projectId={projectId}
 | 
			
		||||
                    environmentId={environmentId}
 | 
			
		||||
                    onClick={openDefaultStrategyCreationModal}
 | 
			
		||||
                    onClick={openMoreStrategies}
 | 
			
		||||
                    aria-labelledby={dialogId}
 | 
			
		||||
                    variant={variant}
 | 
			
		||||
                    sx={{ minWidth: matchWidth ? '282px' : 'auto' }}
 | 
			
		||||
@ -192,26 +176,66 @@ export const FeatureStrategyMenu = ({
 | 
			
		||||
                        title: disableReason ? disableReason : undefined,
 | 
			
		||||
                    }}
 | 
			
		||||
                >
 | 
			
		||||
                    {label}
 | 
			
		||||
                    Add strategy
 | 
			
		||||
                </PermissionButton>
 | 
			
		||||
            ) : (
 | 
			
		||||
                <>
 | 
			
		||||
                    {displayReleasePlanButton ? (
 | 
			
		||||
                        <PermissionButton
 | 
			
		||||
                            data-testid='ADD_TEMPLATE_BUTTON'
 | 
			
		||||
                            permission={CREATE_FEATURE_STRATEGY}
 | 
			
		||||
                            projectId={projectId}
 | 
			
		||||
                            environmentId={environmentId}
 | 
			
		||||
                            onClick={openReleasePlans}
 | 
			
		||||
                            aria-labelledby={dialogId}
 | 
			
		||||
                            variant='outlined'
 | 
			
		||||
                            sx={{ minWidth: matchWidth ? '282px' : 'auto' }}
 | 
			
		||||
                            disabled={Boolean(disableReason)}
 | 
			
		||||
                            tooltipProps={{
 | 
			
		||||
                                title: disableReason
 | 
			
		||||
                                    ? disableReason
 | 
			
		||||
                                    : undefined,
 | 
			
		||||
                            }}
 | 
			
		||||
                        >
 | 
			
		||||
                            Use template
 | 
			
		||||
                        </PermissionButton>
 | 
			
		||||
                    ) : null}
 | 
			
		||||
 | 
			
		||||
                <StyledAdditionalMenuButton
 | 
			
		||||
                    permission={CREATE_FEATURE_STRATEGY}
 | 
			
		||||
                    projectId={projectId}
 | 
			
		||||
                    environmentId={environmentId}
 | 
			
		||||
                    onClick={openMoreStrategies}
 | 
			
		||||
                    variant='outlined'
 | 
			
		||||
                    hideLockIcon
 | 
			
		||||
                    disabled={Boolean(disableReason)}
 | 
			
		||||
                    tooltipProps={{
 | 
			
		||||
                        title: disableReason
 | 
			
		||||
                            ? disableReason
 | 
			
		||||
                            : 'More strategies',
 | 
			
		||||
                    }}
 | 
			
		||||
                >
 | 
			
		||||
                    <MoreVert />
 | 
			
		||||
                </StyledAdditionalMenuButton>
 | 
			
		||||
            </>
 | 
			
		||||
                    <PermissionButton
 | 
			
		||||
                        data-testid='ADD_STRATEGY_BUTTON'
 | 
			
		||||
                        permission={CREATE_FEATURE_STRATEGY}
 | 
			
		||||
                        projectId={projectId}
 | 
			
		||||
                        environmentId={environmentId}
 | 
			
		||||
                        onClick={openDefaultStrategyCreationModal}
 | 
			
		||||
                        aria-labelledby={dialogId}
 | 
			
		||||
                        variant={variant}
 | 
			
		||||
                        sx={{ minWidth: matchWidth ? '282px' : 'auto' }}
 | 
			
		||||
                        disabled={Boolean(disableReason)}
 | 
			
		||||
                        tooltipProps={{
 | 
			
		||||
                            title: disableReason ? disableReason : undefined,
 | 
			
		||||
                        }}
 | 
			
		||||
                    >
 | 
			
		||||
                        {label}
 | 
			
		||||
                    </PermissionButton>
 | 
			
		||||
 | 
			
		||||
                    <StyledAdditionalMenuButton
 | 
			
		||||
                        permission={CREATE_FEATURE_STRATEGY}
 | 
			
		||||
                        projectId={projectId}
 | 
			
		||||
                        environmentId={environmentId}
 | 
			
		||||
                        onClick={openMoreStrategies}
 | 
			
		||||
                        variant='outlined'
 | 
			
		||||
                        hideLockIcon
 | 
			
		||||
                        disabled={Boolean(disableReason)}
 | 
			
		||||
                        tooltipProps={{
 | 
			
		||||
                            title: disableReason
 | 
			
		||||
                                ? disableReason
 | 
			
		||||
                                : 'More strategies',
 | 
			
		||||
                        }}
 | 
			
		||||
                    >
 | 
			
		||||
                        <MoreVert />
 | 
			
		||||
                    </StyledAdditionalMenuButton>
 | 
			
		||||
                </>
 | 
			
		||||
            )}
 | 
			
		||||
            <Dialog
 | 
			
		||||
                open={isStrategyMenuDialogOpen}
 | 
			
		||||
                onClose={onClose}
 | 
			
		||||
@ -222,22 +246,41 @@ export const FeatureStrategyMenu = ({
 | 
			
		||||
                    },
 | 
			
		||||
                }}
 | 
			
		||||
            >
 | 
			
		||||
                <FeatureStrategyMenuCards
 | 
			
		||||
                    projectId={projectId}
 | 
			
		||||
                    featureId={featureId}
 | 
			
		||||
                    environmentId={environmentId}
 | 
			
		||||
                    onlyReleasePlans={onlyReleasePlans}
 | 
			
		||||
                    onAddReleasePlan={(template) => {
 | 
			
		||||
                        setSelectedTemplate(template);
 | 
			
		||||
                        addReleasePlan(template);
 | 
			
		||||
                    }}
 | 
			
		||||
                    onReviewReleasePlan={(template) => {
 | 
			
		||||
                        setSelectedTemplate(template);
 | 
			
		||||
                        setAddReleasePlanOpen(true);
 | 
			
		||||
                        onClose();
 | 
			
		||||
                    }}
 | 
			
		||||
                    onClose={onClose}
 | 
			
		||||
                />
 | 
			
		||||
                {newStrategyModalEnabled ? (
 | 
			
		||||
                    <FeatureStrategyMenuCards
 | 
			
		||||
                        projectId={projectId}
 | 
			
		||||
                        featureId={featureId}
 | 
			
		||||
                        environmentId={environmentId}
 | 
			
		||||
                        onlyReleasePlans={onlyReleasePlans}
 | 
			
		||||
                        onAddReleasePlan={(template) => {
 | 
			
		||||
                            setSelectedTemplate(template);
 | 
			
		||||
                            addReleasePlan(template);
 | 
			
		||||
                        }}
 | 
			
		||||
                        onReviewReleasePlan={(template) => {
 | 
			
		||||
                            setSelectedTemplate(template);
 | 
			
		||||
                            setAddReleasePlanOpen(true);
 | 
			
		||||
                            onClose();
 | 
			
		||||
                        }}
 | 
			
		||||
                        onClose={onClose}
 | 
			
		||||
                    />
 | 
			
		||||
                ) : (
 | 
			
		||||
                    <LegacyFeatureStrategyMenuCards
 | 
			
		||||
                        projectId={projectId}
 | 
			
		||||
                        featureId={featureId}
 | 
			
		||||
                        environmentId={environmentId}
 | 
			
		||||
                        onlyReleasePlans={onlyReleasePlans}
 | 
			
		||||
                        onAddReleasePlan={(template) => {
 | 
			
		||||
                            setSelectedTemplate(template);
 | 
			
		||||
                            addReleasePlan(template);
 | 
			
		||||
                        }}
 | 
			
		||||
                        onReviewReleasePlan={(template) => {
 | 
			
		||||
                            setSelectedTemplate(template);
 | 
			
		||||
                            setAddReleasePlanOpen(true);
 | 
			
		||||
                            onClose();
 | 
			
		||||
                        }}
 | 
			
		||||
                        onClose={onClose}
 | 
			
		||||
                    />
 | 
			
		||||
                )}
 | 
			
		||||
            </Dialog>
 | 
			
		||||
            {selectedTemplate && (
 | 
			
		||||
                <ReleasePlanReviewDialog
 | 
			
		||||
 | 
			
		||||
@ -204,9 +204,7 @@ export const FeatureStrategyMenuCards = ({
 | 
			
		||||
    return (
 | 
			
		||||
        <GridContainer>
 | 
			
		||||
            <TitleRow>
 | 
			
		||||
                <TitleText variant='h2'>
 | 
			
		||||
                    {onlyReleasePlans ? 'Select template' : 'Add configuration'}
 | 
			
		||||
                </TitleText>
 | 
			
		||||
                <TitleText variant='h2'>Add strategy</TitleText>
 | 
			
		||||
                <IconButton
 | 
			
		||||
                    size='small'
 | 
			
		||||
                    onClick={onClose}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,294 @@
 | 
			
		||||
import { Link, styled, Typography, Box, IconButton } from '@mui/material';
 | 
			
		||||
import { useStrategies } from 'hooks/api/getters/useStrategies/useStrategies';
 | 
			
		||||
import { FeatureStrategyMenuCard } from '../FeatureStrategyMenuCard/FeatureStrategyMenuCard.tsx';
 | 
			
		||||
import { useReleasePlanTemplates } from 'hooks/api/getters/useReleasePlanTemplates/useReleasePlanTemplates';
 | 
			
		||||
import { FeatureReleasePlanCard } from '../FeatureReleasePlanCard/FeatureReleasePlanCard.tsx';
 | 
			
		||||
import type { IReleasePlanTemplate } from 'interfaces/releasePlans';
 | 
			
		||||
import { useNavigate } from 'react-router-dom';
 | 
			
		||||
import CloseIcon from '@mui/icons-material/Close';
 | 
			
		||||
import FactCheckOutlinedIcon from '@mui/icons-material/FactCheckOutlined';
 | 
			
		||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig.ts';
 | 
			
		||||
import { HelpIcon } from 'component/common/HelpIcon/HelpIcon.tsx';
 | 
			
		||||
 | 
			
		||||
interface IFeatureStrategyMenuCardsProps {
 | 
			
		||||
    projectId: string;
 | 
			
		||||
    featureId: string;
 | 
			
		||||
    environmentId: string;
 | 
			
		||||
    onlyReleasePlans: boolean;
 | 
			
		||||
    onAddReleasePlan: (template: IReleasePlanTemplate) => void;
 | 
			
		||||
    onReviewReleasePlan: (template: IReleasePlanTemplate) => void;
 | 
			
		||||
    onClose: () => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const GridContainer = styled(Box)(() => ({
 | 
			
		||||
    width: '100%',
 | 
			
		||||
    display: 'flex',
 | 
			
		||||
    flexDirection: 'column',
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const ScrollableContent = styled(Box)(({ theme }) => ({
 | 
			
		||||
    width: '100%',
 | 
			
		||||
    maxHeight: '70vh',
 | 
			
		||||
    overflowY: 'auto',
 | 
			
		||||
    padding: theme.spacing(4),
 | 
			
		||||
    paddingTop: 0,
 | 
			
		||||
    display: 'flex',
 | 
			
		||||
    flexDirection: 'column',
 | 
			
		||||
    gap: theme.spacing(3),
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const GridSection = styled(Box)(({ theme }) => ({
 | 
			
		||||
    display: 'grid',
 | 
			
		||||
    gridTemplateColumns: 'repeat(2, 1fr)',
 | 
			
		||||
    gap: theme.spacing(1.5),
 | 
			
		||||
    width: '100%',
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const CardWrapper = styled(Box)(() => ({
 | 
			
		||||
    width: '100%',
 | 
			
		||||
    minWidth: 0,
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const TitleRow = styled(Box)(({ theme }) => ({
 | 
			
		||||
    display: 'flex',
 | 
			
		||||
    justifyContent: 'space-between',
 | 
			
		||||
    alignItems: 'center',
 | 
			
		||||
    padding: theme.spacing(4, 4, 2, 4),
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const TitleText = styled(Typography)(({ theme }) => ({
 | 
			
		||||
    fontSize: theme.typography.body1.fontSize,
 | 
			
		||||
    fontWeight: theme.typography.fontWeightBold,
 | 
			
		||||
    margin: 0,
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const SectionTitle = styled(Box)(({ theme }) => ({
 | 
			
		||||
    display: 'flex',
 | 
			
		||||
    alignItems: 'center',
 | 
			
		||||
    gap: theme.spacing(0.5),
 | 
			
		||||
    marginBottom: theme.spacing(1),
 | 
			
		||||
    width: '100%',
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const StyledIcon = styled('span')(({ theme }) => ({
 | 
			
		||||
    width: theme.spacing(3),
 | 
			
		||||
    '& > svg': {
 | 
			
		||||
        fill: theme.palette.primary.main,
 | 
			
		||||
        width: theme.spacing(2.25),
 | 
			
		||||
        height: theme.spacing(2.25),
 | 
			
		||||
    },
 | 
			
		||||
    display: 'flex',
 | 
			
		||||
    alignItems: 'center',
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const EmptyStateContainer = styled(Box)(({ theme }) => ({
 | 
			
		||||
    display: 'flex',
 | 
			
		||||
    flexDirection: 'column',
 | 
			
		||||
    alignItems: 'flex-start',
 | 
			
		||||
    justifyContent: 'flex-start',
 | 
			
		||||
    backgroundColor: theme.palette.neutral.light,
 | 
			
		||||
    borderRadius: theme.shape.borderRadiusMedium,
 | 
			
		||||
    padding: theme.spacing(3),
 | 
			
		||||
    width: 'auto',
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const EmptyStateTitle = styled(Typography)(({ theme }) => ({
 | 
			
		||||
    fontSize: theme.typography.caption.fontSize,
 | 
			
		||||
    fontWeight: theme.typography.fontWeightBold,
 | 
			
		||||
    marginBottom: theme.spacing(1),
 | 
			
		||||
    display: 'flex',
 | 
			
		||||
    alignItems: 'center',
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const EmptyStateDescription = styled(Typography)(({ theme }) => ({
 | 
			
		||||
    fontSize: theme.typography.caption.fontSize,
 | 
			
		||||
    color: theme.palette.text.secondary,
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const ClickableBoldText = styled(Link)(({ theme }) => ({
 | 
			
		||||
    fontWeight: theme.typography.fontWeightBold,
 | 
			
		||||
    cursor: 'pointer',
 | 
			
		||||
    '&:hover': {
 | 
			
		||||
        textDecoration: 'underline',
 | 
			
		||||
    },
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
export const LegacyFeatureStrategyMenuCards = ({
 | 
			
		||||
    projectId,
 | 
			
		||||
    featureId,
 | 
			
		||||
    environmentId,
 | 
			
		||||
    onlyReleasePlans,
 | 
			
		||||
    onAddReleasePlan,
 | 
			
		||||
    onReviewReleasePlan,
 | 
			
		||||
    onClose,
 | 
			
		||||
}: IFeatureStrategyMenuCardsProps) => {
 | 
			
		||||
    const { isEnterprise } = useUiConfig();
 | 
			
		||||
 | 
			
		||||
    const { strategies } = useStrategies();
 | 
			
		||||
    const { templates } = useReleasePlanTemplates();
 | 
			
		||||
    const navigate = useNavigate();
 | 
			
		||||
 | 
			
		||||
    const activeStrategies = strategies.filter(
 | 
			
		||||
        (strategy) => !strategy.deprecated,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const standardStrategies = activeStrategies.filter(
 | 
			
		||||
        (strategy) => !strategy.advanced && !strategy.editable,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const advancedAndCustomStrategies = activeStrategies.filter(
 | 
			
		||||
        (strategy) => strategy.editable || strategy.advanced,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const defaultStrategy = {
 | 
			
		||||
        name: 'flexibleRollout',
 | 
			
		||||
        displayName: 'Default strategy',
 | 
			
		||||
        description:
 | 
			
		||||
            'This is the default strategy defined for this environment in the project',
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const renderReleasePlanTemplates = () => {
 | 
			
		||||
        if (!isEnterprise()) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return (
 | 
			
		||||
            <Box>
 | 
			
		||||
                <SectionTitle>
 | 
			
		||||
                    <Typography color='inherit' variant='body2'>
 | 
			
		||||
                        Release templates
 | 
			
		||||
                    </Typography>
 | 
			
		||||
                    <HelpIcon
 | 
			
		||||
                        tooltip='Use a predefined template to roll out features to users'
 | 
			
		||||
                        size='16px'
 | 
			
		||||
                    />
 | 
			
		||||
                </SectionTitle>
 | 
			
		||||
                {!templates.length ? (
 | 
			
		||||
                    <EmptyStateContainer>
 | 
			
		||||
                        <EmptyStateTitle>
 | 
			
		||||
                            <StyledIcon>
 | 
			
		||||
                                <FactCheckOutlinedIcon />
 | 
			
		||||
                            </StyledIcon>
 | 
			
		||||
                            Create your own release templates
 | 
			
		||||
                        </EmptyStateTitle>
 | 
			
		||||
                        <EmptyStateDescription>
 | 
			
		||||
                            Standardize your rollouts and save time by reusing
 | 
			
		||||
                            predefined strategies. Find release templates in the
 | 
			
		||||
                            side menu under{' '}
 | 
			
		||||
                            <ClickableBoldText
 | 
			
		||||
                                onClick={() => navigate('/release-templates')}
 | 
			
		||||
                            >
 | 
			
		||||
                                Configure > Release templates
 | 
			
		||||
                            </ClickableBoldText>
 | 
			
		||||
                        </EmptyStateDescription>
 | 
			
		||||
                    </EmptyStateContainer>
 | 
			
		||||
                ) : (
 | 
			
		||||
                    <GridSection>
 | 
			
		||||
                        {templates.map((template) => (
 | 
			
		||||
                            <CardWrapper key={template.id}>
 | 
			
		||||
                                <FeatureReleasePlanCard
 | 
			
		||||
                                    template={template}
 | 
			
		||||
                                    onClick={() => onAddReleasePlan(template)}
 | 
			
		||||
                                    onPreviewClick={() =>
 | 
			
		||||
                                        onReviewReleasePlan(template)
 | 
			
		||||
                                    }
 | 
			
		||||
                                />
 | 
			
		||||
                            </CardWrapper>
 | 
			
		||||
                        ))}
 | 
			
		||||
                    </GridSection>
 | 
			
		||||
                )}
 | 
			
		||||
            </Box>
 | 
			
		||||
        );
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <GridContainer>
 | 
			
		||||
            <TitleRow>
 | 
			
		||||
                <TitleText variant='h2'>
 | 
			
		||||
                    {onlyReleasePlans ? 'Select template' : 'Add configuration'}
 | 
			
		||||
                </TitleText>
 | 
			
		||||
                <IconButton
 | 
			
		||||
                    size='small'
 | 
			
		||||
                    onClick={onClose}
 | 
			
		||||
                    edge='end'
 | 
			
		||||
                    aria-label='close'
 | 
			
		||||
                >
 | 
			
		||||
                    <CloseIcon fontSize='small' />
 | 
			
		||||
                </IconButton>
 | 
			
		||||
            </TitleRow>
 | 
			
		||||
            <ScrollableContent>
 | 
			
		||||
                {onlyReleasePlans ? (
 | 
			
		||||
                    renderReleasePlanTemplates()
 | 
			
		||||
                ) : (
 | 
			
		||||
                    <>
 | 
			
		||||
                        <Box>
 | 
			
		||||
                            <SectionTitle>
 | 
			
		||||
                                <Typography color='inherit' variant='body2'>
 | 
			
		||||
                                    Standard strategies
 | 
			
		||||
                                </Typography>
 | 
			
		||||
                                <HelpIcon
 | 
			
		||||
                                    tooltip='Standard strategies let you enable a feature only for a specified audience. Select a starting setup, then customize your strategy with targeting and variants.'
 | 
			
		||||
                                    size='16px'
 | 
			
		||||
                                />
 | 
			
		||||
                            </SectionTitle>
 | 
			
		||||
                            <GridSection>
 | 
			
		||||
                                <CardWrapper key={defaultStrategy.name}>
 | 
			
		||||
                                    <FeatureStrategyMenuCard
 | 
			
		||||
                                        projectId={projectId}
 | 
			
		||||
                                        featureId={featureId}
 | 
			
		||||
                                        environmentId={environmentId}
 | 
			
		||||
                                        strategy={defaultStrategy}
 | 
			
		||||
                                        defaultStrategy
 | 
			
		||||
                                        onClose={onClose}
 | 
			
		||||
                                    />
 | 
			
		||||
                                </CardWrapper>
 | 
			
		||||
                                {standardStrategies.map((strategy) => (
 | 
			
		||||
                                    <CardWrapper key={strategy.name}>
 | 
			
		||||
                                        <FeatureStrategyMenuCard
 | 
			
		||||
                                            projectId={projectId}
 | 
			
		||||
                                            featureId={featureId}
 | 
			
		||||
                                            environmentId={environmentId}
 | 
			
		||||
                                            strategy={strategy}
 | 
			
		||||
                                            onClose={onClose}
 | 
			
		||||
                                        />
 | 
			
		||||
                                    </CardWrapper>
 | 
			
		||||
                                ))}
 | 
			
		||||
                            </GridSection>
 | 
			
		||||
                        </Box>
 | 
			
		||||
                        {renderReleasePlanTemplates()}
 | 
			
		||||
                        {advancedAndCustomStrategies.length > 0 && (
 | 
			
		||||
                            <Box>
 | 
			
		||||
                                <SectionTitle>
 | 
			
		||||
                                    <Typography color='inherit' variant='body2'>
 | 
			
		||||
                                        Custom and advanced strategies
 | 
			
		||||
                                    </Typography>
 | 
			
		||||
                                    <HelpIcon
 | 
			
		||||
                                        tooltip='Advanced strategies let you target based on specific properties. Custom activation strategies let you define your own activation strategies to use with Unleash.'
 | 
			
		||||
                                        size='16px'
 | 
			
		||||
                                    />
 | 
			
		||||
                                </SectionTitle>
 | 
			
		||||
                                <GridSection>
 | 
			
		||||
                                    {advancedAndCustomStrategies.map(
 | 
			
		||||
                                        (strategy) => (
 | 
			
		||||
                                            <CardWrapper key={strategy.name}>
 | 
			
		||||
                                                <FeatureStrategyMenuCard
 | 
			
		||||
                                                    projectId={projectId}
 | 
			
		||||
                                                    featureId={featureId}
 | 
			
		||||
                                                    environmentId={
 | 
			
		||||
                                                        environmentId
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                    strategy={strategy}
 | 
			
		||||
                                                    onClose={onClose}
 | 
			
		||||
                                                />
 | 
			
		||||
                                            </CardWrapper>
 | 
			
		||||
                                        ),
 | 
			
		||||
                                    )}
 | 
			
		||||
                                </GridSection>
 | 
			
		||||
                            </Box>
 | 
			
		||||
                        )}
 | 
			
		||||
                    </>
 | 
			
		||||
                )}
 | 
			
		||||
            </ScrollableContent>
 | 
			
		||||
        </GridContainer>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
@ -87,6 +87,7 @@ export type UiFlags = {
 | 
			
		||||
    customMetrics?: boolean;
 | 
			
		||||
    impactMetrics?: boolean;
 | 
			
		||||
    lifecycleGraphs?: boolean;
 | 
			
		||||
    newStrategyModal?: boolean;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export interface IVersionInfo {
 | 
			
		||||
 | 
			
		||||
@ -57,7 +57,8 @@ export type IFlagKey =
 | 
			
		||||
    | 'lifecycleGraphs'
 | 
			
		||||
    | 'etagByEnv'
 | 
			
		||||
    | 'fetchMode'
 | 
			
		||||
    | 'optimizeLifecycle';
 | 
			
		||||
    | 'optimizeLifecycle'
 | 
			
		||||
    | 'newStrategyModal';
 | 
			
		||||
 | 
			
		||||
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
 | 
			
		||||
 | 
			
		||||
@ -263,6 +264,10 @@ const flags: IFlags = {
 | 
			
		||||
            false,
 | 
			
		||||
        ),
 | 
			
		||||
    },
 | 
			
		||||
    newStrategyModal: parseEnvVarBoolean(
 | 
			
		||||
        process.env.UNLEASH_EXPERIMENTAL_NEW_STRATEGY_MODAL,
 | 
			
		||||
        false,
 | 
			
		||||
    ),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const defaultExperimentalOptions: IExperimentalOptions = {
 | 
			
		||||
 | 
			
		||||
@ -53,6 +53,7 @@ process.nextTick(async () => {
 | 
			
		||||
                        customMetrics: true,
 | 
			
		||||
                        impactMetrics: true,
 | 
			
		||||
                        lifecycleGraphs: true,
 | 
			
		||||
                        newStrategyModal: true,
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
                authentication: {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user