diff --git a/app/docker/views/services/create/createServiceController.js b/app/docker/views/services/create/createServiceController.js index 046d248e6..2602d407d 100644 --- a/app/docker/views/services/create/createServiceController.js +++ b/app/docker/views/services/create/createServiceController.js @@ -165,6 +165,7 @@ angular.module('portainer.docker').controller('CreateServiceController', [ $scope.removeConfig = function (index) { $scope.formValues.Configs.splice(index, 1); + $scope.checkIfConfigDuplicated(); }; $scope.addSecret = function () { @@ -173,6 +174,7 @@ angular.module('portainer.docker').controller('CreateServiceController', [ $scope.removeSecret = function (index) { $scope.formValues.Secrets.splice(index, 1); + $scope.checkIfSecretDuplicated(); }; $scope.addPlacementConstraint = function () { @@ -215,6 +217,36 @@ angular.module('portainer.docker').controller('CreateServiceController', [ $scope.formValues.LogDriverOpts.splice(index, 1); }; + $scope.checkIfSecretDuplicated = function () { + $scope.formValues.Secrets.$invalid = false; + [...$scope.formValues.Secrets] + .sort((a, b) => a.model.Id.localeCompare(b.model.Id)) + .sort((a, b) => { + if (a.model.Id === b.model.Id) { + $scope.formValues.Secrets.$invalid = true; + $scope.formValues.Secrets.$error = 'Secret ' + a.model.Name + ' cannot be assigned multiple times.'; + } + }); + if (!$scope.formValues.Secrets.$invalid) { + $scope.formValues.Secrets.$error = ''; + } + }; + + $scope.checkIfConfigDuplicated = function () { + $scope.formValues.Configs.$invalid = false; + [...$scope.formValues.Configs] + .sort((a, b) => a.model.Id.localeCompare(b.model.Id)) + .sort((a, b) => { + if (a.model.Id === b.model.Id) { + $scope.formValues.Configs.$invalid = true; + $scope.formValues.Configs.$error = 'Config ' + a.model.Name + ' cannot be assigned multiple times.'; + } + }); + if (!$scope.formValues.Configs.$invalid) { + $scope.formValues.Configs.$error = ''; + } + }; + function prepareImageConfig(config, input) { var imageConfig = ImageHelper.createImageConfigForContainer(input.RegistryModel); config.TaskTemplate.ContainerSpec.Image = imageConfig.fromImage; @@ -511,7 +543,7 @@ angular.module('portainer.docker').controller('CreateServiceController', [ function validateForm(accessControlData, isAdmin) { $scope.state.formValidationError = ''; var error = ''; - error = FormValidator.validateAccessControl(accessControlData, isAdmin); + error = FormValidator.validateAccessControl(accessControlData, isAdmin) || $scope.formValues.Secrets.$error || $scope.formValues.Configs.$error; if (error) { $scope.state.formValidationError = error; diff --git a/app/docker/views/services/create/includes/config.html b/app/docker/views/services/create/includes/config.html index 0fbd8dd30..2e10eb722 100644 --- a/app/docker/views/services/create/includes/config.html +++ b/app/docker/views/services/create/includes/config.html @@ -4,11 +4,17 @@ add a config + +