From 7acde189309b8b426bfd0f055acee276dc6bf1a9 Mon Sep 17 00:00:00 2001 From: Chaim Lev-Ari Date: Tue, 26 Sep 2023 13:54:45 +0300 Subject: [PATCH] feat(containers): migrate labels tab to react [EE-5212] (#10348) --- app/docker/react/components/containers.ts | 12 ++++++ .../create/createContainerController.js | 43 ++++--------------- .../containers/create/createcontainer.html | 34 ++------------- app/react-tools/withFormValidation.ts | 4 +- .../containers/CreateView/LabelsTab/Item.tsx | 31 +++++++++++++ .../CreateView/LabelsTab/LabelsTab.tsx | 35 +++++++++++++++ .../containers/CreateView/LabelsTab/index.ts | 14 ++++++ .../CreateView/LabelsTab/toRequest.ts | 17 ++++++++ .../CreateView/LabelsTab/toViewModel.ts | 18 ++++++++ .../containers/CreateView/LabelsTab/types.ts | 6 +++ .../CreateView/LabelsTab/validation.ts | 12 ++++++ 11 files changed, 159 insertions(+), 67 deletions(-) create mode 100644 app/react/docker/containers/CreateView/LabelsTab/Item.tsx create mode 100644 app/react/docker/containers/CreateView/LabelsTab/LabelsTab.tsx create mode 100644 app/react/docker/containers/CreateView/LabelsTab/index.ts create mode 100644 app/react/docker/containers/CreateView/LabelsTab/toRequest.ts create mode 100644 app/react/docker/containers/CreateView/LabelsTab/toViewModel.ts create mode 100644 app/react/docker/containers/CreateView/LabelsTab/types.ts create mode 100644 app/react/docker/containers/CreateView/LabelsTab/validation.ts diff --git a/app/docker/react/components/containers.ts b/app/docker/react/components/containers.ts index e12ea93d8..257807eeb 100644 --- a/app/docker/react/components/containers.ts +++ b/app/docker/react/components/containers.ts @@ -38,6 +38,10 @@ import { RestartPolicyTab, restartPolicyTabUtils, } from '@/react/docker/containers/CreateView/RestartPolicyTab'; +import { + LabelsTab, + labelsTabUtils, +} from '@/react/docker/containers/CreateView/LabelsTab'; const ngModule = angular .module('portainer.docker.react.components.containers', []) @@ -114,3 +118,11 @@ withFormValidation( [], restartPolicyTabUtils.validation ); + +withFormValidation( + ngModule, + withUIRouter(withReactQuery(LabelsTab)), + 'dockerCreateContainerLabelsTab', + [], + labelsTabUtils.validation +); diff --git a/app/docker/views/containers/create/createContainerController.js b/app/docker/views/containers/create/createContainerController.js index 4e6b7d617..7e088026d 100644 --- a/app/docker/views/containers/create/createContainerController.js +++ b/app/docker/views/containers/create/createContainerController.js @@ -12,6 +12,7 @@ import { networkTabUtils } from '@/react/docker/containers/CreateView/NetworkTab import { capabilitiesTabUtils } from '@/react/docker/containers/CreateView/CapabilitiesTab'; import { AccessControlFormData } from '@/portainer/components/accessControlForm/porAccessControlFormModel'; import { ContainerDetailsViewModel } from '@/docker/models/container'; +import { labelsTabUtils } from '@/react/docker/containers/CreateView/LabelsTab'; import './createcontainer.css'; import { envVarsTabUtils } from '@/react/docker/containers/CreateView/EnvVarsTab'; @@ -77,7 +78,6 @@ angular.module('portainer.docker').controller('CreateContainerController', [ selectedGPUs: ['all'], capabilities: ['compute', 'utility'], }, - Labels: [], ExtraHosts: [], MacAddress: '', IPv4: '', @@ -95,6 +95,7 @@ angular.module('portainer.docker').controller('CreateContainerController', [ resources: resourcesTabUtils.getDefaultViewModel(), capabilities: capabilitiesTabUtils.getDefaultViewModel(), restartPolicy: restartPolicyTabUtils.getDefaultViewModel(), + labels: labelsTabUtils.getDefaultViewModel(), }; $scope.state = { @@ -136,6 +137,11 @@ angular.module('portainer.docker').controller('CreateContainerController', [ $scope.formValues.network = network; }); }; + $scope.onLabelsChange = function (labels) { + return $scope.$evalAsync(() => { + $scope.formValues.labels = labels; + }); + }; $scope.onResourcesChange = function (resources) { return $scope.$evalAsync(() => { @@ -250,14 +256,6 @@ angular.module('portainer.docker').controller('CreateContainerController', [ $scope.config.HostConfig.PortBindings.splice(index, 1); }; - $scope.addLabel = function () { - $scope.formValues.Labels.push({ name: '', value: '' }); - }; - - $scope.removeLabel = function (index) { - $scope.formValues.Labels.splice(index, 1); - }; - $scope.addExtraHost = function () { $scope.formValues.ExtraHosts.push({ value: '' }); }; @@ -302,20 +300,6 @@ angular.module('portainer.docker').controller('CreateContainerController', [ config.HostConfig.PortBindings = bindings; } - function prepareLabels(config) { - var labels = {}; - $scope.formValues.Labels.forEach(function (label) { - if (label.name) { - if (label.value) { - labels[label.name] = label.value; - } else { - labels[label.name] = ''; - } - } - }); - config.Labels = labels; - } - function prepareConfiguration() { var config = angular.copy($scope.config); config = commandsTabUtils.toRequest(config, $scope.formValues.commands); @@ -325,11 +309,10 @@ angular.module('portainer.docker').controller('CreateContainerController', [ config = resourcesTabUtils.toRequest(config, $scope.formValues.resources); config = capabilitiesTabUtils.toRequest(config, $scope.formValues.capabilities); config = restartPolicyTabUtils.toRequest(config, $scope.formValues.restartPolicy); + config = labelsTabUtils.toRequest(config, $scope.formValues.labels); prepareImageConfig(config); preparePortBindings(config); - prepareLabels(config); - return config; } function loadFromContainerPortBindings() { @@ -337,14 +320,6 @@ angular.module('portainer.docker').controller('CreateContainerController', [ $scope.config.HostConfig.PortBindings = bindings; } - function loadFromContainerLabels() { - for (var l in $scope.config.Labels) { - if ({}.hasOwnProperty.call($scope.config.Labels, l)) { - $scope.formValues.Labels.push({ name: l, value: $scope.config.Labels[l] }); - } - } - } - function loadFromContainerImageConfig() { RegistryService.retrievePorRegistryModelFromRepository($scope.config.Image, endpoint.Id) .then((model) => { @@ -381,11 +356,11 @@ angular.module('portainer.docker').controller('CreateContainerController', [ $scope.formValues.network = networkTabUtils.toViewModel(d, $scope.availableNetworks, $scope.runningContainers); $scope.formValues.resources = resourcesTabUtils.toViewModel(d); $scope.formValues.capabilities = capabilitiesTabUtils.toViewModel(d); + $scope.formValues.labels = labelsTabUtils.toViewModel(d); $scope.formValues.restartPolicy = restartPolicyTabUtils.toViewModel(d); loadFromContainerPortBindings(d); - loadFromContainerLabels(d); loadFromContainerImageConfig(d); }) .then(() => { diff --git a/app/docker/views/containers/create/createcontainer.html b/app/docker/views/containers/create/createcontainer.html index 821c3f3f6..68b79f36c 100644 --- a/app/docker/views/containers/create/createcontainer.html +++ b/app/docker/views/containers/create/createcontainer.html @@ -201,13 +201,12 @@
  • Runtime & Resources
  • Capabilities
  • -
    +
    -
    -
    - -
    -
    - - add label -
    - -
    -
    -
    - name - -
    -
    - value - -
    - -
    -
    - -
    - -
    +
    - +
    { - onChange(values: TValue): void; - values: TValue; + onChange(values: TValue): void; // update the values for the entire form object used in yup validation, not just one input. + values: TValue; // current values errors?: FormikErrors | ArrayError; } diff --git a/app/react/docker/containers/CreateView/LabelsTab/Item.tsx b/app/react/docker/containers/CreateView/LabelsTab/Item.tsx new file mode 100644 index 000000000..98c40fcb9 --- /dev/null +++ b/app/react/docker/containers/CreateView/LabelsTab/Item.tsx @@ -0,0 +1,31 @@ +import { FormError } from '@@/form-components/FormError'; +import { InputGroup } from '@@/form-components/InputGroup'; +import { ItemProps } from '@@/form-components/InputList'; + +import { Label } from './types'; + +export function Item({ item, onChange, error }: ItemProps