1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-05-26 01:17:00 +02:00

chore: remove split button strategy flag (#4245)

This commit is contained in:
Jaanus Sellin 2023-07-14 14:23:23 +03:00 committed by GitHub
parent 8de7dfc488
commit 4cd4153412
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 26 additions and 381 deletions

View File

@ -14,8 +14,6 @@ import { ILegalValue } from 'interfaces/context';
import { ContextFormChip } from 'component/context/ContectFormChip/ContextFormChip';
import { ContextFormChipList } from 'component/context/ContectFormChip/ContextFormChipList';
import { ContextFieldUsage } from '../ContextFieldUsage/ContextFieldUsage';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
interface IContextForm {
contextName: string;
@ -104,7 +102,6 @@ export const ContextForm: React.FC<IContextForm> = ({
const [value, setValue] = useState('');
const [valueDesc, setValueDesc] = useState('');
const [valueFocused, setValueFocused] = useState(false);
const { uiConfig } = useUiConfig();
const isMissingValue = valueDesc.trim() && !value.trim();

View File

@ -24,7 +24,6 @@ import { ContextActionsCell } from '../ContextActionsCell';
import { Adjust } from '@mui/icons-material';
import { IconCell } from 'component/common/Table/cells/IconCell/IconCell';
import { Search } from 'component/common/Search/Search';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { UsedInCell } from '../UsedInCell';
const ContextList: VFC = () => {
@ -32,7 +31,6 @@ const ContextList: VFC = () => {
const [name, setName] = useState<string>();
const { context, refetchUnleashContext, loading } = useUnleashContext();
const { removeContext } = useContextsApi();
const { uiConfig } = useUiConfig();
const { setToastData, setToastApiError } = useToast();
const data = useMemo(() => {

View File

@ -1,130 +0,0 @@
import { ElementType, FC } from 'react';
import { Card, CardContent, Typography, styled, Box } from '@mui/material';
import { ChangeRequestDialogue } from 'component/changeRequest/ChangeRequestConfirmDialog/ChangeRequestConfirmDialog';
import useFeatureStrategyApi from 'hooks/api/actions/useFeatureStrategyApi/useFeatureStrategyApi';
import useToast from 'hooks/useToast';
import { AddStrategyMessage } from 'component/changeRequest/ChangeRequestConfirmDialog/ChangeRequestMessages/AddStrategyMessage';
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
import { useChangeRequestAddStrategy } from 'hooks/useChangeRequestAddStrategy';
import { formatUnknownError } from 'utils/formatUnknownError';
import PermissionButton from 'component/common/PermissionButton/PermissionButton';
import { CREATE_FEATURE_STRATEGY } from 'component/providers/AccessProvider/permissions';
import { IFeatureStrategyPayload } from 'interfaces/strategy';
interface IAddFromTemplateCardProps {
title: string;
featureId: string;
projectId: string;
environmentId: string;
strategy: IFeatureStrategyPayload;
Icon: ElementType;
onAfterAddStrategy: () => void;
}
const StyledCard = styled(Card)(({ theme }) => ({
display: 'flex',
flexDirection: 'column',
borderRadius: theme.shape.borderRadiusMedium,
}));
export const AddFromTemplateCard: FC<IAddFromTemplateCardProps> = ({
title,
children,
featureId,
projectId,
environmentId,
strategy,
Icon,
onAfterAddStrategy,
}) => {
const { addStrategyToFeature } = useFeatureStrategyApi();
const { setToastApiError } = useToast();
const { isChangeRequestConfigured } = useChangeRequestsEnabled(projectId);
const {
changeRequestDialogDetails,
onChangeRequestAddStrategy,
onChangeRequestAddStrategyConfirm,
onChangeRequestAddStrategyClose,
} = useChangeRequestAddStrategy(projectId, featureId, 'addStrategy');
const onStrategyAdd = async () => {
try {
if (isChangeRequestConfigured(environmentId)) {
onChangeRequestAddStrategy(environmentId, strategy);
} else {
await addStrategyToFeature(
projectId,
featureId,
environmentId,
strategy
);
onAfterAddStrategy();
}
} catch (error) {
setToastApiError(formatUnknownError(error));
}
};
return (
<>
<StyledCard variant="outlined">
<CardContent
sx={{
display: 'flex',
flexDirection: 'column',
flexGrow: 1,
}}
>
<Typography
variant="body1"
fontWeight="medium"
sx={{ mb: 0.5, display: 'flex', alignItems: 'center' }}
>
<Icon color="disabled" sx={{ mr: 1 }} /> {title}
</Typography>
<Typography
variant="body2"
color="text.secondary"
component="p"
>
{children}
</Typography>
<Box
sx={{
ml: 'auto',
mt: 'auto',
pt: 1,
mr: { xs: 'auto', sm: 0 },
}}
>
<PermissionButton
permission={CREATE_FEATURE_STRATEGY}
projectId={projectId}
environmentId={environmentId}
variant="outlined"
size="small"
onClick={onStrategyAdd}
>
Use template
</PermissionButton>
</Box>
</CardContent>
</StyledCard>
<ChangeRequestDialogue
isOpen={changeRequestDialogDetails.isOpen}
onClose={onChangeRequestAddStrategyClose}
environment={changeRequestDialogDetails?.environment}
onConfirm={onChangeRequestAddStrategyConfirm}
messageComponent={
<AddStrategyMessage
environment={environmentId}
payload={changeRequestDialogDetails.strategy!}
/>
}
/>
</>
);
};

View File

@ -1,6 +1,5 @@
import { Link } from 'react-router-dom';
import { Box, styled } from '@mui/material';
import { SectionSeparator } from 'component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/SectionSeparator/SectionSeparator';
import useFeatureStrategyApi from 'hooks/api/actions/useFeatureStrategyApi/useFeatureStrategyApi';
import useToast from 'hooks/useToast';
import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
@ -12,11 +11,7 @@ import { useChangeRequestAddStrategy } from 'hooks/useChangeRequestAddStrategy';
import { ChangeRequestDialogue } from 'component/changeRequest/ChangeRequestConfirmDialog/ChangeRequestConfirmDialog';
import { CopyStrategiesMessage } from 'component/changeRequest/ChangeRequestConfirmDialog/ChangeRequestMessages/CopyStrategiesMessage';
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
import { getFeatureStrategyIcon } from 'utils/strategyNames';
import { AddFromTemplateCard } from './AddFromTemplateCard/AddFromTemplateCard';
import { FeatureStrategyMenu } from '../FeatureStrategyMenu/FeatureStrategyMenu';
import { LegacyFeatureStrategyMenu } from '../FeatureStrategyMenu/LegacyFeatureStrategyMenu';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
interface IFeatureStrategyEmptyProps {
projectId: string;
@ -78,9 +73,6 @@ export const FeatureStrategyEmpty = ({
onChangeRequestAddStrategyClose,
} = useChangeRequestAddStrategy(projectId, featureId, 'addStrategy');
const { uiConfig } = useUiConfig();
const strategySplittedButton = uiConfig?.flags?.strategySplittedButton;
const onAfterAddStrategy = (multiple = false) => {
refetchFeature();
refetchFeatureImmutable();
@ -171,26 +163,12 @@ export const FeatureStrategyEmpty = ({
justifyContent: 'center',
}}
>
<ConditionallyRender
condition={Boolean(strategySplittedButton)}
show={
<FeatureStrategyMenu
label="Add your first strategy"
projectId={projectId}
featureId={featureId}
environmentId={environmentId}
matchWidth={canCopyFromOtherEnvironment}
/>
}
elseShow={
<LegacyFeatureStrategyMenu
label="Add your first strategy"
projectId={projectId}
featureId={featureId}
environmentId={environmentId}
matchWidth={canCopyFromOtherEnvironment}
/>
}
<FeatureStrategyMenu
label="Add your first strategy"
projectId={projectId}
featureId={featureId}
environmentId={environmentId}
matchWidth={canCopyFromOtherEnvironment}
/>
<ConditionallyRender
condition={canCopyFromOtherEnvironment}
@ -205,67 +183,6 @@ export const FeatureStrategyEmpty = ({
}
/>
</Box>
<ConditionallyRender
condition={strategySplittedButton === false}
show={
<>
<Box sx={{ width: '100%', mt: 3 }}>
<SectionSeparator>
Or use a strategy template
</SectionSeparator>
</Box>
<Box
sx={{
display: 'grid',
width: '100%',
gap: 2,
gridTemplateColumns: {
xs: '1fr',
sm: '1fr 1fr',
},
}}
>
<AddFromTemplateCard
title="Standard strategy"
projectId={projectId}
featureId={featureId}
environmentId={environmentId}
onAfterAddStrategy={onAfterAddStrategy}
Icon={getFeatureStrategyIcon('default')}
strategy={{
name: 'default',
parameters: {},
constraints: [],
}}
>
The standard strategy is strictly on/off for
your entire userbase.
</AddFromTemplateCard>
<AddFromTemplateCard
title="Gradual rollout"
projectId={projectId}
featureId={featureId}
environmentId={environmentId}
onAfterAddStrategy={onAfterAddStrategy}
Icon={getFeatureStrategyIcon(
'flexibleRollout'
)}
strategy={{
name: 'flexibleRollout',
parameters: {
rollout: '50',
stickiness: 'default',
groupId: feature.name,
},
constraints: [],
}}
>
Roll out to a percentage of your userbase.
</AddFromTemplateCard>
</Box>
</>
}
/>
</StyledContainer>
</>
);

View File

@ -1,70 +0,0 @@
import React, { useState } from 'react';
import PermissionButton, {
IPermissionButtonProps,
} from 'component/common/PermissionButton/PermissionButton';
import { CREATE_FEATURE_STRATEGY } from 'component/providers/AccessProvider/permissions';
import { Popover } from '@mui/material';
import { FeatureStrategyMenuCards } from './FeatureStrategyMenuCards/FeatureStrategyMenuCards';
interface IFeatureStrategyMenuProps {
label: string;
projectId: string;
featureId: string;
environmentId: string;
variant?: IPermissionButtonProps['variant'];
matchWidth?: boolean;
}
/**
* Remove when removing feature flag strategySplittedButton
* @deprecated
*/
export const LegacyFeatureStrategyMenu = ({
label,
projectId,
featureId,
environmentId,
variant,
matchWidth,
}: IFeatureStrategyMenuProps) => {
const [anchor, setAnchor] = useState<Element>();
const isPopoverOpen = Boolean(anchor);
const popoverId = isPopoverOpen ? 'FeatureStrategyMenuPopover' : undefined;
const onClose = () => {
setAnchor(undefined);
};
const onClick = (event: React.SyntheticEvent) => {
setAnchor(event.currentTarget);
};
return (
<div onClick={event => event.stopPropagation()}>
<PermissionButton
permission={CREATE_FEATURE_STRATEGY}
projectId={projectId}
environmentId={environmentId}
onClick={onClick}
aria-labelledby={popoverId}
variant={variant}
sx={{ minWidth: matchWidth ? '282px' : 'auto' }}
>
{label}
</PermissionButton>
<Popover
id={popoverId}
open={isPopoverOpen}
anchorEl={anchor}
onClose={onClose}
onClick={onClose}
>
<FeatureStrategyMenuCards
projectId={projectId}
featureId={featureId}
environmentId={environmentId}
/>
</Popover>
</div>
);
};

View File

@ -17,7 +17,6 @@ import EnvironmentAccordionBody from './EnvironmentAccordionBody/EnvironmentAcco
import { EnvironmentFooter } from './EnvironmentFooter/EnvironmentFooter';
import FeatureOverviewEnvironmentMetrics from './FeatureOverviewEnvironmentMetrics/FeatureOverviewEnvironmentMetrics';
import { FeatureStrategyMenu } from 'component/feature/FeatureStrategy/FeatureStrategyMenu/FeatureStrategyMenu';
import { LegacyFeatureStrategyMenu } from 'component/feature/FeatureStrategy/FeatureStrategyMenu/LegacyFeatureStrategyMenu';
import { FEATURE_ENVIRONMENT_ACCORDION } from 'utils/testIds';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import { FeatureStrategyIcons } from 'component/feature/FeatureStrategy/FeatureStrategyIcons/FeatureStrategyIcons';
@ -106,19 +105,6 @@ const StyledStringTruncator = styled(StringTruncator)(({ theme }) => ({
},
}));
/**
* @deprecated
*/
const LegacyStyledButtonContainer = styled('div')(({ theme }) => ({
display: 'flex',
alignItems: 'center',
marginLeft: '1.8rem',
[theme.breakpoints.down(560)]: {
flexDirection: 'column',
marginLeft: '0',
},
}));
const StyledButtonContainer = styled('div')(({ theme }) => ({
display: 'flex',
alignItems: 'center',
@ -138,8 +124,6 @@ const FeatureOverviewEnvironment = ({
const { metrics } = useFeatureMetrics(projectId, featureId);
const { feature } = useFeature(projectId, featureId);
const { value: globalStore } = useGlobalLocalStorage();
const { uiConfig } = useUiConfig();
const strategySplittedButton = uiConfig?.flags?.strategySplittedButton;
const featureMetrics = getFeatureMetrics(feature?.environments, metrics);
const environmentMetric = featureMetrics.find(
@ -189,42 +173,21 @@ const FeatureOverviewEnvironment = ({
}
/>
</StyledHeaderTitle>
<ConditionallyRender
condition={Boolean(strategySplittedButton)}
show={
<StyledButtonContainer>
<FeatureStrategyMenu
label="Add strategy"
projectId={projectId}
featureId={featureId}
environmentId={env.name}
variant="outlined"
size="small"
/>
<FeatureStrategyIcons
strategies={
featureEnvironment?.strategies
}
/>
</StyledButtonContainer>
}
elseShow={
<LegacyStyledButtonContainer>
<LegacyFeatureStrategyMenu
label="Add strategy"
projectId={projectId}
featureId={featureId}
environmentId={env.name}
variant="text"
/>
<FeatureStrategyIcons
strategies={
featureEnvironment?.strategies
}
/>
</LegacyStyledButtonContainer>
}
/>
<StyledButtonContainer>
<FeatureStrategyMenu
label="Add strategy"
projectId={projectId}
featureId={featureId}
environmentId={env.name}
variant="outlined"
size="small"
/>
<FeatureStrategyIcons
strategies={
featureEnvironment?.strategies
}
/>
</StyledButtonContainer>
</StyledHeader>
<FeatureOverviewEnvironmentMetrics
@ -255,26 +218,11 @@ const FeatureOverviewEnvironment = ({
py: 1,
}}
>
<ConditionallyRender
condition={Boolean(
strategySplittedButton
)}
show={
<FeatureStrategyMenu
label="Add strategy"
projectId={projectId}
featureId={featureId}
environmentId={env.name}
/>
}
elseShow={
<LegacyFeatureStrategyMenu
label="Add strategy"
projectId={projectId}
featureId={featureId}
environmentId={env.name}
/>
}
<FeatureStrategyMenu
label="Add strategy"
projectId={projectId}
featureId={featureId}
environmentId={env.name}
/>
</Box>
<EnvironmentFooter

View File

@ -1,4 +1,3 @@
import { useNavigate } from 'react-router-dom';
import FormTemplate from 'component/common/FormTemplate/FormTemplate';
import { UPDATE_PROJECT } from 'component/providers/AccessProvider/permissions';
import useProjectApi from 'hooks/api/actions/useProjectApi/useProjectApi';
@ -10,7 +9,6 @@ import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import { useContext } from 'react';
import AccessContext from 'contexts/AccessContext';
import { Alert } from '@mui/material';
import { GO_BACK } from 'constants/navigate';
import { useDefaultProjectSettings } from 'hooks/useDefaultProjectSettings';
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
import useProjectForm, {

View File

@ -28,13 +28,11 @@ import { Search } from 'component/common/Search/Search';
import { useConditionallyHiddenColumns } from 'hooks/useConditionallyHiddenColumns';
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
import { useOptionalPathParam } from 'hooks/useOptionalPathParam';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { UsedInCell } from 'component/context/ContextList/UsedInCell';
export const SegmentTable = () => {
const projectId = useOptionalPathParam('projectId');
const { segments, loading } = useSegments();
const { uiConfig } = useUiConfig();
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
const [initialState] = useState({
sortBy: [{ id: 'createdAt' }],

View File

@ -51,7 +51,6 @@ export interface IFlags {
disableNotifications?: boolean;
advancedPlayground?: boolean;
customRootRoles?: boolean;
strategySplittedButton?: boolean;
strategyVariant?: boolean;
newProjectLayout?: boolean;
}

View File

@ -1,5 +1,3 @@
import useUiConfig from '../hooks/api/getters/useUiConfig/useUiConfig';
export const getTogglePath = (projectId: string, featureToggleName: string) => {
return `/projects/${projectId}/features/${featureToggleName}`;
};

View File

@ -95,7 +95,6 @@ exports[`should create default config 1`] = `
"proPlanAutoCharge": false,
"responseTimeWithAppNameKillSwitch": false,
"slackAppAddon": false,
"strategySplittedButton": false,
"strategyVariant": false,
"strictSchemaValidation": false,
},
@ -130,7 +129,6 @@ exports[`should create default config 1`] = `
"proPlanAutoCharge": false,
"responseTimeWithAppNameKillSwitch": false,
"slackAppAddon": false,
"strategySplittedButton": false,
"strategyVariant": false,
"strictSchemaValidation": false,
},

View File

@ -22,7 +22,6 @@ export type IFlagKey =
| 'disableNotifications'
| 'advancedPlayground'
| 'customRootRoles'
| 'strategySplittedButton'
| 'strategyVariant'
| 'newProjectLayout'
| 'slackAppAddon'
@ -83,10 +82,6 @@ const flags: IFlags = {
cleanClientApi: parseEnvVarBoolean(process.env.CLEAN_CLIENT_API, false),
migrationLock: parseEnvVarBoolean(process.env.MIGRATION_LOCK, false),
demo: parseEnvVarBoolean(process.env.UNLEASH_DEMO, false),
strategySplittedButton: parseEnvVarBoolean(
process.env.UNLEASH_STRATEGY_SPLITTED_BUTTON,
false,
),
googleAuthEnabled: parseEnvVarBoolean(
process.env.GOOGLE_AUTH_ENABLED,
false,

View File

@ -38,7 +38,6 @@ process.nextTick(async () => {
anonymiseEventLog: false,
responseTimeWithAppNameKillSwitch: false,
advancedPlayground: true,
strategySplittedButton: true,
strategyVariant: true,
newProjectLayout: true,
emitPotentiallyStaleEvents: true,