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

chore: remove strategyImprovements flag (#4043)

<!-- Thanks for creating a PR! To make it easier for reviewers and
everyone else to understand what your changes relate to, please add some
relevant content to the headings below. Feel free to ignore or delete
sections that you don't think are relevant. Thank you! ❤️ -->
Remove strategy improvements flag 
## About the changes
<!-- Describe the changes introduced. What are they and why are they
being introduced? Feel free to also add screenshots or steps to view the
changes if they're visual. -->

<!-- Does it close an issue? Multiple? -->
Closes #
[1-1048](https://linear.app/unleash/issue/1-1048/remove-strategyimprovements-flag)

<!-- (For internal contributors): Does it relate to an issue on public
roadmap? -->
<!--
Relates to [roadmap](https://github.com/orgs/Unleash/projects/10) item:
#
-->

### Important files
<!-- PRs can contain a lot of changes, but not all changes are equally
important. Where should a reviewer start looking to get an overview of
the changes? Are any files particularly important? -->


## Discussion points
<!-- Anything about the PR you'd like to discuss before it gets merged?
Got any questions or doubts? -->

---------

Signed-off-by: andreas-unleash <andreas@getunleash.ai>
This commit is contained in:
andreas-unleash 2023-06-28 11:38:21 +03:00 committed by GitHub
parent b13f7f8519
commit 5cbbd6f798
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 89 additions and 439 deletions

View File

@ -49,12 +49,6 @@ describe('feature', () => {
}); });
}); });
it('can add a userId strategy to the development environment', () => {
cy.addUserIdStrategyToFeature_UI(featureToggleName).then(() => {
cy.deleteFeatureStrategy_UI(featureToggleName, false);
});
});
it('can add variants to the development environment', () => { it('can add variants to the development environment', () => {
cy.addVariantsToFeature_UI(featureToggleName, [variant1, variant2]); cy.addVariantsToFeature_UI(featureToggleName, [variant1, variant2]);
}); });

View File

@ -221,6 +221,7 @@ export const deleteFeatureStrategy_UI = (
).as('deleteUserStrategy'); ).as('deleteUserStrategy');
cy.visit(`/projects/${project}/features/${featureToggleName}`); cy.visit(`/projects/${project}/features/${featureToggleName}`);
cy.get('[data-testid=FEATURE_ENVIRONMENT_ACCORDION_development]').click(); cy.get('[data-testid=FEATURE_ENVIRONMENT_ACCORDION_development]').click();
cy.get('[data-testid=STRATEGY_REMOVE_MENU_BTN]').first().click();
cy.get('[data-testid=STRATEGY_FORM_REMOVE_ID]').first().click(); cy.get('[data-testid=STRATEGY_FORM_REMOVE_ID]').first().click();
if (!shouldWait) return cy.get('[data-testid=DIALOGUE_CONFIRM_ID]').click(); if (!shouldWait) return cy.get('[data-testid=DIALOGUE_CONFIRM_ID]').click();
else cy.get('[data-testid=DIALOGUE_CONFIRM_ID]').click(); else cy.get('[data-testid=DIALOGUE_CONFIRM_ID]').click();

View File

@ -203,37 +203,54 @@ const strategiesAreDisplayed = async (
await screen.findByText(secondStrategy); await screen.findByText(secondStrategy);
}; };
const getDeleteButtons = async () => {
const removeMenus = screen.getAllByTestId(`STRATEGY_REMOVE_MENU_BTN`);
const deleteButtons: HTMLElement[] = [];
await Promise.all(
removeMenus.map(async menu => {
menu.click();
const removeButton = screen.getAllByTestId(
'STRATEGY_FORM_REMOVE_ID'
);
deleteButtons.push(...removeButton);
})
);
console.log(deleteButtons);
return deleteButtons;
};
const deleteButtonsActiveInChangeRequestEnv = async () => { const deleteButtonsActiveInChangeRequestEnv = async () => {
const deleteButtons = screen.getAllByTestId('STRATEGY_FORM_REMOVE_ID'); const deleteButtons = await getDeleteButtons();
expect(deleteButtons.length).toBe(2); expect(deleteButtons.length).toBe(3);
// wait for change request config to be loaded // wait for change request config to be loaded
await waitFor(() => { await waitFor(() => {
// production // production
const productionStrategyDeleteButton = deleteButtons[0]; const productionStrategyDeleteButton = deleteButtons[1];
expect(productionStrategyDeleteButton).not.toBeDisabled(); expect(productionStrategyDeleteButton).not.toHaveClass('Mui-disabled');
}); });
await waitFor(() => { await waitFor(() => {
// custom env // custom env
const customEnvStrategyDeleteButton = deleteButtons[1]; const customEnvStrategyDeleteButton = deleteButtons[2];
expect(customEnvStrategyDeleteButton).toBeDisabled(); expect(customEnvStrategyDeleteButton).toHaveClass('Mui-disabled');
}); });
}; };
const deleteButtonsInactiveInChangeRequestEnv = async () => { const deleteButtonsInactiveInChangeRequestEnv = async () => {
const deleteButtons = screen.getAllByTestId('STRATEGY_FORM_REMOVE_ID'); const deleteButtons = await getDeleteButtons();
expect(deleteButtons.length).toBe(2); expect(deleteButtons.length).toBe(3);
// wait for change request config to be loaded // wait for change request config to be loaded
await waitFor(() => { await waitFor(() => {
// production // production
const productionStrategyDeleteButton = deleteButtons[0]; const productionStrategyDeleteButton = deleteButtons[1];
expect(productionStrategyDeleteButton).toBeDisabled(); expect(productionStrategyDeleteButton).toHaveClass('Mui-disabled');
}); });
await waitFor(() => { await waitFor(() => {
// custom env // custom env
const customEnvStrategyDeleteButton = deleteButtons[1]; const customEnvStrategyDeleteButton = deleteButtons[2];
expect(customEnvStrategyDeleteButton).toBeDisabled(); expect(customEnvStrategyDeleteButton).toHaveClass('Mui-disabled');
}); });
}; };

