diff --git a/app/docker/react/components/containers.ts b/app/docker/react/components/containers.ts index c93d7e49e..827ae9d5e 100644 --- a/app/docker/react/components/containers.ts +++ b/app/docker/react/components/containers.ts @@ -12,6 +12,11 @@ import { import { r2a } from '@/react-tools/react2angular'; import { withCurrentUser } from '@/react-tools/withCurrentUser'; import { ContainerNetworksDatatable } from '@/react/docker/containers/ItemView/ContainerNetworksDatatable'; +import { + EnvVarsTab, + Values as EnvVarsTabValues, + envVarsTabUtils, +} from '@/react/docker/containers/CreateView/EnvVarsTab'; const ngModule = angular .module('portainer.docker.react.components.containers', []) @@ -33,3 +38,11 @@ withFormValidation, CommandsTabValues>( ['apiVersion'], commandsTabValidation ); + +withFormValidation, EnvVarsTabValues>( + ngModule, + withUIRouter(withReactQuery(EnvVarsTab)), + 'dockerCreateContainerEnvVarsTab', + [], + envVarsTabUtils.validation +); diff --git a/app/docker/views/containers/create/createContainerController.js b/app/docker/views/containers/create/createContainerController.js index 75f13d9d2..25104500a 100644 --- a/app/docker/views/containers/create/createContainerController.js +++ b/app/docker/views/containers/create/createContainerController.js @@ -1,6 +1,5 @@ import _ from 'lodash-es'; -import * as envVarsUtils from '@/react/components/form-components/EnvironmentVariablesFieldset/utils'; import { PorImageRegistryModel } from 'Docker/models/porImageRegistry'; import { confirmDestructive } from '@@/modals/confirm'; @@ -13,6 +12,7 @@ import { AccessControlFormData } from '@/portainer/components/accessControlForm/ import { ContainerDetailsViewModel } from '@/docker/models/container'; import './createcontainer.css'; +import { envVarsTabUtils } from '@/react/docker/containers/CreateView/EnvVarsTab'; angular.module('portainer.docker').controller('CreateContainerController', [ '$q', @@ -89,12 +89,12 @@ angular.module('portainer.docker').controller('CreateContainerController', [ MemoryLimit: 0, MemoryReservation: 0, ShmSize: 64, - Env: [], NodeName: null, capabilities: [], Sysctls: [], RegistryModel: new PorImageRegistryModel(), commands: commandsTabUtils.getDefaultViewModel(), + envVars: envVarsTabUtils.getDefaultViewModel(), }; $scope.extraNetworks = {}; @@ -114,6 +114,7 @@ angular.module('portainer.docker').controller('CreateContainerController', [ $scope.handlePrivilegedChange = handlePrivilegedChange; $scope.handleInitChange = handleInitChange; $scope.handleCommandsChange = handleCommandsChange; + $scope.handleEnvVarsChange = handleEnvVarsChange; function handleCommandsChange(commands) { return $scope.$evalAsync(() => { @@ -121,6 +122,12 @@ angular.module('portainer.docker').controller('CreateContainerController', [ }); } + function handleEnvVarsChange(value) { + return $scope.$evalAsync(() => { + $scope.formValues.envVars = value; + }); + } + function onAlwaysPullChange(checked) { return $scope.$evalAsync(() => { $scope.formValues.alwaysPull = checked; @@ -151,11 +158,6 @@ angular.module('portainer.docker').controller('CreateContainerController', [ }); } - $scope.handleEnvVarChange = handleEnvVarChange; - function handleEnvVarChange(value) { - $scope.formValues.Env = value; - } - $scope.refreshSlider = function () { $timeout(function () { $scope.$broadcast('rzSliderForceRender'); @@ -281,10 +283,6 @@ angular.module('portainer.docker').controller('CreateContainerController', [ config.HostConfig.PortBindings = bindings; } - function prepareEnvironmentVariables(config) { - config.Env = envVarsUtils.convertToArrayOfStrings($scope.formValues.Env); - } - function prepareVolumes(config) { var binds = []; var volumes = {}; @@ -462,11 +460,11 @@ angular.module('portainer.docker').controller('CreateContainerController', [ function prepareConfiguration() { var config = angular.copy($scope.config); config = commandsTabUtils.toRequest(config, $scope.formValues.commands); + config = envVarsTabUtils.toRequest(config, $scope.formValues.envVars); prepareNetworkConfig(config); prepareImageConfig(config); preparePortBindings(config); - prepareEnvironmentVariables(config); prepareVolumes(config); prepareLabels(config); prepareDevices(config); @@ -561,10 +559,6 @@ angular.module('portainer.docker').controller('CreateContainerController', [ } } - function loadFromContainerEnvironmentVariables() { - $scope.formValues.Env = envVarsUtils.parseArrayOfStrings($scope.config.Env); - } - function loadFromContainerLabels() { for (var l in $scope.config.Labels) { if ({}.hasOwnProperty.call($scope.config.Labels, l)) { @@ -687,11 +681,12 @@ angular.module('portainer.docker').controller('CreateContainerController', [ $scope.config = ContainerHelper.configFromContainer(fromContainer.Model); $scope.formValues.commands = commandsTabUtils.toViewModel(d); + $scope.formValues.envVars = envVarsTabUtils.toViewModel(d); loadFromContainerPortBindings(d); loadFromContainerVolumes(d); loadFromContainerNetworkConfig(d); - loadFromContainerEnvironmentVariables(d); + loadFromContainerLabels(d); loadFromContainerDevices(d); loadFromContainerDeviceRequests(d); diff --git a/app/docker/views/containers/create/createcontainer.html b/app/docker/views/containers/create/createcontainer.html index f50030b33..ca32dcba2 100644 --- a/app/docker/views/containers/create/createcontainer.html +++ b/app/docker/views/containers/create/createcontainer.html @@ -434,13 +434,11 @@
-
- -
+
diff --git a/app/react/docker/containers/CreateView/EnvVarsTab/EnvVarsTab.tsx b/app/react/docker/containers/CreateView/EnvVarsTab/EnvVarsTab.tsx new file mode 100644 index 000000000..8c5053b40 --- /dev/null +++ b/app/react/docker/containers/CreateView/EnvVarsTab/EnvVarsTab.tsx @@ -0,0 +1,32 @@ +import { useState } from 'react'; + +import { EnvironmentVariablesPanel } from '@@/form-components/EnvironmentVariablesFieldset'; +import { ArrayError } from '@@/form-components/InputList/InputList'; + +import { Values } from './types'; + +export function EnvVarsTab({ + values: initialValues, + onChange, + errors, +}: { + values: Values; + onChange(value: Values): void; + errors?: ArrayError; +}) { + const [values, setControlledValues] = useState(initialValues); + + return ( + + ); + + function handleChange(values: Values) { + setControlledValues(values); + onChange(values); + } +} diff --git a/app/react/docker/containers/CreateView/EnvVarsTab/index.ts b/app/react/docker/containers/CreateView/EnvVarsTab/index.ts new file mode 100644 index 000000000..3ff04e636 --- /dev/null +++ b/app/react/docker/containers/CreateView/EnvVarsTab/index.ts @@ -0,0 +1,14 @@ +import { envVarValidation } from '@@/form-components/EnvironmentVariablesFieldset'; + +import { toRequest } from './toRequest'; +import { toViewModel, getDefaultViewModel } from './toViewModel'; + +export { EnvVarsTab } from './EnvVarsTab'; +export type { Values } from './types'; + +export const envVarsTabUtils = { + toRequest, + toViewModel, + validation: envVarValidation, + getDefaultViewModel, +}; diff --git a/app/react/docker/containers/CreateView/EnvVarsTab/toRequest.ts b/app/react/docker/containers/CreateView/EnvVarsTab/toRequest.ts new file mode 100644 index 000000000..aa42efca4 --- /dev/null +++ b/app/react/docker/containers/CreateView/EnvVarsTab/toRequest.ts @@ -0,0 +1,15 @@ +import { convertToArrayOfStrings } from '@@/form-components/EnvironmentVariablesFieldset/utils'; + +import { CreateContainerRequest } from '../types'; + +import { Values } from './types'; + +export function toRequest( + oldConfig: CreateContainerRequest, + values: Values +): CreateContainerRequest { + return { + ...oldConfig, + Env: convertToArrayOfStrings(values), + }; +} diff --git a/app/react/docker/containers/CreateView/EnvVarsTab/toViewModel.ts b/app/react/docker/containers/CreateView/EnvVarsTab/toViewModel.ts new file mode 100644 index 000000000..1e1bb906e --- /dev/null +++ b/app/react/docker/containers/CreateView/EnvVarsTab/toViewModel.ts @@ -0,0 +1,11 @@ +import { parseArrayOfStrings } from '@@/form-components/EnvironmentVariablesFieldset/utils'; + +import { ContainerJSON } from '../../queries/container'; + +export function getDefaultViewModel() { + return []; +} + +export function toViewModel(container: ContainerJSON) { + return parseArrayOfStrings(container.Config?.Env); +} diff --git a/app/react/docker/containers/CreateView/EnvVarsTab/types.ts b/app/react/docker/containers/CreateView/EnvVarsTab/types.ts new file mode 100644 index 000000000..a3029f519 --- /dev/null +++ b/app/react/docker/containers/CreateView/EnvVarsTab/types.ts @@ -0,0 +1 @@ +export type { Value as Values } from '@@/form-components/EnvironmentVariablesFieldset/types';