mirror of
https://github.com/Unleash/unleash.git
synced 2025-09-01 13:47:27 +02:00
chore: remove new strategy configuration flag (#6335)
This commit is contained in:
parent
e9603f866b
commit
c049374a25
@ -1,9 +1,9 @@
|
|||||||
import React, { FC, useState } from 'react';
|
import React, { FC, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
ChangeRequestType,
|
ChangeRequestType,
|
||||||
|
IChange,
|
||||||
IChangeRequestAddStrategy,
|
IChangeRequestAddStrategy,
|
||||||
IChangeRequestUpdateStrategy,
|
IChangeRequestUpdateStrategy,
|
||||||
IChange,
|
|
||||||
} from 'component/changeRequest/changeRequest.types';
|
} from 'component/changeRequest/changeRequest.types';
|
||||||
import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi';
|
import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi';
|
||||||
import useToast from 'hooks/useToast';
|
import useToast from 'hooks/useToast';
|
||||||
@ -24,8 +24,6 @@ import {
|
|||||||
Typography,
|
Typography,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { Delete, Edit, MoreVert } from '@mui/icons-material';
|
import { Delete, Edit, MoreVert } from '@mui/icons-material';
|
||||||
import { EditChange } from './EditChange';
|
|
||||||
import { useUiFlag } from 'hooks/useUiFlag';
|
|
||||||
import { NewEditChange } from './NewEditChange';
|
import { NewEditChange } from './NewEditChange';
|
||||||
|
|
||||||
const useShowActions = (changeRequest: ChangeRequestType, change: IChange) => {
|
const useShowActions = (changeRequest: ChangeRequestType, change: IChange) => {
|
||||||
@ -68,7 +66,6 @@ export const ChangeActions: FC<{
|
|||||||
const { showDiscard, showEdit } = useShowActions(changeRequest, change);
|
const { showDiscard, showEdit } = useShowActions(changeRequest, change);
|
||||||
const { discardChange } = useChangeRequestApi();
|
const { discardChange } = useChangeRequestApi();
|
||||||
const { setToastData, setToastApiError } = useToast();
|
const { setToastData, setToastApiError } = useToast();
|
||||||
const newStrategyConfiguration = useUiFlag('newStrategyConfiguration');
|
|
||||||
|
|
||||||
const [editOpen, setEditOpen] = useState(false);
|
const [editOpen, setEditOpen] = useState(false);
|
||||||
|
|
||||||
@ -152,13 +149,8 @@ export const ChangeActions: FC<{
|
|||||||
Edit change
|
Edit change
|
||||||
</Typography>
|
</Typography>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
<ConditionallyRender
|
|
||||||
condition={newStrategyConfiguration}
|
|
||||||
show={
|
|
||||||
<NewEditChange
|
<NewEditChange
|
||||||
changeRequestId={
|
changeRequestId={changeRequest.id}
|
||||||
changeRequest.id
|
|
||||||
}
|
|
||||||
featureId={feature}
|
featureId={feature}
|
||||||
change={
|
change={
|
||||||
change as
|
change as
|
||||||
@ -177,32 +169,6 @@ export const ChangeActions: FC<{
|
|||||||
setEditOpen(false);
|
setEditOpen(false);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
|
||||||
elseShow={
|
|
||||||
<EditChange
|
|
||||||
changeRequestId={
|
|
||||||
changeRequest.id
|
|
||||||
}
|
|
||||||
featureId={feature}
|
|
||||||
change={
|
|
||||||
change as
|
|
||||||
| IChangeRequestAddStrategy
|
|
||||||
| IChangeRequestUpdateStrategy
|
|
||||||
}
|
|
||||||
environment={
|
|
||||||
changeRequest.environment
|
|
||||||
}
|
|
||||||
open={editOpen}
|
|
||||||
onSubmit={() => {
|
|
||||||
setEditOpen(false);
|
|
||||||
onRefetch?.();
|
|
||||||
}}
|
|
||||||
onClose={() => {
|
|
||||||
setEditOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { FeatureStrategyForm } from 'component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm';
|
|
||||||
import FormTemplate from 'component/common/FormTemplate/FormTemplate';
|
import FormTemplate from 'component/common/FormTemplate/FormTemplate';
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
||||||
@ -22,8 +21,6 @@ import {
|
|||||||
} from 'component/changeRequest/changeRequest.types';
|
} from 'component/changeRequest/changeRequest.types';
|
||||||
import { SidebarModal } from 'component/common/SidebarModal/SidebarModal';
|
import { SidebarModal } from 'component/common/SidebarModal/SidebarModal';
|
||||||
import { useSegments } from 'hooks/api/getters/useSegments/useSegments';
|
import { useSegments } from 'hooks/api/getters/useSegments/useSegments';
|
||||||
import { useUiFlag } from 'hooks/useUiFlag';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
|
||||||
import { NewFeatureStrategyForm } from 'component/feature/FeatureStrategy/FeatureStrategyForm/NewFeatureStrategyForm';
|
import { NewFeatureStrategyForm } from 'component/feature/FeatureStrategy/FeatureStrategyForm/NewFeatureStrategyForm';
|
||||||
import { StrategyVariants } from 'component/feature/StrategyTypes/StrategyVariants';
|
import { StrategyVariants } from 'component/feature/StrategyTypes/StrategyVariants';
|
||||||
|
|
||||||
@ -49,7 +46,6 @@ export const EditChange = ({
|
|||||||
const projectId = useRequiredPathParam('projectId');
|
const projectId = useRequiredPathParam('projectId');
|
||||||
const { editChange } = useChangeRequestApi();
|
const { editChange } = useChangeRequestApi();
|
||||||
const [tab, setTab] = useState(0);
|
const [tab, setTab] = useState(0);
|
||||||
const newStrategyConfiguration = useUiFlag('newStrategyConfiguration');
|
|
||||||
|
|
||||||
const [strategy, setStrategy] = useState<Partial<IFeatureStrategy>>(
|
const [strategy, setStrategy] = useState<Partial<IFeatureStrategy>>(
|
||||||
change.payload,
|
change.payload,
|
||||||
@ -152,9 +148,6 @@ export const EditChange = ({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<ConditionallyRender
|
|
||||||
condition={newStrategyConfiguration}
|
|
||||||
show={
|
|
||||||
<NewFeatureStrategyForm
|
<NewFeatureStrategyForm
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
feature={data}
|
feature={data}
|
||||||
@ -168,9 +161,7 @@ export const EditChange = ({
|
|||||||
loading={false}
|
loading={false}
|
||||||
permission={UPDATE_FEATURE_STRATEGY}
|
permission={UPDATE_FEATURE_STRATEGY}
|
||||||
errors={errors}
|
errors={errors}
|
||||||
isChangeRequest={isChangeRequestConfigured(
|
isChangeRequest={isChangeRequestConfigured(environment)}
|
||||||
environment,
|
|
||||||
)}
|
|
||||||
tab={tab}
|
tab={tab}
|
||||||
setTab={setTab}
|
setTab={setTab}
|
||||||
StrategyVariants={
|
StrategyVariants={
|
||||||
@ -182,27 +173,6 @@ export const EditChange = ({
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
}
|
|
||||||
elseShow={
|
|
||||||
<FeatureStrategyForm
|
|
||||||
projectId={projectId}
|
|
||||||
feature={data}
|
|
||||||
strategy={strategy}
|
|
||||||
setStrategy={setStrategy}
|
|
||||||
segments={segments}
|
|
||||||
setSegments={setSegments}
|
|
||||||
environmentId={environment}
|
|
||||||
onSubmit={onInternalSubmit}
|
|
||||||
onCancel={onClose}
|
|
||||||
loading={false}
|
|
||||||
permission={UPDATE_FEATURE_STRATEGY}
|
|
||||||
errors={errors}
|
|
||||||
isChangeRequest={isChangeRequestConfigured(
|
|
||||||
environment,
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{staleDataNotification}
|
{staleDataNotification}
|
||||||
</FormTemplate>
|
</FormTemplate>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { FeatureStrategyForm } from 'component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm';
|
|
||||||
import FormTemplate from 'component/common/FormTemplate/FormTemplate';
|
import FormTemplate from 'component/common/FormTemplate/FormTemplate';
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
||||||
@ -23,8 +22,6 @@ import {
|
|||||||
} from 'component/changeRequest/changeRequest.types';
|
} from 'component/changeRequest/changeRequest.types';
|
||||||
import { SidebarModal } from 'component/common/SidebarModal/SidebarModal';
|
import { SidebarModal } from 'component/common/SidebarModal/SidebarModal';
|
||||||
import { useSegments } from 'hooks/api/getters/useSegments/useSegments';
|
import { useSegments } from 'hooks/api/getters/useSegments/useSegments';
|
||||||
import { useUiFlag } from 'hooks/useUiFlag';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
|
||||||
import { NewFeatureStrategyForm } from 'component/feature/FeatureStrategy/FeatureStrategyForm/NewFeatureStrategyForm';
|
import { NewFeatureStrategyForm } from 'component/feature/FeatureStrategy/FeatureStrategyForm/NewFeatureStrategyForm';
|
||||||
import { NewStrategyVariants } from 'component/feature/StrategyTypes/NewStrategyVariants';
|
import { NewStrategyVariants } from 'component/feature/StrategyTypes/NewStrategyVariants';
|
||||||
import { constraintId } from 'component/common/ConstraintAccordion/ConstraintAccordionList/createEmptyConstraint';
|
import { constraintId } from 'component/common/ConstraintAccordion/ConstraintAccordionList/createEmptyConstraint';
|
||||||
@ -62,7 +59,6 @@ export const NewEditChange = ({
|
|||||||
const projectId = useRequiredPathParam('projectId');
|
const projectId = useRequiredPathParam('projectId');
|
||||||
const { editChange } = useChangeRequestApi();
|
const { editChange } = useChangeRequestApi();
|
||||||
const [tab, setTab] = useState(0);
|
const [tab, setTab] = useState(0);
|
||||||
const newStrategyConfiguration = useUiFlag('newStrategyConfiguration');
|
|
||||||
|
|
||||||
const constraintsWithId = addIdSymbolToConstraints(change.payload);
|
const constraintsWithId = addIdSymbolToConstraints(change.payload);
|
||||||
|
|
||||||
@ -168,9 +164,6 @@ export const NewEditChange = ({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<ConditionallyRender
|
|
||||||
condition={newStrategyConfiguration}
|
|
||||||
show={
|
|
||||||
<NewFeatureStrategyForm
|
<NewFeatureStrategyForm
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
feature={data}
|
feature={data}
|
||||||
@ -184,9 +177,7 @@ export const NewEditChange = ({
|
|||||||
loading={false}
|
loading={false}
|
||||||
permission={UPDATE_FEATURE_STRATEGY}
|
permission={UPDATE_FEATURE_STRATEGY}
|
||||||
errors={errors}
|
errors={errors}
|
||||||
isChangeRequest={isChangeRequestConfigured(
|
isChangeRequest={isChangeRequestConfigured(environment)}
|
||||||
environment,
|
|
||||||
)}
|
|
||||||
tab={tab}
|
tab={tab}
|
||||||
setTab={setTab}
|
setTab={setTab}
|
||||||
StrategyVariants={
|
StrategyVariants={
|
||||||
@ -198,27 +189,6 @@ export const NewEditChange = ({
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
}
|
|
||||||
elseShow={
|
|
||||||
<FeatureStrategyForm
|
|
||||||
projectId={projectId}
|
|
||||||
feature={data}
|
|
||||||
strategy={strategy}
|
|
||||||
setStrategy={setStrategy}
|
|
||||||
segments={segments}
|
|
||||||
setSegments={setSegments}
|
|
||||||
environmentId={environment}
|
|
||||||
onSubmit={onInternalSubmit}
|
|
||||||
onCancel={onClose}
|
|
||||||
loading={false}
|
|
||||||
permission={UPDATE_FEATURE_STRATEGY}
|
|
||||||
errors={errors}
|
|
||||||
isChangeRequest={isChangeRequestConfigured(
|
|
||||||
environment,
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{staleDataNotification}
|
{staleDataNotification}
|
||||||
</FormTemplate>
|
</FormTemplate>
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
import { useStyles } from 'component/common/AutocompleteBox/AutocompleteBox.styles';
|
import { useStyles } from 'component/common/AutocompleteBox/AutocompleteBox.styles';
|
||||||
import { Search, ArrowDropDown, Add } from '@mui/icons-material';
|
import { Add } from '@mui/icons-material';
|
||||||
import { Autocomplete, styled, InputAdornment, useTheme } from '@mui/material';
|
import {
|
||||||
|
Autocomplete,
|
||||||
|
InputAdornment,
|
||||||
|
styled,
|
||||||
|
TextField,
|
||||||
|
useTheme,
|
||||||
|
} from '@mui/material';
|
||||||
import { AutocompleteRenderInputParams } from '@mui/material/Autocomplete';
|
import { AutocompleteRenderInputParams } from '@mui/material/Autocomplete';
|
||||||
import { TextField } from '@mui/material';
|
|
||||||
import { useUiFlag } from 'hooks/useUiFlag';
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
interface IAutocompleteBoxProps {
|
interface IAutocompleteBoxProps {
|
||||||
@ -60,8 +64,6 @@ export const AutocompleteBox = ({
|
|||||||
const { classes: styles } = useStyles();
|
const { classes: styles } = useStyles();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const newStrategyConfiguration = useUiFlag('newStrategyConfiguration');
|
|
||||||
|
|
||||||
const renderInput = (params: AutocompleteRenderInputParams) => {
|
const renderInput = (params: AutocompleteRenderInputParams) => {
|
||||||
return <TextField {...params} variant='outlined' label={label} />;
|
return <TextField {...params} variant='outlined' label={label} />;
|
||||||
};
|
};
|
||||||
@ -113,7 +115,6 @@ export const AutocompleteBox = ({
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
if (newStrategyConfiguration) {
|
|
||||||
return (
|
return (
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<StyledAutocomplete
|
<StyledAutocomplete
|
||||||
@ -128,25 +129,4 @@ export const AutocompleteBox = ({
|
|||||||
/>
|
/>
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<StyledContainer>
|
|
||||||
<StyledIcon $disabled={Boolean(disabled)} aria-hidden>
|
|
||||||
<Search />
|
|
||||||
</StyledIcon>
|
|
||||||
<StyledAutocomplete
|
|
||||||
classes={{ inputRoot: styles.inputRoot }}
|
|
||||||
options={options}
|
|
||||||
value={value}
|
|
||||||
popupIcon={<ArrowDropDown titleAccess='Toggle' />}
|
|
||||||
onChange={(event, value) => onChange(value || [])}
|
|
||||||
renderInput={renderInput}
|
|
||||||
getOptionLabel={(value) => value.label}
|
|
||||||
disabled={disabled}
|
|
||||||
size='small'
|
|
||||||
multiple
|
|
||||||
/>
|
|
||||||
</StyledContainer>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
@ -4,11 +4,8 @@ import { Add, HelpOutline } from '@mui/icons-material';
|
|||||||
import { IConstraint } from 'interfaces/strategy';
|
import { IConstraint } from 'interfaces/strategy';
|
||||||
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
|
||||||
import { useUiFlag } from 'hooks/useUiFlag';
|
|
||||||
import { HelpIcon } from 'component/common/HelpIcon/HelpIcon';
|
import { HelpIcon } from 'component/common/HelpIcon/HelpIcon';
|
||||||
import {
|
import {
|
||||||
ConstraintList,
|
|
||||||
IConstraintAccordionListRef,
|
IConstraintAccordionListRef,
|
||||||
useConstraintAccordionList,
|
useConstraintAccordionList,
|
||||||
} from 'component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList';
|
} from 'component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList';
|
||||||
@ -21,6 +18,7 @@ interface IConstraintAccordionListProps {
|
|||||||
/* Add "constraints" title on the top - default `true` */
|
/* Add "constraints" title on the top - default `true` */
|
||||||
showLabel?: boolean;
|
showLabel?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const constraintAccordionListId = 'constraintAccordionListId';
|
export const constraintAccordionListId = 'constraintAccordionListId';
|
||||||
|
|
||||||
const StyledContainer = styled('div')({
|
const StyledContainer = styled('div')({
|
||||||
@ -72,13 +70,11 @@ export const FeatureStrategyConstraintAccordionList = forwardRef<
|
|||||||
setConstraints,
|
setConstraints,
|
||||||
ref as RefObject<IConstraintAccordionListRef>,
|
ref as RefObject<IConstraintAccordionListRef>,
|
||||||
);
|
);
|
||||||
const newStrategyConfiguration = useUiFlag('newStrategyConfiguration');
|
|
||||||
|
|
||||||
if (context.length === 0) {
|
if (context.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newStrategyConfiguration) {
|
|
||||||
return (
|
return (
|
||||||
<StyledContainer id={constraintAccordionListId}>
|
<StyledContainer id={constraintAccordionListId}>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
@ -93,11 +89,10 @@ export const FeatureStrategyConstraintAccordionList = forwardRef<
|
|||||||
<Box>
|
<Box>
|
||||||
<Typography variant='body2'>
|
<Typography variant='body2'>
|
||||||
Constraints are advanced
|
Constraints are advanced
|
||||||
targeting rules that you can
|
targeting rules that you can use
|
||||||
use to enable a feature
|
to enable a feature toggle for a
|
||||||
toggle for a subset of your
|
subset of your users. Read more
|
||||||
users. Read more about
|
about constraints{' '}
|
||||||
constraints{' '}
|
|
||||||
<a
|
<a
|
||||||
href='https://docs.getunleash.io/reference/strategy-constraints'
|
href='https://docs.getunleash.io/reference/strategy-constraints'
|
||||||
target='_blank'
|
target='_blank'
|
||||||
@ -132,60 +127,5 @@ export const FeatureStrategyConstraintAccordionList = forwardRef<
|
|||||||
/>
|
/>
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<StyledContainer id={constraintAccordionListId}>
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={
|
|
||||||
constraints && constraints.length > 0 && showLabel
|
|
||||||
}
|
|
||||||
show={
|
|
||||||
<StyledConstraintLabel>
|
|
||||||
Constraints
|
|
||||||
</StyledConstraintLabel>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<ConstraintList
|
|
||||||
ref={ref}
|
|
||||||
setConstraints={setConstraints}
|
|
||||||
constraints={constraints}
|
|
||||||
state={state}
|
|
||||||
/>
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={Boolean(showCreateButton && onAdd)}
|
|
||||||
show={
|
|
||||||
<div>
|
|
||||||
<StyledAddCustomLabel>
|
|
||||||
<p>Add any number of constraints</p>
|
|
||||||
<StyledHelpWrapper
|
|
||||||
title='View constraints documentation'
|
|
||||||
arrow
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href={
|
|
||||||
'https://docs.getunleash.io/reference/strategy-constraints'
|
|
||||||
}
|
|
||||||
target='_blank'
|
|
||||||
rel='noopener noreferrer'
|
|
||||||
>
|
|
||||||
<StyledHelp />
|
|
||||||
</a>
|
|
||||||
</StyledHelpWrapper>
|
|
||||||
</StyledAddCustomLabel>
|
|
||||||
<Button
|
|
||||||
type='button'
|
|
||||||
onClick={onAdd}
|
|
||||||
variant='outlined'
|
|
||||||
color='primary'
|
|
||||||
data-testid='ADD_CONSTRAINT_BUTTON'
|
|
||||||
>
|
|
||||||
Add constraint
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</StyledContainer>
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
FormControlLabel,
|
FormControlLabel,
|
||||||
|
styled,
|
||||||
Switch,
|
Switch,
|
||||||
Typography,
|
Typography,
|
||||||
styled,
|
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { useUiFlag } from 'hooks/useUiFlag';
|
|
||||||
import { VFC } from 'react';
|
import { VFC } from 'react';
|
||||||
|
|
||||||
interface IFeatureStrategyEnabledDisabledProps {
|
interface IFeatureStrategyEnabledDisabledProps {
|
||||||
@ -25,9 +24,6 @@ const StyledBox = styled(Box)(({ theme }) => ({
|
|||||||
export const FeatureStrategyEnabledDisabled: VFC<
|
export const FeatureStrategyEnabledDisabled: VFC<
|
||||||
IFeatureStrategyEnabledDisabledProps
|
IFeatureStrategyEnabledDisabledProps
|
||||||
> = ({ enabled, onToggleEnabled }) => {
|
> = ({ enabled, onToggleEnabled }) => {
|
||||||
const strategyConfigurationEnabled = useUiFlag('newStrategyConfiguration');
|
|
||||||
|
|
||||||
if (strategyConfigurationEnabled) {
|
|
||||||
return (
|
return (
|
||||||
<StyledBox>
|
<StyledBox>
|
||||||
<Typography>Strategy Status</Typography>
|
<Typography>Strategy Status</Typography>
|
||||||
@ -43,18 +39,4 @@ export const FeatureStrategyEnabledDisabled: VFC<
|
|||||||
/>
|
/>
|
||||||
</StyledBox>
|
</StyledBox>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Switch
|
|
||||||
name='enabled'
|
|
||||||
onChange={onToggleEnabled}
|
|
||||||
checked={enabled}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label='Enabled – This strategy will be used when evaluating feature toggles.'
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
@ -9,7 +9,6 @@ import { FeatureStrategySegmentList } from 'component/feature/FeatureStrategy/Fe
|
|||||||
import { SegmentDocsStrategyWarning } from 'component/segments/SegmentDocs';
|
import { SegmentDocsStrategyWarning } from 'component/segments/SegmentDocs';
|
||||||
import { useSegmentLimits } from 'hooks/api/getters/useSegmentLimits/useSegmentLimits';
|
import { useSegmentLimits } from 'hooks/api/getters/useSegmentLimits/useSegmentLimits';
|
||||||
import { Box, Divider, styled, Typography } from '@mui/material';
|
import { Box, Divider, styled, Typography } from '@mui/material';
|
||||||
import { useUiFlag } from 'hooks/useUiFlag';
|
|
||||||
import { HelpIcon } from 'component/common/HelpIcon/HelpIcon';
|
import { HelpIcon } from 'component/common/HelpIcon/HelpIcon';
|
||||||
|
|
||||||
interface IFeatureStrategySegmentProps {
|
interface IFeatureStrategySegmentProps {
|
||||||
@ -37,8 +36,6 @@ export const FeatureStrategySegment = ({
|
|||||||
const { segments: allSegments } = useSegments();
|
const { segments: allSegments } = useSegments();
|
||||||
const { strategySegmentsLimit } = useSegmentLimits();
|
const { strategySegmentsLimit } = useSegmentLimits();
|
||||||
|
|
||||||
const newStrategyConfiguration = useUiFlag('newStrategyConfiguration');
|
|
||||||
|
|
||||||
const atStrategySegmentsLimit: boolean = Boolean(
|
const atStrategySegmentsLimit: boolean = Boolean(
|
||||||
strategySegmentsLimit &&
|
strategySegmentsLimit &&
|
||||||
selectedSegments.length >= strategySegmentsLimit,
|
selectedSegments.length >= strategySegmentsLimit,
|
||||||
@ -70,7 +67,6 @@ export const FeatureStrategySegment = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (newStrategyConfiguration) {
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<StyledHelpIconBox>
|
<StyledHelpIconBox>
|
||||||
@ -80,11 +76,11 @@ export const FeatureStrategySegment = ({
|
|||||||
tooltip={
|
tooltip={
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant='body2'>
|
<Typography variant='body2'>
|
||||||
Segments are reusable sets of constraints
|
Segments are reusable sets of constraints that
|
||||||
that can be defined once and reused across
|
can be defined once and reused across feature
|
||||||
feature toggle configurations. You can
|
toggle configurations. You can create a segment
|
||||||
create a segment on the global or the
|
on the global or the project level. Read more
|
||||||
project level. Read more about segments{' '}
|
about segments{' '}
|
||||||
<a
|
<a
|
||||||
href='https://docs.getunleash.io/reference/segments'
|
href='https://docs.getunleash.io/reference/segments'
|
||||||
target='_blank'
|
target='_blank'
|
||||||
@ -111,27 +107,4 @@ export const FeatureStrategySegment = ({
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Typography component='h3' sx={{ m: 0 }} variant='h3'>
|
|
||||||
Segmentation
|
|
||||||
</Typography>
|
|
||||||
{atStrategySegmentsLimit && <SegmentDocsStrategyWarning />}
|
|
||||||
<p>Add a predefined segment to constrain this feature toggle:</p>
|
|
||||||
<AutocompleteBox
|
|
||||||
label='Select segments'
|
|
||||||
options={autocompleteOptions}
|
|
||||||
onChange={onChange}
|
|
||||||
disabled={atStrategySegmentsLimit}
|
|
||||||
/>
|
|
||||||
<FeatureStrategySegmentList
|
|
||||||
segments={selectedSegments}
|
|
||||||
setSegments={setSelectedSegments}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<StyledDivider />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
@ -3,16 +3,12 @@ import FeatureOverviewEnvironments from './FeatureOverviewEnvironments/FeatureOv
|
|||||||
import { Route, Routes, useNavigate } from 'react-router-dom';
|
import { Route, Routes, useNavigate } from 'react-router-dom';
|
||||||
import { FeatureStrategyCreate } from 'component/feature/FeatureStrategy/FeatureStrategyCreate/FeatureStrategyCreate';
|
import { FeatureStrategyCreate } from 'component/feature/FeatureStrategy/FeatureStrategyCreate/FeatureStrategyCreate';
|
||||||
import { SidebarModal } from 'component/common/SidebarModal/SidebarModal';
|
import { SidebarModal } from 'component/common/SidebarModal/SidebarModal';
|
||||||
import {
|
import { formatFeaturePath } from 'component/feature/FeatureStrategy/FeatureStrategyEdit/FeatureStrategyEdit';
|
||||||
FeatureStrategyEdit,
|
|
||||||
formatFeaturePath,
|
|
||||||
} from 'component/feature/FeatureStrategy/FeatureStrategyEdit/FeatureStrategyEdit';
|
|
||||||
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
||||||
import { usePageTitle } from 'hooks/usePageTitle';
|
import { usePageTitle } from 'hooks/usePageTitle';
|
||||||
import { FeatureOverviewSidePanel } from 'component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanel';
|
import { FeatureOverviewSidePanel } from 'component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanel';
|
||||||
import { useHiddenEnvironments } from 'hooks/useHiddenEnvironments';
|
import { useHiddenEnvironments } from 'hooks/useHiddenEnvironments';
|
||||||
import { styled } from '@mui/material';
|
import { styled } from '@mui/material';
|
||||||
import { useUiFlag } from 'hooks/useUiFlag';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { NewFeatureStrategyCreate } from 'component/feature/FeatureStrategy/NewFeatureStrategyCreate/NewFeatureStrategyCreate';
|
import { NewFeatureStrategyCreate } from 'component/feature/FeatureStrategy/NewFeatureStrategyCreate/NewFeatureStrategyCreate';
|
||||||
import { NewFeatureStrategyEdit } from 'component/feature/FeatureStrategy/NewFeatureStrategyEdit/NewFeatureStrategyEdit';
|
import { NewFeatureStrategyEdit } from 'component/feature/FeatureStrategy/NewFeatureStrategyEdit/NewFeatureStrategyEdit';
|
||||||
@ -44,8 +40,6 @@ const FeatureOverview = () => {
|
|||||||
const onSidebarClose = () => navigate(featurePath);
|
const onSidebarClose = () => navigate(featurePath);
|
||||||
usePageTitle(featureId);
|
usePageTitle(featureId);
|
||||||
|
|
||||||
const newStrategyConfiguration = useUiFlag('newStrategyConfiguration');
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<div>
|
<div>
|
||||||
@ -67,11 +61,7 @@ const FeatureOverview = () => {
|
|||||||
onClose={onSidebarClose}
|
onClose={onSidebarClose}
|
||||||
open
|
open
|
||||||
>
|
>
|
||||||
<ConditionallyRender
|
<NewFeatureStrategyCreate />
|
||||||
condition={newStrategyConfiguration}
|
|
||||||
show={<NewFeatureStrategyCreate />}
|
|
||||||
elseShow={<FeatureStrategyCreate />}
|
|
||||||
/>
|
|
||||||
</SidebarModal>
|
</SidebarModal>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -83,11 +73,7 @@ const FeatureOverview = () => {
|
|||||||
onClose={onSidebarClose}
|
onClose={onSidebarClose}
|
||||||
open
|
open
|
||||||
>
|
>
|
||||||
<ConditionallyRender
|
<NewFeatureStrategyEdit />
|
||||||
condition={newStrategyConfiguration}
|
|
||||||
show={<NewFeatureStrategyEdit />}
|
|
||||||
elseShow={<FeatureStrategyEdit />}
|
|
||||||
/>
|
|
||||||
</SidebarModal>
|
</SidebarModal>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Box, Typography, styled } from '@mui/material';
|
import { Box, styled } from '@mui/material';
|
||||||
import { IFeatureStrategyParameters } from 'interfaces/strategy';
|
import { IFeatureStrategyParameters } from 'interfaces/strategy';
|
||||||
import RolloutSlider from '../RolloutSlider/RolloutSlider';
|
import RolloutSlider from '../RolloutSlider/RolloutSlider';
|
||||||
import Input from 'component/common/Input/Input';
|
import Input from 'component/common/Input/Input';
|
||||||
@ -6,7 +6,6 @@ import {
|
|||||||
FLEXIBLE_STRATEGY_GROUP_ID,
|
FLEXIBLE_STRATEGY_GROUP_ID,
|
||||||
FLEXIBLE_STRATEGY_STICKINESS_ID,
|
FLEXIBLE_STRATEGY_STICKINESS_ID,
|
||||||
} from 'utils/testIds';
|
} from 'utils/testIds';
|
||||||
import { HelpIcon } from 'component/common/HelpIcon/HelpIcon';
|
|
||||||
import {
|
import {
|
||||||
parseParameterNumber,
|
parseParameterNumber,
|
||||||
parseParameterString,
|
parseParameterString,
|
||||||
@ -17,7 +16,6 @@ import Loader from '../../../common/Loader/Loader';
|
|||||||
import { useEffect, useMemo } from 'react';
|
import { useEffect, useMemo } from 'react';
|
||||||
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
||||||
import { useLocation } from 'react-router';
|
import { useLocation } from 'react-router';
|
||||||
import { useUiFlag } from 'hooks/useUiFlag';
|
|
||||||
|
|
||||||
interface IFlexibleStrategyProps {
|
interface IFlexibleStrategyProps {
|
||||||
parameters: IFeatureStrategyParameters;
|
parameters: IFeatureStrategyParameters;
|
||||||
@ -60,8 +58,6 @@ const FlexibleStrategy = ({
|
|||||||
const { defaultStickiness, loading } = useDefaultProjectSettings(projectId);
|
const { defaultStickiness, loading } = useDefaultProjectSettings(projectId);
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
|
|
||||||
const newStrategyConfiguration = useUiFlag('newStrategyConfiguration');
|
|
||||||
|
|
||||||
const isDefaultStrategyEdit = pathname.includes('default-strategy');
|
const isDefaultStrategyEdit = pathname.includes('default-strategy');
|
||||||
const onUpdate = (field: string) => (newValue: string) => {
|
const onUpdate = (field: string) => (newValue: string) => {
|
||||||
updateParameter(field, newValue);
|
updateParameter(field, newValue);
|
||||||
@ -98,7 +94,6 @@ const FlexibleStrategy = ({
|
|||||||
return <Loader />;
|
return <Loader />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newStrategyConfiguration) {
|
|
||||||
return (
|
return (
|
||||||
<StyledBox>
|
<StyledBox>
|
||||||
<RolloutSlider
|
<RolloutSlider
|
||||||
@ -114,9 +109,7 @@ const FlexibleStrategy = ({
|
|||||||
value={stickiness}
|
value={stickiness}
|
||||||
editable={editable}
|
editable={editable}
|
||||||
dataTestId={FLEXIBLE_STRATEGY_STICKINESS_ID}
|
dataTestId={FLEXIBLE_STRATEGY_STICKINESS_ID}
|
||||||
onChange={(e) =>
|
onChange={(e) => onUpdate('stickiness')(e.target.value)}
|
||||||
onUpdate('stickiness')(e.target.value)
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</StyledInnerBox1>
|
</StyledInnerBox1>
|
||||||
<StyledInnerBox2>
|
<StyledInnerBox2>
|
||||||
@ -126,73 +119,13 @@ const FlexibleStrategy = ({
|
|||||||
id='groupId-input'
|
id='groupId-input'
|
||||||
value={parseParameterString(parameters.groupId)}
|
value={parseParameterString(parameters.groupId)}
|
||||||
disabled={!editable}
|
disabled={!editable}
|
||||||
onChange={(e) =>
|
onChange={(e) => onUpdate('groupId')(e.target.value)}
|
||||||
onUpdate('groupId')(e.target.value)
|
|
||||||
}
|
|
||||||
data-testid={FLEXIBLE_STRATEGY_GROUP_ID}
|
data-testid={FLEXIBLE_STRATEGY_GROUP_ID}
|
||||||
/>
|
/>
|
||||||
</StyledInnerBox2>
|
</StyledInnerBox2>
|
||||||
</StyledOuterBox>
|
</StyledOuterBox>
|
||||||
</StyledBox>
|
</StyledBox>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<RolloutSlider
|
|
||||||
name='Rollout'
|
|
||||||
value={rollout}
|
|
||||||
disabled={!editable}
|
|
||||||
onChange={updateRollout}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<div>
|
|
||||||
<Typography
|
|
||||||
variant='subtitle2'
|
|
||||||
style={{
|
|
||||||
marginBottom: '1rem',
|
|
||||||
display: 'flex',
|
|
||||||
gap: '1ch',
|
|
||||||
}}
|
|
||||||
component='h2'
|
|
||||||
>
|
|
||||||
Stickiness
|
|
||||||
<HelpIcon tooltip='Stickiness defines what parameter should be used to ensure that your users get consistency in features. By default unleash will use the first value present in the context in the order of userId, sessionId and random.' />
|
|
||||||
</Typography>
|
|
||||||
<StickinessSelect
|
|
||||||
label='Stickiness'
|
|
||||||
value={stickiness}
|
|
||||||
editable={editable}
|
|
||||||
dataTestId={FLEXIBLE_STRATEGY_STICKINESS_ID}
|
|
||||||
onChange={(e) => onUpdate('stickiness')(e.target.value)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<Typography
|
|
||||||
variant='subtitle2'
|
|
||||||
style={{
|
|
||||||
marginBottom: '1rem',
|
|
||||||
display: 'flex',
|
|
||||||
gap: '1ch',
|
|
||||||
}}
|
|
||||||
component='h2'
|
|
||||||
>
|
|
||||||
GroupId
|
|
||||||
<HelpIcon tooltip='GroupId is used to ensure that different toggles will hash differently for the same user. The groupId defaults to feature toggle name, but you can override it to correlate rollout of multiple feature toggles.' />
|
|
||||||
</Typography>
|
|
||||||
<Input
|
|
||||||
label='groupId'
|
|
||||||
id='groupId-input'
|
|
||||||
value={parseParameterString(parameters.groupId)}
|
|
||||||
disabled={!editable}
|
|
||||||
onChange={(e) => onUpdate('groupId')(e.target.value)}
|
|
||||||
data-testid={FLEXIBLE_STRATEGY_GROUP_ID}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FlexibleStrategy;
|
export default FlexibleStrategy;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import Select from 'component/common/select';
|
import Select from 'component/common/select';
|
||||||
import { SelectChangeEvent, useTheme } from '@mui/material';
|
import { SelectChangeEvent, useTheme } from '@mui/material';
|
||||||
import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext';
|
import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext';
|
||||||
import { useUiFlag } from 'hooks/useUiFlag';
|
|
||||||
|
|
||||||
type OptionType = { key: string; label: string };
|
type OptionType = { key: string; label: string };
|
||||||
|
|
||||||
@ -23,7 +22,6 @@ export const StickinessSelect = ({
|
|||||||
dataTestId,
|
dataTestId,
|
||||||
}: IStickinessSelectProps) => {
|
}: IStickinessSelectProps) => {
|
||||||
const { context } = useUnleashContext();
|
const { context } = useUnleashContext();
|
||||||
const newStrategyConfiguration = useUiFlag('newStrategyConfiguration');
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const resolveStickinessOptions = () => {
|
const resolveStickinessOptions = () => {
|
||||||
@ -53,9 +51,6 @@ export const StickinessSelect = ({
|
|||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
|
|
||||||
// newStrategyConfiguration - Temporary check for backwards compatibility
|
|
||||||
const formControlStyles = newStrategyConfiguration ? { width: '100%' } : {};
|
|
||||||
|
|
||||||
const stickinessOptions = resolveStickinessOptions();
|
const stickinessOptions = resolveStickinessOptions();
|
||||||
return (
|
return (
|
||||||
<Select
|
<Select
|
||||||
@ -71,7 +66,7 @@ export const StickinessSelect = ({
|
|||||||
minWidth: '100%',
|
minWidth: '100%',
|
||||||
marginBottom: theme.spacing(2),
|
marginBottom: theme.spacing(2),
|
||||||
}}
|
}}
|
||||||
formControlStyles={formControlStyles}
|
formControlStyles={{ width: '100%' }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -129,7 +129,6 @@ exports[`should create default config 1`] = `
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"migrationLock": true,
|
"migrationLock": true,
|
||||||
"newStrategyConfiguration": false,
|
|
||||||
"newStrategyConfigurationFeedback": false,
|
"newStrategyConfigurationFeedback": false,
|
||||||
"personalAccessTokensKillSwitch": false,
|
"personalAccessTokensKillSwitch": false,
|
||||||
"proPlanAutoCharge": false,
|
"proPlanAutoCharge": false,
|
||||||
|
@ -28,7 +28,6 @@ export type IFlagKey =
|
|||||||
| 'disableMetrics'
|
| 'disableMetrics'
|
||||||
| 'scheduledConfigurationChanges'
|
| 'scheduledConfigurationChanges'
|
||||||
| 'stripClientHeadersOn304'
|
| 'stripClientHeadersOn304'
|
||||||
| 'newStrategyConfiguration'
|
|
||||||
| 'stripHeadersOnAPI'
|
| 'stripHeadersOnAPI'
|
||||||
| 'incomingWebhooks'
|
| 'incomingWebhooks'
|
||||||
| 'automatedActions'
|
| 'automatedActions'
|
||||||
@ -139,10 +138,6 @@ const flags: IFlags = {
|
|||||||
.UNLEASH_EXPERIMENTAL_DETECT_SEGMENT_USAGE_IN_CHANGE_REQUESTS,
|
.UNLEASH_EXPERIMENTAL_DETECT_SEGMENT_USAGE_IN_CHANGE_REQUESTS,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
newStrategyConfiguration: parseEnvVarBoolean(
|
|
||||||
process.env.UNLEASH_EXPERIMENTAL_NEW_STRATEGY_CONFIGURATION,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
incomingWebhooks: parseEnvVarBoolean(
|
incomingWebhooks: parseEnvVarBoolean(
|
||||||
process.env.UNLEASH_EXPERIMENTAL_INCOMING_WEBHOOKS,
|
process.env.UNLEASH_EXPERIMENTAL_INCOMING_WEBHOOKS,
|
||||||
false,
|
false,
|
||||||
|
@ -41,7 +41,6 @@ process.nextTick(async () => {
|
|||||||
anonymiseEventLog: false,
|
anonymiseEventLog: false,
|
||||||
responseTimeWithAppNameKillSwitch: false,
|
responseTimeWithAppNameKillSwitch: false,
|
||||||
stripClientHeadersOn304: true,
|
stripClientHeadersOn304: true,
|
||||||
newStrategyConfiguration: true,
|
|
||||||
stripHeadersOnAPI: true,
|
stripHeadersOnAPI: true,
|
||||||
celebrateUnleash: true,
|
celebrateUnleash: true,
|
||||||
increaseUnleashWidth: true,
|
increaseUnleashWidth: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user