mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-28 00:06:53 +01:00
feat: Limit environments component (#7548)
This commit is contained in:
parent
c802442846
commit
963d051632
@ -0,0 +1,57 @@
|
|||||||
|
import { screen } from '@testing-library/react';
|
||||||
|
import { render } from 'utils/testRenderer';
|
||||||
|
import { testServerRoute, testServerSetup } from '../../../utils/testServer';
|
||||||
|
import CreateEnvironment from './CreateEnvironment';
|
||||||
|
import { ADMIN } from '../../providers/AccessProvider/permissions';
|
||||||
|
|
||||||
|
const server = testServerSetup();
|
||||||
|
|
||||||
|
const setupApi = ({
|
||||||
|
resourceLimits,
|
||||||
|
limit,
|
||||||
|
environments,
|
||||||
|
}: { resourceLimits: boolean; limit: number; environments: number }) => {
|
||||||
|
testServerRoute(server, '/api/admin/ui-config', {
|
||||||
|
flags: {
|
||||||
|
resourceLimits,
|
||||||
|
},
|
||||||
|
resourceLimits: {
|
||||||
|
environments: limit,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
testServerRoute(server, '/api/admin/environments', {
|
||||||
|
environments: [...Array(environments).keys()].map((i) => ({
|
||||||
|
name: `environment${i}`,
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
test('show limit reached info', async () => {
|
||||||
|
setupApi({ environments: 1, limit: 1, resourceLimits: true });
|
||||||
|
render(<CreateEnvironment />, { permissions: [{ permission: ADMIN }] });
|
||||||
|
|
||||||
|
await screen.findByText('You have reached the limit for environments');
|
||||||
|
const createButton = await screen.findByText('Create environment', {
|
||||||
|
selector: 'button',
|
||||||
|
});
|
||||||
|
expect(createButton).toBeDisabled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('show approaching limit info', async () => {
|
||||||
|
setupApi({ environments: 9, limit: 10, resourceLimits: true });
|
||||||
|
render(<CreateEnvironment />, { permissions: [{ permission: ADMIN }] });
|
||||||
|
|
||||||
|
await screen.findByText('You are nearing the limit for environments');
|
||||||
|
const createButton = await screen.findByText('Create environment', {
|
||||||
|
selector: 'button',
|
||||||
|
});
|
||||||
|
expect(createButton).toBeEnabled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('show limit reached info - no resource limits component', async () => {
|
||||||
|
setupApi({ environments: 1, limit: 1, resourceLimits: false });
|
||||||
|
render(<CreateEnvironment />);
|
||||||
|
|
||||||
|
await screen.findByText('Go back');
|
||||||
|
});
|
@ -16,10 +16,13 @@ import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
|||||||
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
||||||
import { formatUnknownError } from 'utils/formatUnknownError';
|
import { formatUnknownError } from 'utils/formatUnknownError';
|
||||||
import { GO_BACK } from 'constants/navigate';
|
import { GO_BACK } from 'constants/navigate';
|
||||||
|
import { Limit } from 'component/common/Limit/Limit';
|
||||||
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
|
|
||||||
const CreateEnvironment = () => {
|
const CreateEnvironment = () => {
|
||||||
const { setToastApiError, setToastData } = useToast();
|
const { setToastApiError, setToastData } = useToast();
|
||||||
const { uiConfig } = useUiConfig();
|
const { uiConfig } = useUiConfig();
|
||||||
|
const resourceLimitsEnabled = useUiFlag('resourceLimits');
|
||||||
const environmentLimit = uiConfig.resourceLimits.environments;
|
const environmentLimit = uiConfig.resourceLimits.environments;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { environments } = useEnvironments();
|
const { environments } = useEnvironments();
|
||||||
@ -71,7 +74,7 @@ const CreateEnvironment = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={canCreateMoreEnvs}
|
condition={resourceLimitsEnabled || canCreateMoreEnvs}
|
||||||
show={
|
show={
|
||||||
<FormTemplate
|
<FormTemplate
|
||||||
loading={loading}
|
loading={loading}
|
||||||
@ -101,8 +104,24 @@ const CreateEnvironment = () => {
|
|||||||
setType={setType}
|
setType={setType}
|
||||||
mode='Create'
|
mode='Create'
|
||||||
clearErrors={clearErrors}
|
clearErrors={clearErrors}
|
||||||
|
Limit={
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={resourceLimitsEnabled}
|
||||||
|
show={
|
||||||
|
<Limit
|
||||||
|
name='environments'
|
||||||
|
limit={environmentLimit}
|
||||||
|
currentValue={environments.length}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<CreateButton name='environment' permission={ADMIN} />
|
<CreateButton
|
||||||
|
name='environment'
|
||||||
|
permission={ADMIN}
|
||||||
|
disabled={!canCreateMoreEnvs}
|
||||||
|
/>
|
||||||
</EnvironmentForm>
|
</EnvironmentForm>
|
||||||
</FormTemplate>
|
</FormTemplate>
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Button, styled } from '@mui/material';
|
import { Box, Button, styled } from '@mui/material';
|
||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
import Input from 'component/common/Input/Input';
|
import Input from 'component/common/Input/Input';
|
||||||
import EnvironmentTypeSelector from './EnvironmentTypeSelector/EnvironmentTypeSelector';
|
import EnvironmentTypeSelector from './EnvironmentTypeSelector/EnvironmentTypeSelector';
|
||||||
@ -16,6 +16,7 @@ interface IEnvironmentForm {
|
|||||||
mode: 'Create' | 'Edit';
|
mode: 'Create' | 'Edit';
|
||||||
clearErrors: () => void;
|
clearErrors: () => void;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
|
Limit?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StyledForm = styled('form')({
|
const StyledForm = styled('form')({
|
||||||
@ -52,6 +53,14 @@ const StyledCancelButton = styled(Button)(({ theme }) => ({
|
|||||||
marginLeft: theme.spacing(3),
|
marginLeft: theme.spacing(3),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const LimitContainer = styled(Box)(({ theme }) => ({
|
||||||
|
flex: 1,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'flex-end',
|
||||||
|
marginTop: theme.spacing(3),
|
||||||
|
marginBottom: theme.spacing(3),
|
||||||
|
}));
|
||||||
|
|
||||||
const EnvironmentForm: React.FC<IEnvironmentForm> = ({
|
const EnvironmentForm: React.FC<IEnvironmentForm> = ({
|
||||||
children,
|
children,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@ -64,6 +73,7 @@ const EnvironmentForm: React.FC<IEnvironmentForm> = ({
|
|||||||
errors,
|
errors,
|
||||||
mode,
|
mode,
|
||||||
clearErrors,
|
clearErrors,
|
||||||
|
Limit,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<StyledForm onSubmit={handleSubmit}>
|
<StyledForm onSubmit={handleSubmit}>
|
||||||
@ -93,6 +103,9 @@ const EnvironmentForm: React.FC<IEnvironmentForm> = ({
|
|||||||
value={type}
|
value={type}
|
||||||
/>
|
/>
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
|
|
||||||
|
<LimitContainer>{Limit}</LimitContainer>
|
||||||
|
|
||||||
<StyledButtonContainer>
|
<StyledButtonContainer>
|
||||||
{children}
|
{children}
|
||||||
<StyledCancelButton onClick={handleCancel}>
|
<StyledCancelButton onClick={handleCancel}>
|
||||||
|
@ -3,11 +3,7 @@ import { render } from 'utils/testRenderer';
|
|||||||
import FeatureOverviewEnvironment from './FeatureOverviewEnvironment';
|
import FeatureOverviewEnvironment from './FeatureOverviewEnvironment';
|
||||||
import { Route, Routes } from 'react-router-dom';
|
import { Route, Routes } from 'react-router-dom';
|
||||||
import { CREATE_FEATURE_STRATEGY } from 'component/providers/AccessProvider/permissions';
|
import { CREATE_FEATURE_STRATEGY } from 'component/providers/AccessProvider/permissions';
|
||||||
import type { IFeatureStrategy } from 'interfaces/strategy';
|
|
||||||
|
|
||||||
const strategy = {
|
|
||||||
name: 'default',
|
|
||||||
} as IFeatureStrategy;
|
|
||||||
const environmentWithoutStrategies = {
|
const environmentWithoutStrategies = {
|
||||||
name: 'production',
|
name: 'production',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user