Details
diff --git a/ui/src/app/extension/extension-dialog.controller.js b/ui/src/app/extension/extension-dialog.controller.js
index cc8d7c3..cfec9cf 100644
--- a/ui/src/app/extension/extension-dialog.controller.js
+++ b/ui/src/app/extension/extension-dialog.controller.js
@@ -40,8 +40,6 @@ export default function ExtensionDialogController($scope, $mdDialog, $translate,
vm.extensionTypeChange = function () {
- // $scope.theForm.$setPristine();
- // $scope.theForm.$setUntouched();
if (vm.extension.type === "HTTP") {
vm.extension.configuration = {
@@ -68,28 +66,49 @@ export default function ExtensionDialogController($scope, $mdDialog, $translate,
vm.save = save;
function save() {
saveTransformers();
- if(vm.isAdd) {
- vm.allExtensions.push(vm.extension);
+
+ let $errorElement = angular.element('[name=theForm]').find('.ng-invalid');
+
+ if ($errorElement.length) {
+
+ let $mdDialogScroll = angular.element('md-dialog-content').scrollTop();
+ let $mdDialogTop = angular.element('md-dialog-content').offset().top;
+ let $errorElementTop = angular.element('[name=theForm]').find('.ng-invalid').eq(0).offset().top;
+
+
+ if ($errorElementTop !== $mdDialogTop) {
+ angular.element('md-dialog-content').animate({
+ scrollTop: $mdDialogScroll + ($errorElementTop - $mdDialogTop) - 20
+ }, 500);
+ $errorElement.eq(0).focus();
+ }
+
} else {
- var index = vm.allExtensions.indexOf(extension);
- if(index > -1) {
- vm.allExtensions[index] = vm.extension;
+
+ if(vm.isAdd) {
+ vm.allExtensions.push(vm.extension);
+ } else {
+ var index = vm.allExtensions.indexOf(extension);
+ if(index > -1) {
+ vm.allExtensions[index] = vm.extension;
+ }
}
- }
- var editedValue = angular.toJson(vm.allExtensions);
+ var editedValue = angular.toJson(vm.allExtensions);
- attributeService
- .saveEntityAttributes(
- vm.entityType,
- vm.entityId,
- types.attributesScope.shared.value,
- [{key:"configuration", value:editedValue}]
- )
- .then(function success() {
+ attributeService
+ .saveEntityAttributes(
+ vm.entityType,
+ vm.entityId,
+ types.attributesScope.shared.value,
+ [{key:"configuration", value:editedValue}]
+ )
+ .then(function success() {
$scope.theForm.$setPristine();
$mdDialog.hide();
- });
+ });
+
+ }
}
vm.validateId = function() {
diff --git a/ui/src/app/extension/extension-dialog.tpl.html b/ui/src/app/extension/extension-dialog.tpl.html
index b4fac57..2336a60 100644
--- a/ui/src/app/extension/extension-dialog.tpl.html
+++ b/ui/src/app/extension/extension-dialog.tpl.html
@@ -16,7 +16,7 @@
-->
<md-dialog class="extensionDialog" aria-label="{{ (vm.isAdd ? 'extension.add' : 'extension.edit' ) | translate }}">
- <form name="theForm" ng-submit="vm.save()">
+ <form name="theForm" ng-submit="vm.save()" novalidate>
<md-toolbar>
<div class="md-toolbar-tools">
<h2 translate>{{ vm.isAdd ? 'extension.add' : 'extension.edit'}}</h2>
@@ -70,10 +70,9 @@
</md-dialog-content>
<md-dialog-actions layout="row">
- <span flex></span>
<md-button type="submit"
- ng-disabled="loading || theForm.$invalid || !theForm.$dirty"
- class="md-raised md-primary">
+ class="md-raised md-primary"
+ >
{{ (vm.isAdd ? 'action.add' : 'action.save') | translate }}
</md-button>
diff --git a/ui/src/app/extension/extensions-forms/extension-form-http.directive.js b/ui/src/app/extension/extensions-forms/extension-form-http.directive.js
index 9a07f2b..4c09078 100644
--- a/ui/src/app/extension/extensions-forms/extension-form-http.directive.js
+++ b/ui/src/app/extension/extensions-forms/extension-form-http.directive.js
@@ -53,36 +53,14 @@ export default function ExtensionFormHttpDirective($compile, $templateCache, $tr
}
};
- if(scope.isAdd) {
- scope.converterConfigs = [];
- scope.config.converterConfigurations = scope.converterConfigs;
- } else {
- scope.converterConfigs = scope.config.converterConfigurations;
- }
-
- scope.updateValidity = function() {
- var valid = scope.converterConfigs && scope.converterConfigs.length > 0;
- scope.theForm.$setValidity('converterConfigs', valid);
- if(scope.converterConfigs.length) {
- for(let i=0;i<scope.converterConfigs.length;i++) {
- if(!scope.converterConfigs[i].converters.length) {
- scope.theForm.$setValidity('converters', false);
- break;
- } else {
- scope.theForm.$setValidity('converters', true);
- }
- }
- }
- };
-
- scope.$watch('converterConfigs', function() {
- scope.updateValidity();
- }, true);
scope.addConverterConfig = function() {
var newConverterConfig = {converterId:"", converters:[]};
scope.converterConfigs.push(newConverterConfig);
- }
+
+ scope.converterConfigs[scope.converterConfigs.length - 1].converters = [];
+ scope.addConverter(scope.converterConfigs[scope.converterConfigs.length - 1].converters);
+ };
scope.removeConverterConfig = function(config) {
var index = scope.converterConfigs.indexOf(config);
@@ -90,12 +68,17 @@ export default function ExtensionFormHttpDirective($compile, $templateCache, $tr
scope.converterConfigs.splice(index, 1);
}
scope.theForm.$setDirty();
- }
+ };
scope.addConverter = function(converters) {
- var newConverter = {deviceNameJsonExpression:"", deviceTypeJsonExpression:"", attributes:[], timeseries:[]};
+ var newConverter = {
+ deviceNameJsonExpression:"",
+ deviceTypeJsonExpression:"",
+ attributes:[],
+ timeseries:[]
+ };
converters.push(newConverter);
- }
+ };
scope.removeConverter = function(converter, converters) {
var index = converters.indexOf(converter);
@@ -103,12 +86,12 @@ export default function ExtensionFormHttpDirective($compile, $templateCache, $tr
converters.splice(index, 1);
}
scope.theForm.$setDirty();
- }
+ };
scope.addAttribute = function(attributes) {
var newAttribute = {type:"", key:"", value:""};
attributes.push(newAttribute);
- }
+ };
scope.removeAttribute = function(attribute, attributes) {
var index = attributes.indexOf(attribute);
@@ -116,11 +99,44 @@ export default function ExtensionFormHttpDirective($compile, $templateCache, $tr
attributes.splice(index, 1);
}
scope.theForm.$setDirty();
+ };
+
+
+
+
+
+ if(scope.isAdd) {
+ scope.converterConfigs = scope.config.converterConfigurations;
+ scope.addConverterConfig();
+ } else {
+ scope.converterConfigs = scope.config.converterConfigurations;
}
+
+
+ scope.updateValidity = function() {
+ let valid = scope.converterConfigs && scope.converterConfigs.length > 0;
+ scope.theForm.$setValidity('converterConfigs', valid);
+ if(scope.converterConfigs.length) {
+ for(let i=0; i<scope.converterConfigs.length; i++) {
+ if(!scope.converterConfigs[i].converters.length) {
+ scope.theForm.$setValidity('converters', false);
+ break;
+ } else {
+ scope.theForm.$setValidity('converters', true);
+ }
+ }
+ }
+ };
+
+ scope.$watch('converterConfigs', function() {
+ scope.updateValidity();
+ }, true);
+
+
scope.transformerTypeChange = function(attribute) {
attribute.transformer = "";
- }
+ };
scope.validateTransformer = function (model, editorName) {
if(model && model.length) {
@@ -131,10 +147,10 @@ export default function ExtensionFormHttpDirective($compile, $templateCache, $tr
scope.theForm[editorName].$setValidity('transformerJSON', false);
}
}
- }
+ };
$compile(element.contents())(scope);
- }
+ };
return {
restrict: "A",
diff --git a/ui/src/app/extension/extensions-forms/extension-form-http.tpl.html b/ui/src/app/extension/extensions-forms/extension-form-http.tpl.html
index eb3bb3e..6416656 100644
--- a/ui/src/app/extension/extensions-forms/extension-form-http.tpl.html
+++ b/ui/src/app/extension/extensions-forms/extension-form-http.tpl.html
@@ -33,8 +33,12 @@
</div>
<div ng-if="converterConfigs.length > 0">
<ol class="list-group">
- <li class="list-group-item" ng-repeat="(configIndex,config) in converterConfigs">
- <md-button aria-label="{{ 'action.remove' | translate }}" class="md-icon-button" ng-click="removeConverterConfig(config)">
+ <li class="list-group-item" ng-repeat="(configIndex, config) in converterConfigs">
+ <md-button aria-label="{{ 'action.remove' | translate }}"
+ class="md-icon-button"
+ ng-click="removeConverterConfig(config)"
+ ng-hide="converterConfigs.length < 2"
+ >
<ng-md-icon icon="close" aria-label="{{ 'action.remove' | translate }}"></ng-md-icon>
<md-tooltip md-direction="top">
{{ 'action.remove' | translate }}
@@ -65,8 +69,14 @@
</div>
<div ng-if="config.converters.length > 0">
<ol class="list-group">
- <li class="list-group-item" ng-repeat="(converterIndex,converter) in config.converters">
- <md-button aria-label="{{ 'action.remove' | translate }}" class="md-icon-button" ng-click="removeConverter(converter, config.converters)">
+ <li class="list-group-item"
+ ng-repeat="(converterIndex,converter) in config.converters"
+ >
+ <md-button aria-label="{{ 'action.remove' | translate }}"
+ class="md-icon-button"
+ ng-click="removeConverter(converter, config.converters)"
+ ng-hide="config.converters.length < 2"
+ >
<ng-md-icon icon="close" aria-label="{{ 'action.remove' | translate }}"></ng-md-icon>
<md-tooltip md-direction="top">
{{ 'action.remove' | translate }}
diff --git a/ui/src/app/extension/extensions-forms/extension-form-opc.tpl.html b/ui/src/app/extension/extensions-forms/extension-form-opc.tpl.html
index e19984e..8c959db 100644
--- a/ui/src/app/extension/extensions-forms/extension-form-opc.tpl.html
+++ b/ui/src/app/extension/extensions-forms/extension-form-opc.tpl.html
@@ -216,7 +216,7 @@
</div>
</md-input-container>
- <div class="tb-container">
+ <div class="tb-container" ng-class="{'ng-invalid':!server.keystore.file}">
<span ng-init='fieldsToFill = {"fileName":"fileName", "file":"file"}'></span>
<label class="tb-label" translate>extension.opc-keystore-location</label>
<div flow-init="{singleFile:true}" flow-file-added='fileAdded($file, server.keystore, fieldsToFill)' class="tb-file-select-container">