1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-23 07:19:41 +02:00

refactor(app): migrate replicas form section [EE-6238] (#10705)

Co-authored-by: testa113 <testa113>
This commit is contained in:
Ali 2024-01-03 10:27:38 +13:00 committed by GitHub
parent 58da51f767
commit 6da71661d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 142 additions and 66 deletions

View file

@ -0,0 +1,60 @@
import { FormikErrors } from 'formik';
import { round } from 'lodash';
import { FormControl } from '@@/form-components/FormControl';
import { Input } from '@@/form-components/Input';
import { TextTip } from '@@/Tip/TextTip';
import { FormError } from '@@/form-components/FormError';
import { ReplicaCountFormValues } from './types';
type Props = {
values: ReplicaCountFormValues;
onChange: (values: ReplicaCountFormValues) => void;
errors: FormikErrors<ReplicaCountFormValues>;
cpuLimit: number;
memoryLimit: number;
resourceReservationsOverflow: boolean;
supportScalableReplicaDeployment: boolean;
};
export function ReplicationFormSection({
values,
onChange,
errors,
supportScalableReplicaDeployment,
cpuLimit,
memoryLimit,
resourceReservationsOverflow,
}: Props) {
const hasResourceLimit = cpuLimit !== 0 || memoryLimit !== 0;
return (
<>
<FormControl label="Instance count" required>
<Input
type="number"
min="1"
max="9999"
value={values.replicaCount}
disabled={!supportScalableReplicaDeployment}
onChange={(e) =>
onChange({ replicaCount: e.target.valueAsNumber || 1 })
}
className="w-1/4"
data-cy="k8sAppCreate-replicaCountInput"
/>
</FormControl>
{!resourceReservationsOverflow &&
values.replicaCount > 1 &&
hasResourceLimit && (
<TextTip color="blue">
This application will reserve the following resources:{' '}
<b>{round(cpuLimit * values.replicaCount, 2)} CPU</b> and{' '}
<b>{memoryLimit * values.replicaCount} MB</b> of memory.
</TextTip>
)}
{errors?.replicaCount && <FormError>{errors.replicaCount}</FormError>}
</>
);
}

View file

@ -0,0 +1,2 @@
export { ReplicationFormSection } from './ReplicationFormSection';
export { replicationValidation } from './replicationValidation';

View file

@ -0,0 +1,41 @@
import { SchemaOf, number, object } from 'yup';
import { ReplicaCountFormValues } from './types';
type ValidationData = {
resourceReservationsOverflow: boolean;
quotaExceeded: boolean;
nonScalableStorage: string;
supportScalableReplicaDeployment: boolean;
};
export function replicationValidation(
validationData?: ValidationData
): SchemaOf<ReplicaCountFormValues> {
const {
resourceReservationsOverflow,
quotaExceeded,
nonScalableStorage,
supportScalableReplicaDeployment,
} = validationData || {};
return object({
replicaCount: number()
.min(1, 'Instance count must be greater than 0.')
.test(
'overflow',
'This application would exceed available resources. Please review resource reservations or the instance count.',
() => !resourceReservationsOverflow // must not have resource reservations overflow
)
.test(
'quota',
'This application would exceed available storage. Please review the persisted folders or the instance count.',
() => !quotaExceeded // must not have quota exceeded
)
.test(
'scalable',
`The following storage option(s) do not support concurrent access from multiples instances: ${nonScalableStorage}. You will not be able to scale that application.`,
() => !!supportScalableReplicaDeployment // must have support scalable replica deployment
)
.required('Instance count is required.'),
});
}

View file

@ -0,0 +1,3 @@
export type ReplicaCountFormValues = {
replicaCount: number;
};