View File

@ -2,14 +2,8 @@ import { screen } from '@testing-library/react';
import { render } from 'utils/testRenderer'; import { render } from 'utils/testRenderer';
import { StrategyItemContainer } from './StrategyItemContainer'; import { StrategyItemContainer } from './StrategyItemContainer';
import { IFeatureStrategy } from 'interfaces/strategy'; import { IFeatureStrategy } from 'interfaces/strategy';
import { testServerRoute, testServerSetup } from 'utils/testServer';
import { UIProviderContainer } from '../../providers/UIProvider/UIProviderContainer'; import { UIProviderContainer } from '../../providers/UIProvider/UIProviderContainer';
const server = testServerSetup();
testServerRoute(server, '/api/admin/ui-config', {
flags: { strategyImprovements: true },
});
test('should render strategy name, custom title and description', async () => { test('should render strategy name, custom title and description', async () => {
const strategy: IFeatureStrategy = { const strategy: IFeatureStrategy = {
id: 'irrelevant', id: 'irrelevant',

View File

@ -9,7 +9,6 @@ import {
import StringTruncator from 'component/common/StringTruncator/StringTruncator'; import StringTruncator from 'component/common/StringTruncator/StringTruncator';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { PlaygroundStrategySchema } from 'openapi'; import { PlaygroundStrategySchema } from 'openapi';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { Badge } from '../Badge/Badge'; import { Badge } from '../Badge/Badge';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
@ -105,7 +104,6 @@ export const StrategyItemContainer: FC<IStrategyItemContainerProps> = ({
description, description,
}) => { }) => {
const Icon = getFeatureStrategyIcon(strategy.name); const Icon = getFeatureStrategyIcon(strategy.name);
const { uiConfig } = useUiConfig();
const StrategyHeaderLink: React.FC = const StrategyHeaderLink: React.FC =
'links' in strategy 'links' in strategy
@ -158,11 +156,7 @@ export const StrategyItemContainer: FC<IStrategyItemContainerProps> = ({
text={formatStrategyName(String(strategy.name))} text={formatStrategyName(String(strategy.name))}
/> />
<ConditionallyRender <ConditionallyRender
condition={ condition={Boolean(strategy.title)}
Boolean(
uiConfig?.flags?.strategyImprovements
) && Boolean(strategy.title)
}
show={ show={
<StyledCustomTitle> <StyledCustomTitle>
{formatStrategyName( {formatStrategyName(

View File

@ -94,7 +94,7 @@ export const FeatureStrategyEdit = () => {
const { isChangeRequestConfigured } = useChangeRequestsEnabled(projectId); const { isChangeRequestConfigured } = useChangeRequestsEnabled(projectId);
const { refetch: refetchChangeRequests } = const { refetch: refetchChangeRequests } =
usePendingChangeRequests(projectId); usePendingChangeRequests(projectId);
const { setPreviousTitle, trackTitle } = useTitleTracking(); const { setPreviousTitle } = useTitleTracking();
const { feature, refetchFeature } = useFeature(projectId, featureId); const { feature, refetchFeature } = useFeature(projectId, featureId);
@ -153,11 +153,6 @@ export const FeatureStrategyEdit = () => {
payload payload
); );
if (uiConfig?.flags?.strategyImprovements) {
// NOTE: remove tracking when feature flag is removed
trackTitle(strategy.title);
}
await refetchSavedStrategySegments(); await refetchSavedStrategySegments();
setToastData({ setToastData({
title: 'Strategy updated', title: 'Strategy updated',

View File

@ -211,19 +211,14 @@ export const FeatureStrategyForm = ({
/> />
</FeatureStrategyEnabled> </FeatureStrategyEnabled>
<StyledHr /> <StyledHr />
<ConditionallyRender <FeatureStrategyTitle
condition={Boolean(uiConfig?.flags?.strategyImprovements)} title={strategy.title || ''}
show={ setTitle={title => {
<FeatureStrategyTitle setStrategy(prev => ({
title={strategy.title || ''} ...prev,
setTitle={title => { title,
setStrategy(prev => ({ }));
...prev, }}
title,
}));
}}
/>
}
/> />
<ConditionallyRender <ConditionallyRender
condition={Boolean(uiConfig.flags.SE)} condition={Boolean(uiConfig.flags.SE)}

View File

@ -1,7 +1,6 @@
import { Box, Typography } from '@mui/material'; import { Box, Typography } from '@mui/material';
import Input from 'component/common/Input/Input'; import Input from 'component/common/Input/Input';
import { VFC } from 'react'; import { VFC } from 'react';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
interface IFeatureStrategyTitleProps { interface IFeatureStrategyTitleProps {
title: string; title: string;
@ -12,12 +11,6 @@ export const FeatureStrategyTitle: VFC<IFeatureStrategyTitleProps> = ({
title, title,
setTitle, setTitle,
}) => { }) => {
const { uiConfig } = useUiConfig();
if (!uiConfig.flags.strategyImprovements) {
return null;
}
return ( return (
<Box sx={{ paddingBottom: theme => theme.spacing(2) }}> <Box sx={{ paddingBottom: theme => theme.spacing(2) }}>
<Typography <Typography

View File

@ -2,7 +2,6 @@ import { List, ListItem, styled, Typography } from '@mui/material';
import { useStrategies } from 'hooks/api/getters/useStrategies/useStrategies'; import { useStrategies } from 'hooks/api/getters/useStrategies/useStrategies';
import { FeatureStrategyMenuCard } from '../FeatureStrategyMenuCard/FeatureStrategyMenuCard'; import { FeatureStrategyMenuCard } from '../FeatureStrategyMenuCard/FeatureStrategyMenuCard';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
interface IFeatureStrategyMenuCardsProps { interface IFeatureStrategyMenuCardsProps {
projectId: string; projectId: string;
@ -21,7 +20,6 @@ export const FeatureStrategyMenuCards = ({
environmentId, environmentId,
}: IFeatureStrategyMenuCardsProps) => { }: IFeatureStrategyMenuCardsProps) => {
const { strategies } = useStrategies(); const { strategies } = useStrategies();
const { uiConfig } = useUiConfig();
const preDefinedStrategies = strategies.filter( const preDefinedStrategies = strategies.filter(
strategy => !strategy.deprecated && !strategy.editable strategy => !strategy.deprecated && !strategy.editable
@ -39,25 +37,20 @@ export const FeatureStrategyMenuCards = ({
}; };
return ( return (
<List dense> <List dense>
<ConditionallyRender <>
condition={Boolean(uiConfig.flags.strategyImprovements)} <StyledTypography color="textSecondary">
show={ {environmentId} environment default strategy
<> </StyledTypography>
<StyledTypography color="textSecondary"> <ListItem key={defaultStrategy.name}>
{environmentId} environment default strategy <FeatureStrategyMenuCard
</StyledTypography> projectId={projectId}
<ListItem key={defaultStrategy.name}> featureId={featureId}
<FeatureStrategyMenuCard environmentId={environmentId}
projectId={projectId} strategy={defaultStrategy}
featureId={featureId} defaultStrategy={true}
environmentId={environmentId} />
strategy={defaultStrategy} </ListItem>
defaultStrategy={true} </>
/>
</ListItem>
</>
}
/>
<StyledTypography color="textSecondary"> <StyledTypography color="textSecondary">
Predefined strategy types Predefined strategy types
</StyledTypography> </StyledTypography>

View File

@ -1,258 +0,0 @@
import React, { FC, useState } from 'react';
import useFeatureStrategyApi from 'hooks/api/actions/useFeatureStrategyApi/useFeatureStrategyApi';
import { formatUnknownError } from 'utils/formatUnknownError';
import { useNavigate } from 'react-router-dom';
import useToast from 'hooks/useToast';
import { formatFeaturePath } from 'component/feature/FeatureStrategy/FeatureStrategyEdit/FeatureStrategyEdit';
import { Dialogue } from 'component/common/Dialogue/Dialogue';
import { Alert, styled, Typography } from '@mui/material';
import PermissionButton from 'component/common/PermissionButton/PermissionButton';
import { DELETE_FEATURE_STRATEGY } from 'component/providers/AccessProvider/permissions';
import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
import { STRATEGY_FORM_REMOVE_ID } from 'utils/testIds';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton';
import { Delete } from '@mui/icons-material';
import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi';
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
import { usePendingChangeRequests } from 'hooks/api/getters/usePendingChangeRequests/usePendingChangeRequests';
interface IFeatureStrategyRemoveProps {
projectId: string;
featureId: string;
environmentId: string;
strategyId: string;
disabled?: boolean;
icon?: boolean;
text?: boolean;
}
interface IFeatureStrategyRemoveDialogueProps {
onRemove: (event: React.FormEvent) => Promise<void>;
onClose: () => void;
isOpen: boolean;
}
const RemoveAlert: FC = () => (
<Alert severity="error">
Removing the strategy will change which users receive access to the
feature.
</Alert>
);
const FeatureStrategyRemoveDialogue: FC<
IFeatureStrategyRemoveDialogueProps
> = ({ onRemove, onClose, isOpen }) => {
return (
<Dialogue
title="Are you sure you want to delete this strategy?"
open={isOpen}
primaryButtonText="Remove strategy"
secondaryButtonText="Cancel"
onClick={onRemove}
onClose={onClose}
>
<RemoveAlert />
</Dialogue>
);
};
const MsgContainer = styled('div')(({ theme }) => ({
marginTop: theme.spacing(3),
marginBottom: theme.spacing(1),
}));
const SuggestFeatureStrategyRemoveDialogue: FC<
IFeatureStrategyRemoveDialogueProps
> = ({ onRemove, onClose, isOpen }) => {
return (
<Dialogue
title="Suggest changes"
open={isOpen}
primaryButtonText="Add suggestion to draft"
secondaryButtonText="Cancel"
onClick={onRemove}
onClose={onClose}
>
<RemoveAlert />
<MsgContainer>
<Typography variant="body2" color="text.secondary">
Your suggestion:
</Typography>
</MsgContainer>
<Typography fontWeight="bold">Remove strategy</Typography>
</Dialogue>
);
};
interface IRemoveProps {
projectId: string;
featureId: string;
environmentId: string;
strategyId: string;
}
const useOnRemove = ({
projectId,
featureId,
environmentId,
strategyId,
}: IRemoveProps) => {
const { deleteStrategyFromFeature } = useFeatureStrategyApi();
const { setToastData, setToastApiError } = useToast();
const navigate = useNavigate();
const { refetchFeature } = useFeature(projectId, featureId);
const onRemove = async (event: React.FormEvent) => {
try {
event.preventDefault();
await deleteStrategyFromFeature(
projectId,
featureId,
environmentId,
strategyId
);
setToastData({
title: 'Strategy deleted',
type: 'success',
});
refetchFeature();
navigate(formatFeaturePath(projectId, featureId));
} catch (error: unknown) {
setToastApiError(formatUnknownError(error));
}
};
return onRemove;
};
const useOnSuggestRemove = ({
projectId,
featureId,
environmentId,
strategyId,
}: IRemoveProps) => {
const { addChange } = useChangeRequestApi();
const { refetch: refetchChangeRequests } =
usePendingChangeRequests(projectId);
const { setToastData, setToastApiError } = useToast();
const onSuggestRemove = async (event: React.FormEvent) => {
try {
event.preventDefault();
await addChange(projectId, environmentId, {
action: 'deleteStrategy',
feature: featureId,
payload: {
id: strategyId,
},
});
setToastData({
title: 'Changes added to the draft!',
type: 'success',
});
await refetchChangeRequests();
} catch (error: unknown) {
setToastApiError(formatUnknownError(error));
}
};
return onSuggestRemove;
};
/**
* @deprecated
* TODO: remove when strategyImprovements flag is removed
*/
export const LegacyFeatureStrategyRemove = ({
projectId,
featureId,
environmentId,
strategyId,
disabled,
icon,
text,
}: IFeatureStrategyRemoveProps) => {
const [openDialogue, setOpenDialogue] = useState(false);
const { isChangeRequestConfigured } = useChangeRequestsEnabled(projectId);
const onRemove = useOnRemove({
featureId,
projectId,
strategyId,
environmentId,
});
const onSuggestRemove = useOnSuggestRemove({
featureId,
projectId,
strategyId,
environmentId,
});
return (
<>
<ConditionallyRender
condition={Boolean(icon)}
show={
<PermissionIconButton
onClick={() => setOpenDialogue(true)}
projectId={projectId}
environmentId={environmentId}
disabled={disabled}
permission={DELETE_FEATURE_STRATEGY}
data-testid={STRATEGY_FORM_REMOVE_ID}
tooltipProps={{ title: 'Remove strategy' }}
type="button"
>
<Delete />
<ConditionallyRender
condition={Boolean(text)}
show={
<Typography
variant={'body1'}
color={'text.secondary'}
sx={{ ml: theme => theme.spacing(1) }}
>
Remove
</Typography>
}
/>
</PermissionIconButton>
}
elseShow={
<PermissionButton
onClick={() => setOpenDialogue(true)}
projectId={projectId}
environmentId={environmentId}
disabled={disabled}
permission={DELETE_FEATURE_STRATEGY}
data-testid={STRATEGY_FORM_REMOVE_ID}
color="secondary"
variant="text"
type="button"
>
Remove strategy
</PermissionButton>
}
/>
<ConditionallyRender
condition={isChangeRequestConfigured(environmentId)}
show={
<SuggestFeatureStrategyRemoveDialogue
isOpen={openDialogue}
onClose={() => setOpenDialogue(false)}
onRemove={async e => {
await onSuggestRemove(e);
setOpenDialogue(false);
}}
/>
}
elseShow={
<FeatureStrategyRemoveDialogue
isOpen={openDialogue}
onClose={() => setOpenDialogue(false)}
onRemove={onRemove}
/>
}
/>
</>
);
};

View File

@ -21,6 +21,7 @@ import {
} from '@server/types/permissions'; } from '@server/types/permissions';
import { useHasProjectEnvironmentAccess } from 'hooks/useHasAccess'; import { useHasProjectEnvironmentAccess } from 'hooks/useHasAccess';
import { import {
MENU_STRATEGY_REMOVE,
STRATEGY_FORM_REMOVE_ID, STRATEGY_FORM_REMOVE_ID,
STRATEGY_REMOVE_MENU_BTN, STRATEGY_REMOVE_MENU_BTN,
} from 'utils/testIds'; } from 'utils/testIds';
@ -91,6 +92,7 @@ const MenuStrategyRemove = ({
onClick={handleClose} onClick={handleClose}
transformOrigin={{ horizontal: 'right', vertical: 'top' }} transformOrigin={{ horizontal: 'right', vertical: 'top' }}
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }} anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
data-testid={MENU_STRATEGY_REMOVE}
> >
<Tooltip <Tooltip
title={ title={

View File

@ -11,9 +11,7 @@ import { StrategyExecution } from './StrategyExecution/StrategyExecution';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { CopyStrategyIconMenu } from './CopyStrategyIconMenu/CopyStrategyIconMenu'; import { CopyStrategyIconMenu } from './CopyStrategyIconMenu/CopyStrategyIconMenu';
import { StrategyItemContainer } from 'component/common/StrategyItemContainer/StrategyItemContainer'; import { StrategyItemContainer } from 'component/common/StrategyItemContainer/StrategyItemContainer';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import MenuStrategyRemove from './MenuStrategyRemove/MenuStrategyRemove'; import MenuStrategyRemove from './MenuStrategyRemove/MenuStrategyRemove';
import { LegacyFeatureStrategyRemove } from './LegacyFeatureStrategyRemove';
interface IStrategyItemProps { interface IStrategyItemProps {
environmentId: string; environmentId: string;
@ -34,7 +32,6 @@ export const StrategyItem: FC<IStrategyItemProps> = ({
orderNumber, orderNumber,
headerChildren, headerChildren,
}) => { }) => {
const { uiConfig } = useUiConfig();
const projectId = useRequiredPathParam('projectId'); const projectId = useRequiredPathParam('projectId');
const featureId = useRequiredPathParam('featureId'); const featureId = useRequiredPathParam('featureId');
@ -79,27 +76,11 @@ export const StrategyItem: FC<IStrategyItemProps> = ({
> >
<Edit /> <Edit />
</PermissionIconButton> </PermissionIconButton>
<ConditionallyRender <MenuStrategyRemove
condition={Boolean( projectId={projectId}
uiConfig?.flags?.strategyImprovements featureId={featureId}
)} environmentId={environmentId}
show={() => ( strategy={strategy}
<MenuStrategyRemove
projectId={projectId}
featureId={featureId}
environmentId={environmentId}
strategy={strategy}
/>
)}
elseShow={() => (
<LegacyFeatureStrategyRemove
projectId={projectId}
featureId={featureId}
environmentId={environmentId}
strategyId={strategy.id}
icon
/>
)}
/> />
</> </>
} }

View File

@ -14,8 +14,6 @@ import { useChangeRequestToggle } from 'hooks/useChangeRequestToggle';
import { EnableEnvironmentDialog } from 'component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelEnvironmentSwitches/FeatureOverviewSidePanelEnvironmentSwitch/EnableEnvironmentDialog'; import { EnableEnvironmentDialog } from 'component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelEnvironmentSwitches/FeatureOverviewSidePanelEnvironmentSwitch/EnableEnvironmentDialog';
import { UpdateEnabledMessage } from 'component/changeRequest/ChangeRequestConfirmDialog/ChangeRequestMessages/UpdateEnabledMessage'; import { UpdateEnabledMessage } from 'component/changeRequest/ChangeRequestConfirmDialog/ChangeRequestMessages/UpdateEnabledMessage';
import { ChangeRequestDialogue } from 'component/changeRequest/ChangeRequestConfirmDialog/ChangeRequestConfirmDialog'; import { ChangeRequestDialogue } from 'component/changeRequest/ChangeRequestConfirmDialog/ChangeRequestConfirmDialog';
import useUiConfig from '../../../../../hooks/api/getters/useUiConfig/useUiConfig';
import { usePlausibleTracker } from '../../../../../hooks/usePlausibleTracker';
const StyledBoxContainer = styled(Box)<{ 'data-testid': string }>(() => ({ const StyledBoxContainer = styled(Box)<{ 'data-testid': string }>(() => ({
mx: 'auto', mx: 'auto',
@ -65,13 +63,6 @@ export const FeatureToggleSwitch: VFC<IFeatureToggleSwitchProps> = ({
.find(env => env.name === environmentName) .find(env => env.name === environmentName)
?.strategies.filter(strategy => strategy.disabled).length ?? 0; ?.strategies.filter(strategy => strategy.disabled).length ?? 0;
const { uiConfig } = useUiConfig();
const showStrategyImprovements = Boolean(
uiConfig.flags.strategyImprovements
);
const { trackEvent } = usePlausibleTracker();
const handleToggleEnvironmentOn = async ( const handleToggleEnvironmentOn = async (
shouldActivateDisabled = false shouldActivateDisabled = false
) => { ) => {
@ -125,10 +116,7 @@ export const FeatureToggleSwitch: VFC<IFeatureToggleSwitchProps> = ({
const onClick = async (e: React.MouseEvent) => { const onClick = async (e: React.MouseEvent) => {
if (isChangeRequestConfigured(environmentName)) { if (isChangeRequestConfigured(environmentName)) {
e.preventDefault(); e.preventDefault();
if ( if (featureHasOnlyDisabledStrategies()) {
featureHasOnlyDisabledStrategies() &&
showStrategyImprovements
) {
setShowEnabledDialog(true); setShowEnabledDialog(true);
} else { } else {
onChangeRequestToggle( onChangeRequestToggle(
@ -145,7 +133,7 @@ export const FeatureToggleSwitch: VFC<IFeatureToggleSwitchProps> = ({
return; return;
} }
if (featureHasOnlyDisabledStrategies() && showStrategyImprovements) { if (featureHasOnlyDisabledStrategies()) {
setShowEnabledDialog(true); setShowEnabledDialog(true);
} else { } else {
await handleToggleEnvironmentOn(); await handleToggleEnvironmentOn();
@ -153,11 +141,6 @@ export const FeatureToggleSwitch: VFC<IFeatureToggleSwitchProps> = ({
}; };
const onActivateStrategies = async () => { const onActivateStrategies = async () => {
await trackEvent('strategyImprovements', {
props: {
eventType: 'activate disabled strategies',
},
});
if (isChangeRequestConfigured(environmentName)) { if (isChangeRequestConfigured(environmentName)) {
onChangeRequestToggle( onChangeRequestToggle(
feature.name, feature.name,
@ -172,11 +155,6 @@ export const FeatureToggleSwitch: VFC<IFeatureToggleSwitchProps> = ({
}; };
const onAddDefaultStrategy = async () => { const onAddDefaultStrategy = async () => {
await trackEvent('strategyImprovements', {
props: {
eventType: 'add default strategy',
},
});
if (isChangeRequestConfigured(environmentName)) { if (isChangeRequestConfigured(environmentName)) {
onChangeRequestToggle( onChangeRequestToggle(
feature.name, feature.name,
@ -223,16 +201,14 @@ export const FeatureToggleSwitch: VFC<IFeatureToggleSwitchProps> = ({
onClick={onClick} onClick={onClick}
/> />
</StyledBoxContainer> </StyledBoxContainer>
{showStrategyImprovements && ( <EnableEnvironmentDialog
<EnableEnvironmentDialog isOpen={showEnabledDialog}
isOpen={showEnabledDialog} onClose={() => setShowEnabledDialog(false)}
onClose={() => setShowEnabledDialog(false)} environment={environmentName}
environment={environmentName} disabledStrategiesCount={disabledStrategiesCount}
disabledStrategiesCount={disabledStrategiesCount} onActivateDisabledStrategies={onActivateStrategies}
onActivateDisabledStrategies={onActivateStrategies} onAddDefaultStrategy={onAddDefaultStrategy}
onAddDefaultStrategy={onAddDefaultStrategy} />
/>
)}
<ChangeRequestDialogue <ChangeRequestDialogue
isOpen={changeRequestDialogDetails.isOpen} isOpen={changeRequestDialogDetails.isOpen}
onClose={onChangeRequestToggleClose} onClose={onChangeRequestToggleClose}

View File

@ -145,19 +145,14 @@ export const ProjectDefaultStrategyForm = ({
}; };
return ( return (
<StyledForm onSubmit={onSubmitWithValidation}> <StyledForm onSubmit={onSubmitWithValidation}>
<ConditionallyRender <FeatureStrategyTitle
condition={Boolean(uiConfig?.flags?.strategyImprovements)} title={strategy.title || ''}
show={ setTitle={title => {
<FeatureStrategyTitle setStrategy(prev => ({
title={strategy.title || ''} ...prev,
setTitle={title => { title,
setStrategy(prev => ({ }));
...prev, }}
title,
}));
}}
/>
}
/> />
<ConditionallyRender <ConditionallyRender
condition={Boolean(uiConfig.flags.SE)} condition={Boolean(uiConfig.flags.SE)}

View File

@ -12,13 +12,10 @@ import { ChangeRequestConfiguration } from './ChangeRequestConfiguration/ChangeR
import { ProjectApiAccess } from 'component/project/Project/ProjectSettings/ProjectApiAccess/ProjectApiAccess'; import { ProjectApiAccess } from 'component/project/Project/ProjectSettings/ProjectApiAccess/ProjectApiAccess';
import { ProjectSegments } from './ProjectSegments/ProjectSegments'; import { ProjectSegments } from './ProjectSegments/ProjectSegments';
import { ProjectDefaultStrategySettings } from './ProjectDefaultStrategySettings/ProjectDefaultStrategySettings'; import { ProjectDefaultStrategySettings } from './ProjectDefaultStrategySettings/ProjectDefaultStrategySettings';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
export const ProjectSettings = () => { export const ProjectSettings = () => {
const location = useLocation(); const location = useLocation();
const navigate = useNavigate(); const navigate = useNavigate();
const { uiConfig } = useUiConfig();
const { strategyImprovements } = uiConfig.flags;
const tabs: ITab[] = [ const tabs: ITab[] = [
{ {
@ -41,14 +38,11 @@ export const ProjectSettings = () => {
id: 'api-access', id: 'api-access',
label: 'API access', label: 'API access',
}, },
]; {
if (Boolean(strategyImprovements)) {
tabs.push({
id: 'default-strategy', id: 'default-strategy',
label: 'Default strategy', label: 'Default strategy',
}); },
} ];
const onChange = (tab: ITab) => { const onChange = (tab: ITab) => {
navigate(tab.id); navigate(tab.id);
@ -76,12 +70,10 @@ export const ProjectSettings = () => {
element={<ChangeRequestConfiguration />} element={<ChangeRequestConfiguration />}
/> />
<Route path="api-access/*" element={<ProjectApiAccess />} /> <Route path="api-access/*" element={<ProjectApiAccess />} />
{Boolean(strategyImprovements) && ( <Route
<Route path="default-strategy/*"
path="default-strategy/*" element={<ProjectDefaultStrategySettings />}
element={<ProjectDefaultStrategySettings />} />
/>
)}
<Route <Route
path="*" path="*"
element={<Navigate replace to={tabs[0].id} />} element={<Navigate replace to={tabs[0].id} />}

View File

@ -25,7 +25,6 @@ export type CustomEvents =
| 'notifications' | 'notifications'
| 'batch_operations' | 'batch_operations'
| 'strategyTitle' | 'strategyTitle'
| 'strategyImprovements'
| 'default_strategy' | 'default_strategy'
| 'demo' | 'demo'
| 'demo-start' | 'demo-start'

View File

@ -48,7 +48,6 @@ export interface IFlags {
demo?: boolean; demo?: boolean;
groupRootRoles?: boolean; groupRootRoles?: boolean;
googleAuthEnabled?: boolean; googleAuthEnabled?: boolean;
strategyImprovements?: boolean;
disableBulkToggle?: boolean; disableBulkToggle?: boolean;
segmentContextFieldUsage?: boolean; segmentContextFieldUsage?: boolean;
disableNotifications?: boolean; disableNotifications?: boolean;

View File

@ -64,6 +64,7 @@ export const STRATEGY_FORM_SUBMIT_ID = 'STRATEGY_FORM_SUBMIT_ID';
export const STRATEGY_FORM_REMOVE_ID = 'STRATEGY_FORM_REMOVE_ID'; export const STRATEGY_FORM_REMOVE_ID = 'STRATEGY_FORM_REMOVE_ID';
export const STRATEGY_FORM_COPY_ID = 'STRATEGY_FORM_COPY_ID'; export const STRATEGY_FORM_COPY_ID = 'STRATEGY_FORM_COPY_ID';
export const STRATEGY_REMOVE_MENU_BTN = 'STRATEGY_REMOVE_MENU_BTN'; export const STRATEGY_REMOVE_MENU_BTN = 'STRATEGY_REMOVE_MENU_BTN';
export const MENU_STRATEGY_REMOVE = 'MENU_STRATEGY_REMOVE';
/* SPLASH */ /* SPLASH */
export const CLOSE_SPLASH = 'CLOSE_SPLASH'; export const CLOSE_SPLASH = 'CLOSE_SPLASH';

View File

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

View File

@ -1373,11 +1373,7 @@ class FeatureToggleService {
(strategy) => strategy.disabled, (strategy) => strategy.disabled,
); );
if ( if (hasDisabledStrategies && shouldActivateDisabledStrategies) {
this.flagResolver.isEnabled('strategyImprovements') &&
hasDisabledStrategies &&
shouldActivateDisabledStrategies
) {
strategies.map(async (strategy) => { strategies.map(async (strategy) => {
return this.updateStrategy( return this.updateStrategy(
strategy.id, strategy.id,
@ -1406,7 +1402,6 @@ class FeatureToggleService {
environment, environment,
); );
const strategy = const strategy =
this.flagResolver.isEnabled('strategyImprovements') &&
projectEnvironmentDefaultStrategy != null projectEnvironmentDefaultStrategy != null
? getProjectDefaultStrategy( ? getProjectDefaultStrategy(
projectEnvironmentDefaultStrategy, projectEnvironmentDefaultStrategy,
@ -1658,7 +1653,7 @@ class FeatureToggleService {
return this.featureToggleStore.getAll({ archived, project }); return this.featureToggleStore.getAll({ archived, project });
} }
async getProjectId(name: string): Promise<string> { async getProjectId(name: string): Promise<string | undefined> {
return this.featureToggleStore.getProjectId(name); return this.featureToggleStore.getProjectId(name);
} }

View File

@ -18,7 +18,6 @@ export type IFlagKey =
| 'groupRootRoles' | 'groupRootRoles'
| 'migrationLock' | 'migrationLock'
| 'demo' | 'demo'
| 'strategyImprovements'
| 'googleAuthEnabled' | 'googleAuthEnabled'
| 'disableBulkToggle' | 'disableBulkToggle'
| 'experimentalExtendedTelemetry' | 'experimentalExtendedTelemetry'
@ -87,10 +86,6 @@ const flags: IFlags = {
), ),
migrationLock: parseEnvVarBoolean(process.env.MIGRATION_LOCK, false), migrationLock: parseEnvVarBoolean(process.env.MIGRATION_LOCK, false),
demo: parseEnvVarBoolean(process.env.UNLEASH_DEMO, false), demo: parseEnvVarBoolean(process.env.UNLEASH_DEMO, false),
strategyImprovements: parseEnvVarBoolean(
process.env.UNLEASH_STRATEGY_IMPROVEMENTS,
false,
),
strategySplittedButton: parseEnvVarBoolean( strategySplittedButton: parseEnvVarBoolean(
process.env.UNLEASH_STRATEGY_SPLITTED_BUTTON, process.env.UNLEASH_STRATEGY_SPLITTED_BUTTON,
false, false,

View File

@ -37,7 +37,6 @@ process.nextTick(async () => {
embedProxyFrontend: true, embedProxyFrontend: true,
anonymiseEventLog: false, anonymiseEventLog: false,
responseTimeWithAppNameKillSwitch: false, responseTimeWithAppNameKillSwitch: false,
strategyImprovements: true,
segmentContextFieldUsage: true, segmentContextFieldUsage: true,
advancedPlayground: true, advancedPlayground: true,
strategySplittedButton: true, strategySplittedButton: true,