mirror of
https://github.com/Unleash/unleash.git
synced 2025-05-03 01:18:43 +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:
parent
b13f7f8519
commit
5cbbd6f798
@ -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', () => {
|
||||
cy.addVariantsToFeature_UI(featureToggleName, [variant1, variant2]);
|
||||
});
|
||||
|
@ -221,6 +221,7 @@ export const deleteFeatureStrategy_UI = (
|
||||
).as('deleteUserStrategy');
|
||||
cy.visit(`/projects/${project}/features/${featureToggleName}`);
|
||||
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();
|
||||
if (!shouldWait) return cy.get('[data-testid=DIALOGUE_CONFIRM_ID]').click();
|
||||
else cy.get('[data-testid=DIALOGUE_CONFIRM_ID]').click();
|
||||
|
@ -203,37 +203,54 @@ const strategiesAreDisplayed = async (
|
||||
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 deleteButtons = screen.getAllByTestId('STRATEGY_FORM_REMOVE_ID');
|
||||
expect(deleteButtons.length).toBe(2);
|
||||
const deleteButtons = await getDeleteButtons();
|
||||
expect(deleteButtons.length).toBe(3);
|
||||
|
||||
// wait for change request config to be loaded
|
||||
await waitFor(() => {
|
||||
// production
|
||||
const productionStrategyDeleteButton = deleteButtons[0];
|
||||
expect(productionStrategyDeleteButton).not.toBeDisabled();
|
||||
const productionStrategyDeleteButton = deleteButtons[1];
|
||||
expect(productionStrategyDeleteButton).not.toHaveClass('Mui-disabled');
|
||||
});
|
||||
await waitFor(() => {
|
||||
// custom env
|
||||
const customEnvStrategyDeleteButton = deleteButtons[1];
|
||||
expect(customEnvStrategyDeleteButton).toBeDisabled();
|
||||
const customEnvStrategyDeleteButton = deleteButtons[2];
|
||||
expect(customEnvStrategyDeleteButton).toHaveClass('Mui-disabled');
|
||||
});
|
||||
};
|
||||
|
||||
const deleteButtonsInactiveInChangeRequestEnv = async () => {
|
||||
const deleteButtons = screen.getAllByTestId('STRATEGY_FORM_REMOVE_ID');
|
||||
expect(deleteButtons.length).toBe(2);
|
||||
const deleteButtons = await getDeleteButtons();
|
||||
expect(deleteButtons.length).toBe(3);
|
||||
|
||||
// wait for change request config to be loaded
|
||||
await waitFor(() => {
|
||||
// production
|
||||
const productionStrategyDeleteButton = deleteButtons[0];
|
||||
expect(productionStrategyDeleteButton).toBeDisabled();
|
||||
const productionStrategyDeleteButton = deleteButtons[1];
|
||||
expect(productionStrategyDeleteButton).toHaveClass('Mui-disabled');
|
||||
});
|
||||
await waitFor(() => {
|
||||
// custom env
|
||||
const customEnvStrategyDeleteButton = deleteButtons[1];
|
||||
expect(customEnvStrategyDeleteButton).toBeDisabled();
|
||||
const customEnvStrategyDeleteButton = deleteButtons[2];
|
||||
expect(customEnvStrategyDeleteButton).toHaveClass('Mui-disabled');
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -2,14 +2,8 @@ import { screen } from '@testing-library/react';
|
||||
import { render } from 'utils/testRenderer';
|
||||
import { StrategyItemContainer } from './StrategyItemContainer';
|
||||
import { IFeatureStrategy } from 'interfaces/strategy';
|
||||
import { testServerRoute, testServerSetup } from 'utils/testServer';
|
||||
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 () => {
|
||||
const strategy: IFeatureStrategy = {
|
||||
id: 'irrelevant',
|
||||
|
@ -9,7 +9,6 @@ import {
|
||||
import StringTruncator from 'component/common/StringTruncator/StringTruncator';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import { PlaygroundStrategySchema } from 'openapi';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
import { Badge } from '../Badge/Badge';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
@ -105,7 +104,6 @@ export const StrategyItemContainer: FC<IStrategyItemContainerProps> = ({
|
||||
description,
|
||||
}) => {
|
||||
const Icon = getFeatureStrategyIcon(strategy.name);
|
||||
const { uiConfig } = useUiConfig();
|
||||
|
||||
const StrategyHeaderLink: React.FC =
|
||||
'links' in strategy
|
||||
@ -158,11 +156,7 @@ export const StrategyItemContainer: FC<IStrategyItemContainerProps> = ({
|
||||
text={formatStrategyName(String(strategy.name))}
|
||||
/>
|
||||
<ConditionallyRender
|
||||
condition={
|
||||
Boolean(
|
||||
uiConfig?.flags?.strategyImprovements
|
||||
) && Boolean(strategy.title)
|
||||
}
|
||||
condition={Boolean(strategy.title)}
|
||||
show={
|
||||
<StyledCustomTitle>
|
||||
{formatStrategyName(
|
||||
|
@ -94,7 +94,7 @@ export const FeatureStrategyEdit = () => {
|
||||
const { isChangeRequestConfigured } = useChangeRequestsEnabled(projectId);
|
||||
const { refetch: refetchChangeRequests } =
|
||||
usePendingChangeRequests(projectId);
|
||||
const { setPreviousTitle, trackTitle } = useTitleTracking();
|
||||
const { setPreviousTitle } = useTitleTracking();
|
||||
|
||||
const { feature, refetchFeature } = useFeature(projectId, featureId);
|
||||
|
||||
@ -153,11 +153,6 @@ export const FeatureStrategyEdit = () => {
|
||||
payload
|
||||
);
|
||||
|
||||
if (uiConfig?.flags?.strategyImprovements) {
|
||||
// NOTE: remove tracking when feature flag is removed
|
||||
trackTitle(strategy.title);
|
||||
}
|
||||
|
||||
await refetchSavedStrategySegments();
|
||||
setToastData({
|
||||
title: 'Strategy updated',
|
||||
|
@ -211,19 +211,14 @@ export const FeatureStrategyForm = ({
|
||||
/>
|
||||
</FeatureStrategyEnabled>
|
||||
<StyledHr />
|
||||
<ConditionallyRender
|
||||
condition={Boolean(uiConfig?.flags?.strategyImprovements)}
|
||||
show={
|
||||
<FeatureStrategyTitle
|
||||
title={strategy.title || ''}
|
||||
setTitle={title => {
|
||||
setStrategy(prev => ({
|
||||
...prev,
|
||||
title,
|
||||
}));
|
||||
}}
|
||||
/>
|
||||
}
|
||||
<FeatureStrategyTitle
|
||||
title={strategy.title || ''}
|
||||
setTitle={title => {
|
||||
setStrategy(prev => ({
|
||||
...prev,
|
||||
title,
|
||||
}));
|
||||
}}
|
||||
/>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(uiConfig.flags.SE)}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { Box, Typography } from '@mui/material';
|
||||
import Input from 'component/common/Input/Input';
|
||||
import { VFC } from 'react';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
|
||||
interface IFeatureStrategyTitleProps {
|
||||
title: string;
|
||||
@ -12,12 +11,6 @@ export const FeatureStrategyTitle: VFC<IFeatureStrategyTitleProps> = ({
|
||||
title,
|
||||
setTitle,
|
||||
}) => {
|
||||
const { uiConfig } = useUiConfig();
|
||||
|
||||
if (!uiConfig.flags.strategyImprovements) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Box sx={{ paddingBottom: theme => theme.spacing(2) }}>
|
||||
<Typography
|
||||
|
@ -2,7 +2,6 @@ import { List, ListItem, styled, Typography } from '@mui/material';
|
||||
import { useStrategies } from 'hooks/api/getters/useStrategies/useStrategies';
|
||||
import { FeatureStrategyMenuCard } from '../FeatureStrategyMenuCard/FeatureStrategyMenuCard';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
|
||||
interface IFeatureStrategyMenuCardsProps {
|
||||
projectId: string;
|
||||
@ -21,7 +20,6 @@ export const FeatureStrategyMenuCards = ({
|
||||
environmentId,
|
||||
}: IFeatureStrategyMenuCardsProps) => {
|
||||
const { strategies } = useStrategies();
|
||||
const { uiConfig } = useUiConfig();
|
||||
|
||||
const preDefinedStrategies = strategies.filter(
|
||||
strategy => !strategy.deprecated && !strategy.editable
|
||||
@ -39,25 +37,20 @@ export const FeatureStrategyMenuCards = ({
|
||||
};
|
||||
return (
|
||||
<List dense>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(uiConfig.flags.strategyImprovements)}
|
||||
show={
|
||||
<>
|
||||
<StyledTypography color="textSecondary">
|
||||
{environmentId} environment default strategy
|
||||
</StyledTypography>
|
||||
<ListItem key={defaultStrategy.name}>
|
||||
<FeatureStrategyMenuCard
|
||||
projectId={projectId}
|
||||
featureId={featureId}
|
||||
environmentId={environmentId}
|
||||
strategy={defaultStrategy}
|
||||
defaultStrategy={true}
|
||||
/>
|
||||
</ListItem>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<>
|
||||
<StyledTypography color="textSecondary">
|
||||
{environmentId} environment default strategy
|
||||
</StyledTypography>
|
||||
<ListItem key={defaultStrategy.name}>
|
||||
<FeatureStrategyMenuCard
|
||||
projectId={projectId}
|
||||
featureId={featureId}
|
||||
environmentId={environmentId}
|
||||
strategy={defaultStrategy}
|
||||
defaultStrategy={true}
|
||||
/>
|
||||
</ListItem>
|
||||
</>
|
||||
<StyledTypography color="textSecondary">
|
||||
Predefined strategy types
|
||||
</StyledTypography>
|
||||
|
@ -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}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
@ -21,6 +21,7 @@ import {
|
||||
} from '@server/types/permissions';
|
||||
import { useHasProjectEnvironmentAccess } from 'hooks/useHasAccess';
|
||||
import {
|
||||
MENU_STRATEGY_REMOVE,
|
||||
STRATEGY_FORM_REMOVE_ID,
|
||||
STRATEGY_REMOVE_MENU_BTN,
|
||||
} from 'utils/testIds';
|
||||
@ -91,6 +92,7 @@ const MenuStrategyRemove = ({
|
||||
onClick={handleClose}
|
||||
transformOrigin={{ horizontal: 'right', vertical: 'top' }}
|
||||
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
|
||||
data-testid={MENU_STRATEGY_REMOVE}
|
||||
>
|
||||
<Tooltip
|
||||
title={
|
||||
|
@ -11,9 +11,7 @@ import { StrategyExecution } from './StrategyExecution/StrategyExecution';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import { CopyStrategyIconMenu } from './CopyStrategyIconMenu/CopyStrategyIconMenu';
|
||||
import { StrategyItemContainer } from 'component/common/StrategyItemContainer/StrategyItemContainer';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
import MenuStrategyRemove from './MenuStrategyRemove/MenuStrategyRemove';
|
||||
import { LegacyFeatureStrategyRemove } from './LegacyFeatureStrategyRemove';
|
||||
|
||||
interface IStrategyItemProps {
|
||||
environmentId: string;
|
||||
@ -34,7 +32,6 @@ export const StrategyItem: FC<IStrategyItemProps> = ({
|
||||
orderNumber,
|
||||
headerChildren,
|
||||
}) => {
|
||||
const { uiConfig } = useUiConfig();
|
||||
const projectId = useRequiredPathParam('projectId');
|
||||
const featureId = useRequiredPathParam('featureId');
|
||||
|
||||
@ -79,27 +76,11 @@ export const StrategyItem: FC<IStrategyItemProps> = ({
|
||||
>
|
||||
<Edit />
|
||||
</PermissionIconButton>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(
|
||||
uiConfig?.flags?.strategyImprovements
|
||||
)}
|
||||
show={() => (
|
||||
<MenuStrategyRemove
|
||||
projectId={projectId}
|
||||
featureId={featureId}
|
||||
environmentId={environmentId}
|
||||
strategy={strategy}
|
||||
/>
|
||||
)}
|
||||
elseShow={() => (
|
||||
<LegacyFeatureStrategyRemove
|
||||
projectId={projectId}
|
||||
featureId={featureId}
|
||||
environmentId={environmentId}
|
||||
strategyId={strategy.id}
|
||||
icon
|
||||
/>
|
||||
)}
|
||||
<MenuStrategyRemove
|
||||
projectId={projectId}
|
||||
featureId={featureId}
|
||||
environmentId={environmentId}
|
||||
strategy={strategy}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
|
@ -14,8 +14,6 @@ import { useChangeRequestToggle } from 'hooks/useChangeRequestToggle';
|
||||
import { EnableEnvironmentDialog } from 'component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelEnvironmentSwitches/FeatureOverviewSidePanelEnvironmentSwitch/EnableEnvironmentDialog';
|
||||
import { UpdateEnabledMessage } from 'component/changeRequest/ChangeRequestConfirmDialog/ChangeRequestMessages/UpdateEnabledMessage';
|
||||
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 }>(() => ({
|
||||
mx: 'auto',
|
||||
@ -65,13 +63,6 @@ export const FeatureToggleSwitch: VFC<IFeatureToggleSwitchProps> = ({
|
||||
.find(env => env.name === environmentName)
|
||||
?.strategies.filter(strategy => strategy.disabled).length ?? 0;
|
||||
|
||||
const { uiConfig } = useUiConfig();
|
||||
const showStrategyImprovements = Boolean(
|
||||
uiConfig.flags.strategyImprovements
|
||||
);
|
||||
|
||||
const { trackEvent } = usePlausibleTracker();
|
||||
|
||||
const handleToggleEnvironmentOn = async (
|
||||
shouldActivateDisabled = false
|
||||
) => {
|
||||
@ -125,10 +116,7 @@ export const FeatureToggleSwitch: VFC<IFeatureToggleSwitchProps> = ({
|
||||
const onClick = async (e: React.MouseEvent) => {
|
||||
if (isChangeRequestConfigured(environmentName)) {
|
||||
e.preventDefault();
|
||||
if (
|
||||
featureHasOnlyDisabledStrategies() &&
|
||||
showStrategyImprovements
|
||||
) {
|
||||
if (featureHasOnlyDisabledStrategies()) {
|
||||
setShowEnabledDialog(true);
|
||||
} else {
|
||||
onChangeRequestToggle(
|
||||
@ -145,7 +133,7 @@ export const FeatureToggleSwitch: VFC<IFeatureToggleSwitchProps> = ({
|
||||
return;
|
||||
}
|
||||
|
||||
if (featureHasOnlyDisabledStrategies() && showStrategyImprovements) {
|
||||
if (featureHasOnlyDisabledStrategies()) {
|
||||
setShowEnabledDialog(true);
|
||||
} else {
|
||||
await handleToggleEnvironmentOn();
|
||||
@ -153,11 +141,6 @@ export const FeatureToggleSwitch: VFC<IFeatureToggleSwitchProps> = ({
|
||||
};
|
||||
|
||||
const onActivateStrategies = async () => {
|
||||
await trackEvent('strategyImprovements', {
|
||||
props: {
|
||||
eventType: 'activate disabled strategies',
|
||||
},
|
||||
});
|
||||
if (isChangeRequestConfigured(environmentName)) {
|
||||
onChangeRequestToggle(
|
||||
feature.name,
|
||||
@ -172,11 +155,6 @@ export const FeatureToggleSwitch: VFC<IFeatureToggleSwitchProps> = ({
|
||||
};
|
||||
|
||||
const onAddDefaultStrategy = async () => {
|
||||
await trackEvent('strategyImprovements', {
|
||||
props: {
|
||||
eventType: 'add default strategy',
|
||||
},
|
||||
});
|
||||
if (isChangeRequestConfigured(environmentName)) {
|
||||
onChangeRequestToggle(
|
||||
feature.name,
|
||||
@ -223,16 +201,14 @@ export const FeatureToggleSwitch: VFC<IFeatureToggleSwitchProps> = ({
|
||||
onClick={onClick}
|
||||
/>
|
||||
</StyledBoxContainer>
|
||||
{showStrategyImprovements && (
|
||||
<EnableEnvironmentDialog
|
||||
isOpen={showEnabledDialog}
|
||||
onClose={() => setShowEnabledDialog(false)}
|
||||
environment={environmentName}
|
||||
disabledStrategiesCount={disabledStrategiesCount}
|
||||
onActivateDisabledStrategies={onActivateStrategies}
|
||||
onAddDefaultStrategy={onAddDefaultStrategy}
|
||||
/>
|
||||
)}
|
||||
<EnableEnvironmentDialog
|
||||
isOpen={showEnabledDialog}
|
||||
onClose={() => setShowEnabledDialog(false)}
|
||||
environment={environmentName}
|
||||
disabledStrategiesCount={disabledStrategiesCount}
|
||||
onActivateDisabledStrategies={onActivateStrategies}
|
||||
onAddDefaultStrategy={onAddDefaultStrategy}
|
||||
/>
|
||||
<ChangeRequestDialogue
|
||||
isOpen={changeRequestDialogDetails.isOpen}
|
||||
onClose={onChangeRequestToggleClose}
|
||||
|
@ -145,19 +145,14 @@ export const ProjectDefaultStrategyForm = ({
|
||||
};
|
||||
return (
|
||||
<StyledForm onSubmit={onSubmitWithValidation}>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(uiConfig?.flags?.strategyImprovements)}
|
||||
show={
|
||||
<FeatureStrategyTitle
|
||||
title={strategy.title || ''}
|
||||
setTitle={title => {
|
||||
setStrategy(prev => ({
|
||||
...prev,
|
||||
title,
|
||||
}));
|
||||
}}
|
||||
/>
|
||||
}
|
||||
<FeatureStrategyTitle
|
||||
title={strategy.title || ''}
|
||||
setTitle={title => {
|
||||
setStrategy(prev => ({
|
||||
...prev,
|
||||
title,
|
||||
}));
|
||||
}}
|
||||
/>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(uiConfig.flags.SE)}
|
||||
|
@ -12,13 +12,10 @@ import { ChangeRequestConfiguration } from './ChangeRequestConfiguration/ChangeR
|
||||
import { ProjectApiAccess } from 'component/project/Project/ProjectSettings/ProjectApiAccess/ProjectApiAccess';
|
||||
import { ProjectSegments } from './ProjectSegments/ProjectSegments';
|
||||
import { ProjectDefaultStrategySettings } from './ProjectDefaultStrategySettings/ProjectDefaultStrategySettings';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
|
||||
export const ProjectSettings = () => {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const { uiConfig } = useUiConfig();
|
||||
const { strategyImprovements } = uiConfig.flags;
|
||||
|
||||
const tabs: ITab[] = [
|
||||
{
|
||||
@ -41,14 +38,11 @@ export const ProjectSettings = () => {
|
||||
id: 'api-access',
|
||||
label: 'API access',
|
||||
},
|
||||
];
|
||||
|
||||
if (Boolean(strategyImprovements)) {
|
||||
tabs.push({
|
||||
{
|
||||
id: 'default-strategy',
|
||||
label: 'Default strategy',
|
||||
});
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
const onChange = (tab: ITab) => {
|
||||
navigate(tab.id);
|
||||
@ -76,12 +70,10 @@ export const ProjectSettings = () => {
|
||||
element={<ChangeRequestConfiguration />}
|
||||
/>
|
||||
<Route path="api-access/*" element={<ProjectApiAccess />} />
|
||||
{Boolean(strategyImprovements) && (
|
||||
<Route
|
||||
path="default-strategy/*"
|
||||
element={<ProjectDefaultStrategySettings />}
|
||||
/>
|
||||
)}
|
||||
<Route
|
||||
path="default-strategy/*"
|
||||
element={<ProjectDefaultStrategySettings />}
|
||||
/>
|
||||
<Route
|
||||
path="*"
|
||||
element={<Navigate replace to={tabs[0].id} />}
|
||||
|
@ -25,7 +25,6 @@ export type CustomEvents =
|
||||
| 'notifications'
|
||||
| 'batch_operations'
|
||||
| 'strategyTitle'
|
||||
| 'strategyImprovements'
|
||||
| 'default_strategy'
|
||||
| 'demo'
|
||||
| 'demo-start'
|
||||
|
@ -48,7 +48,6 @@ export interface IFlags {
|
||||
demo?: boolean;
|
||||
groupRootRoles?: boolean;
|
||||
googleAuthEnabled?: boolean;
|
||||
strategyImprovements?: boolean;
|
||||
disableBulkToggle?: boolean;
|
||||
segmentContextFieldUsage?: boolean;
|
||||
disableNotifications?: boolean;
|
||||
|
@ -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_COPY_ID = 'STRATEGY_FORM_COPY_ID';
|
||||
export const STRATEGY_REMOVE_MENU_BTN = 'STRATEGY_REMOVE_MENU_BTN';
|
||||
export const MENU_STRATEGY_REMOVE = 'MENU_STRATEGY_REMOVE';
|
||||
|
||||
/* SPLASH */
|
||||
export const CLOSE_SPLASH = 'CLOSE_SPLASH';
|
||||
|
@ -95,7 +95,6 @@ exports[`should create default config 1`] = `
|
||||
"proPlanAutoCharge": false,
|
||||
"responseTimeWithAppNameKillSwitch": false,
|
||||
"segmentContextFieldUsage": false,
|
||||
"strategyImprovements": false,
|
||||
"strategySplittedButton": false,
|
||||
"strictSchemaValidation": false,
|
||||
},
|
||||
@ -130,7 +129,6 @@ exports[`should create default config 1`] = `
|
||||
"proPlanAutoCharge": false,
|
||||
"responseTimeWithAppNameKillSwitch": false,
|
||||
"segmentContextFieldUsage": false,
|
||||
"strategyImprovements": false,
|
||||
"strategySplittedButton": false,
|
||||
"strictSchemaValidation": false,
|
||||
},
|
||||
|
@ -1373,11 +1373,7 @@ class FeatureToggleService {
|
||||
(strategy) => strategy.disabled,
|
||||
);
|
||||
|
||||
if (
|
||||
this.flagResolver.isEnabled('strategyImprovements') &&
|
||||
hasDisabledStrategies &&
|
||||
shouldActivateDisabledStrategies
|
||||
) {
|
||||
if (hasDisabledStrategies && shouldActivateDisabledStrategies) {
|
||||
strategies.map(async (strategy) => {
|
||||
return this.updateStrategy(
|
||||
strategy.id,
|
||||
@ -1406,7 +1402,6 @@ class FeatureToggleService {
|
||||
environment,
|
||||
);
|
||||
const strategy =
|
||||
this.flagResolver.isEnabled('strategyImprovements') &&
|
||||
projectEnvironmentDefaultStrategy != null
|
||||
? getProjectDefaultStrategy(
|
||||
projectEnvironmentDefaultStrategy,
|
||||
@ -1658,7 +1653,7 @@ class FeatureToggleService {
|
||||
return this.featureToggleStore.getAll({ archived, project });
|
||||
}
|
||||
|
||||
async getProjectId(name: string): Promise<string> {
|
||||
async getProjectId(name: string): Promise<string | undefined> {
|
||||
return this.featureToggleStore.getProjectId(name);
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,6 @@ export type IFlagKey =
|
||||
| 'groupRootRoles'
|
||||
| 'migrationLock'
|
||||
| 'demo'
|
||||
| 'strategyImprovements'
|
||||
| 'googleAuthEnabled'
|
||||
| 'disableBulkToggle'
|
||||
| 'experimentalExtendedTelemetry'
|
||||
@ -87,10 +86,6 @@ const flags: IFlags = {
|
||||
),
|
||||
migrationLock: parseEnvVarBoolean(process.env.MIGRATION_LOCK, false),
|
||||
demo: parseEnvVarBoolean(process.env.UNLEASH_DEMO, false),
|
||||
strategyImprovements: parseEnvVarBoolean(
|
||||
process.env.UNLEASH_STRATEGY_IMPROVEMENTS,
|
||||
false,
|
||||
),
|
||||
strategySplittedButton: parseEnvVarBoolean(
|
||||
process.env.UNLEASH_STRATEGY_SPLITTED_BUTTON,
|
||||
false,
|
||||
|
@ -37,7 +37,6 @@ process.nextTick(async () => {
|
||||
embedProxyFrontend: true,
|
||||
anonymiseEventLog: false,
|
||||
responseTimeWithAppNameKillSwitch: false,
|
||||
strategyImprovements: true,
|
||||
segmentContextFieldUsage: true,
|
||||
advancedPlayground: true,
|
||||
strategySplittedButton: true,
|
||||
|
Loading…
Reference in New Issue
Block a user