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

refactor(templates): migrate list view to react [EE-2296] (#10999)

This commit is contained in:
Chaim Lev-Ari 2024-04-11 09:29:30 +03:00 committed by GitHub
parent d38085a560
commit 6ff4fd3db2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
103 changed files with 2628 additions and 1315 deletions

View file

@ -11,9 +11,7 @@ import { useEnvironmentId } from '@/react/hooks/useEnvironmentId';
import { isAgentEnvironment } from '@/react/portainer/environments/utils';
import { FeatureId } from '@/react/portainer/feature-flags/enums';
import { FormControl } from '@@/form-components/FormControl';
import { FormSection } from '@@/form-components/FormSection';
import { Input } from '@@/form-components/Input';
import { SwitchField } from '@@/form-components/SwitchField';
import { ImageConfigFieldset, ImageConfigValues } from '@@/ImageConfigFieldset';
import { LoadingButton } from '@@/buttons';
@ -23,6 +21,7 @@ import {
PortsMappingField,
Values as PortMappingValue,
} from './PortsMappingField';
import { NameField } from './NameField';
export interface Values {
name: string;
@ -74,19 +73,14 @@ export function BaseForm({
return (
<Widget>
<Widget.Body>
<FormControl label="Name" inputId="name-input" errors={errors?.name}>
<Input
id="name-input"
value={values.name}
onChange={(e) => {
const name = e.target.value;
onChangeName(name);
setFieldValue('name', name);
}}
placeholder="e.g. myContainer"
data-cy="container-name-input"
/>
</FormControl>
<NameField
value={values.name}
onChange={(name) => {
setFieldValue('name', name);
onChangeName(name);
}}
error={errors?.name}
/>
<FormSection title="Image Configuration">
<ImageConfigFieldset

View file

@ -0,0 +1,32 @@
import { string } from 'yup';
import { FormControl } from '@@/form-components/FormControl';
import { Input } from '@@/form-components/Input';
export function NameField({
value,
error,
onChange,
}: {
value: string;
error?: string;
onChange: (value: string) => void;
}) {
return (
<FormControl label="Name" inputId="name-input" errors={error}>
<Input
id="name-input"
value={value}
onChange={(e) => {
onChange(e.target.value);
}}
placeholder="e.g. myContainer"
data-cy="container-name-input"
/>
</FormControl>
);
}
export function nameValidation() {
return string().default('');
}

View file

@ -9,7 +9,7 @@ type PortKey = `${string}/${Protocol}`;
export function parsePortBindingRequest(portBindings: Values): PortMap {
const bindings: Record<
PortKey,
Array<{ HostIp: string; HostPort: string }>
Array<{ HostIp?: string; HostPort?: string }>
> = {};
_.forEach(portBindings, (portBinding) => {
if (!portBinding.containerPort) {
@ -17,9 +17,6 @@ export function parsePortBindingRequest(portBindings: Values): PortMap {
}
const portInfo = extractPortInfo(portBinding);
if (!portInfo) {
return;
}
let { hostPort } = portBinding;
const { endHostPort, endPort, hostIp, startHostPort, startPort } = portInfo;
@ -36,7 +33,9 @@ export function parsePortBindingRequest(portBindings: Values): PortMap {
hostPort += `-${endHostPort.toString()}`;
}
bindings[bindKey].push({ HostIp: hostIp, HostPort: hostPort });
bindings[bindKey].push(
hostIp || hostPort ? { HostIp: hostIp, HostPort: hostPort } : {}
);
});
});
return bindings;
@ -71,7 +70,13 @@ function parsePort(port: string) {
return 0;
}
function extractPortInfo(portBinding: PortMapping) {
function extractPortInfo(portBinding: PortMapping): {
startPort: number;
endPort: number;
hostIp: string;
startHostPort: number;
endHostPort: number;
} {
const containerPortRange = parsePortRange(portBinding.containerPort);
if (!isValidPortRange(containerPortRange)) {
throw new Error(`Invalid port specification: ${portBinding.containerPort}`);
@ -82,7 +87,13 @@ function extractPortInfo(portBinding: PortMapping) {
let hostIp = '';
let { hostPort } = portBinding;
if (!hostPort) {
return null;
return {
startPort,
endPort,
hostIp: '',
startHostPort: 0,
endHostPort: 0,
};
}
if (hostPort.includes('[')) {

View file

@ -5,7 +5,7 @@ import { Values } from './PortsMappingField';
export function validationSchema(): SchemaOf<Values> {
return array(
object({
hostPort: string().required('host is required'),
hostPort: string().default(''),
containerPort: string().required('container is required'),
protocol: mixed().oneOf(['tcp', 'udp']),
})

View file

@ -6,6 +6,7 @@ import { imageConfigValidation } from '@@/ImageConfigFieldset';
import { Values } from './BaseForm';
import { validationSchema as portsSchema } from './PortsMappingField.validation';
import { nameValidation } from './NameField';
export function validation(
{
@ -26,9 +27,10 @@ export function validation(
}
): SchemaOf<Values> {
return object({
name: string()
.default('')
.test('not-duplicate-portainer', () => !isDuplicatingPortainer),
name: nameValidation().test(
'not-duplicate-portainer',
() => !isDuplicatingPortainer
),
alwaysPull: boolean()
.default(true)
.test('rate-limits', 'Rate limit exceeded', (alwaysPull: boolean) =>