mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
feat: constraints limit in a strategy UI (#7555)
This commit is contained in:
parent
7ca2ace0bc
commit
5ed4ccc981
@ -0,0 +1,61 @@
|
||||
import { screen } from '@testing-library/react';
|
||||
import { render } from 'utils/testRenderer';
|
||||
import { testServerRoute, testServerSetup } from 'utils/testServer';
|
||||
import { FeatureStrategyConstraintAccordionList } from './FeatureStrategyConstraintAccordionList';
|
||||
import type { IConstraint } from 'interfaces/strategy';
|
||||
|
||||
const server = testServerSetup();
|
||||
|
||||
const LIMIT = 5;
|
||||
|
||||
const setupApi = () => {
|
||||
testServerRoute(server, '/api/admin/ui-config', {
|
||||
flags: {
|
||||
resourceLimits: true,
|
||||
},
|
||||
resourceLimits: {
|
||||
constraints: LIMIT,
|
||||
},
|
||||
});
|
||||
testServerRoute(server, '/api/admin/context', [{ name: 'text' }]);
|
||||
};
|
||||
|
||||
const constraints = (limit: number): IConstraint[] =>
|
||||
Array.from(Array(limit).keys()).map(() => ({
|
||||
contextName: 'test',
|
||||
operator: 'IN',
|
||||
}));
|
||||
|
||||
test('show limit reached and disable adding new constraints', async () => {
|
||||
setupApi();
|
||||
render(
|
||||
<FeatureStrategyConstraintAccordionList
|
||||
constraints={constraints(LIMIT)}
|
||||
showCreateButton={true}
|
||||
setConstraints={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
await screen.findByText(
|
||||
'You have reached the limit for constraints in this strategy',
|
||||
);
|
||||
const button = await screen.findByText('Add constraint');
|
||||
expect(button).toBeDisabled();
|
||||
});
|
||||
|
||||
test('show nearing limit', async () => {
|
||||
setupApi();
|
||||
render(
|
||||
<FeatureStrategyConstraintAccordionList
|
||||
constraints={constraints(LIMIT - 1)}
|
||||
showCreateButton={true}
|
||||
setConstraints={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
await screen.findByText(
|
||||
'You are nearing the limit for constraints in this strategy',
|
||||
);
|
||||
const button = await screen.findByText('Add constraint');
|
||||
expect(button).toBeEnabled();
|
||||
});
|
@ -12,6 +12,9 @@ import {
|
||||
useConstraintAccordionList,
|
||||
} from 'component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList';
|
||||
import { NewConstraintAccordionList } from 'component/common/NewConstraintAccordion/NewConstraintAccordionList/NewConstraintAccordionList';
|
||||
import { Limit } from 'component/common/Limit/Limit';
|
||||
import { useUiFlag } from 'hooks/useUiFlag';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
|
||||
interface IConstraintAccordionListProps {
|
||||
constraints: IConstraint[];
|
||||
@ -60,6 +63,20 @@ const StyledHelpIconBox = styled(Box)(({ theme }) => ({
|
||||
marginBottom: theme.spacing(1),
|
||||
}));
|
||||
|
||||
const useConstraintLimit = (constraintsCount: number) => {
|
||||
const resourceLimitsEnabled = useUiFlag('resourceLimits');
|
||||
const { uiConfig } = useUiConfig();
|
||||
const constraintsLimit = uiConfig.resourceLimits?.constraints || 30;
|
||||
const limitReached =
|
||||
resourceLimitsEnabled && constraintsCount >= constraintsLimit;
|
||||
|
||||
return {
|
||||
resourceLimitsEnabled,
|
||||
limit: constraintsLimit,
|
||||
limitReached,
|
||||
};
|
||||
};
|
||||
|
||||
export const FeatureStrategyConstraintAccordionList = forwardRef<
|
||||
IConstraintAccordionListRef | undefined,
|
||||
IConstraintAccordionListProps
|
||||
@ -72,6 +89,8 @@ export const FeatureStrategyConstraintAccordionList = forwardRef<
|
||||
setConstraints,
|
||||
ref as RefObject<IConstraintAccordionListRef>,
|
||||
);
|
||||
const { resourceLimitsEnabled, limit, limitReached } =
|
||||
useConstraintLimit(constraints.length);
|
||||
|
||||
if (context.length === 0) {
|
||||
return null;
|
||||
@ -113,14 +132,34 @@ export const FeatureStrategyConstraintAccordionList = forwardRef<
|
||||
constraints={constraints}
|
||||
state={state}
|
||||
/>
|
||||
|
||||
<Box
|
||||
sx={(theme) => ({
|
||||
marginTop: theme.spacing(2),
|
||||
marginBottom: theme.spacing(2),
|
||||
})}
|
||||
>
|
||||
<ConditionallyRender
|
||||
condition={resourceLimitsEnabled}
|
||||
show={
|
||||
<Limit
|
||||
name='constraints in this strategy'
|
||||
shortName='constraints'
|
||||
currentValue={constraints.length}
|
||||
limit={limit}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Button
|
||||
sx={{ marginTop: '1rem' }}
|
||||
type='button'
|
||||
onClick={onAdd}
|
||||
startIcon={<Add />}
|
||||
variant='outlined'
|
||||
color='primary'
|
||||
data-testid='ADD_CONSTRAINT_BUTTON'
|
||||
disabled={Boolean(limitReached)}
|
||||
>
|
||||
Add constraint
|
||||
</Button>
|
||||
|
@ -40,6 +40,7 @@ export const defaultValue: IUiConfig = {
|
||||
featureEnvironmentStrategies: 30,
|
||||
environments: 50,
|
||||
constraintValues: 250,
|
||||
constraints: 30,
|
||||
projects: 500,
|
||||
segments: 300,
|
||||
apiTokens: 2000,
|
||||
|
@ -30,6 +30,8 @@ export interface ResourceLimitsSchema {
|
||||
environments: number;
|
||||
/** The maximum number of values for a single constraint. */
|
||||
constraintValues: number;
|
||||
/** The maximum number of constraints for a single strategy. */
|
||||
constraints: number;
|
||||
/** The maximum number of projects allowed. */
|
||||
projects: number;
|
||||
/** The maximum number of segments allowed. */
|
||||
|
Loading…
Reference in New Issue
Block a user