Commit f00898c7a06218bfa2095cd71d89e304646f4861
1 parent
cc302f18
device extensions opc, http validation
Showing
5 changed files
with
105 additions
and
61 deletions
... | ... | @@ -40,8 +40,6 @@ export default function ExtensionDialogController($scope, $mdDialog, $translate, |
40 | 40 | |
41 | 41 | |
42 | 42 | vm.extensionTypeChange = function () { |
43 | - // $scope.theForm.$setPristine(); | |
44 | - // $scope.theForm.$setUntouched(); | |
45 | 43 | |
46 | 44 | if (vm.extension.type === "HTTP") { |
47 | 45 | vm.extension.configuration = { |
... | ... | @@ -68,28 +66,49 @@ export default function ExtensionDialogController($scope, $mdDialog, $translate, |
68 | 66 | vm.save = save; |
69 | 67 | function save() { |
70 | 68 | saveTransformers(); |
71 | - if(vm.isAdd) { | |
72 | - vm.allExtensions.push(vm.extension); | |
69 | + | |
70 | + let $errorElement = angular.element('[name=theForm]').find('.ng-invalid'); | |
71 | + | |
72 | + if ($errorElement.length) { | |
73 | + | |
74 | + let $mdDialogScroll = angular.element('md-dialog-content').scrollTop(); | |
75 | + let $mdDialogTop = angular.element('md-dialog-content').offset().top; | |
76 | + let $errorElementTop = angular.element('[name=theForm]').find('.ng-invalid').eq(0).offset().top; | |
77 | + | |
78 | + | |
79 | + if ($errorElementTop !== $mdDialogTop) { | |
80 | + angular.element('md-dialog-content').animate({ | |
81 | + scrollTop: $mdDialogScroll + ($errorElementTop - $mdDialogTop) - 20 | |
82 | + }, 500); | |
83 | + $errorElement.eq(0).focus(); | |
84 | + } | |
85 | + | |
73 | 86 | } else { |
74 | - var index = vm.allExtensions.indexOf(extension); | |
75 | - if(index > -1) { | |
76 | - vm.allExtensions[index] = vm.extension; | |
87 | + | |
88 | + if(vm.isAdd) { | |
89 | + vm.allExtensions.push(vm.extension); | |
90 | + } else { | |
91 | + var index = vm.allExtensions.indexOf(extension); | |
92 | + if(index > -1) { | |
93 | + vm.allExtensions[index] = vm.extension; | |
94 | + } | |
77 | 95 | } |
78 | - } | |
79 | 96 | |
80 | - var editedValue = angular.toJson(vm.allExtensions); | |
97 | + var editedValue = angular.toJson(vm.allExtensions); | |
81 | 98 | |
82 | - attributeService | |
83 | - .saveEntityAttributes( | |
84 | - vm.entityType, | |
85 | - vm.entityId, | |
86 | - types.attributesScope.shared.value, | |
87 | - [{key:"configuration", value:editedValue}] | |
88 | - ) | |
89 | - .then(function success() { | |
99 | + attributeService | |
100 | + .saveEntityAttributes( | |
101 | + vm.entityType, | |
102 | + vm.entityId, | |
103 | + types.attributesScope.shared.value, | |
104 | + [{key:"configuration", value:editedValue}] | |
105 | + ) | |
106 | + .then(function success() { | |
90 | 107 | $scope.theForm.$setPristine(); |
91 | 108 | $mdDialog.hide(); |
92 | - }); | |
109 | + }); | |
110 | + | |
111 | + } | |
93 | 112 | } |
94 | 113 | |
95 | 114 | vm.validateId = function() { | ... | ... |
... | ... | @@ -16,7 +16,7 @@ |
16 | 16 | |
17 | 17 | --> |
18 | 18 | <md-dialog class="extensionDialog" aria-label="{{ (vm.isAdd ? 'extension.add' : 'extension.edit' ) | translate }}"> |
19 | - <form name="theForm" ng-submit="vm.save()"> | |
19 | + <form name="theForm" ng-submit="vm.save()" novalidate> | |
20 | 20 | <md-toolbar> |
21 | 21 | <div class="md-toolbar-tools"> |
22 | 22 | <h2 translate>{{ vm.isAdd ? 'extension.add' : 'extension.edit'}}</h2> |
... | ... | @@ -70,10 +70,9 @@ |
70 | 70 | </md-dialog-content> |
71 | 71 | |
72 | 72 | <md-dialog-actions layout="row"> |
73 | - <span flex></span> | |
74 | 73 | <md-button type="submit" |
75 | - ng-disabled="loading || theForm.$invalid || !theForm.$dirty" | |
76 | - class="md-raised md-primary"> | |
74 | + class="md-raised md-primary" | |
75 | + > | |
77 | 76 | {{ (vm.isAdd ? 'action.add' : 'action.save') | translate }} |
78 | 77 | </md-button> |
79 | 78 | ... | ... |
... | ... | @@ -53,36 +53,14 @@ export default function ExtensionFormHttpDirective($compile, $templateCache, $tr |
53 | 53 | } |
54 | 54 | }; |
55 | 55 | |
56 | - if(scope.isAdd) { | |
57 | - scope.converterConfigs = []; | |
58 | - scope.config.converterConfigurations = scope.converterConfigs; | |
59 | - } else { | |
60 | - scope.converterConfigs = scope.config.converterConfigurations; | |
61 | - } | |
62 | - | |
63 | - scope.updateValidity = function() { | |
64 | - var valid = scope.converterConfigs && scope.converterConfigs.length > 0; | |
65 | - scope.theForm.$setValidity('converterConfigs', valid); | |
66 | - if(scope.converterConfigs.length) { | |
67 | - for(let i=0;i<scope.converterConfigs.length;i++) { | |
68 | - if(!scope.converterConfigs[i].converters.length) { | |
69 | - scope.theForm.$setValidity('converters', false); | |
70 | - break; | |
71 | - } else { | |
72 | - scope.theForm.$setValidity('converters', true); | |
73 | - } | |
74 | - } | |
75 | - } | |
76 | - }; | |
77 | - | |
78 | - scope.$watch('converterConfigs', function() { | |
79 | - scope.updateValidity(); | |
80 | - }, true); | |
81 | 56 | |
82 | 57 | scope.addConverterConfig = function() { |
83 | 58 | var newConverterConfig = {converterId:"", converters:[]}; |
84 | 59 | scope.converterConfigs.push(newConverterConfig); |
85 | - } | |
60 | + | |
61 | + scope.converterConfigs[scope.converterConfigs.length - 1].converters = []; | |
62 | + scope.addConverter(scope.converterConfigs[scope.converterConfigs.length - 1].converters); | |
63 | + }; | |
86 | 64 | |
87 | 65 | scope.removeConverterConfig = function(config) { |
88 | 66 | var index = scope.converterConfigs.indexOf(config); |
... | ... | @@ -90,12 +68,17 @@ export default function ExtensionFormHttpDirective($compile, $templateCache, $tr |
90 | 68 | scope.converterConfigs.splice(index, 1); |
91 | 69 | } |
92 | 70 | scope.theForm.$setDirty(); |
93 | - } | |
71 | + }; | |
94 | 72 | |
95 | 73 | scope.addConverter = function(converters) { |
96 | - var newConverter = {deviceNameJsonExpression:"", deviceTypeJsonExpression:"", attributes:[], timeseries:[]}; | |
74 | + var newConverter = { | |
75 | + deviceNameJsonExpression:"", | |
76 | + deviceTypeJsonExpression:"", | |
77 | + attributes:[], | |
78 | + timeseries:[] | |
79 | + }; | |
97 | 80 | converters.push(newConverter); |
98 | - } | |
81 | + }; | |
99 | 82 | |
100 | 83 | scope.removeConverter = function(converter, converters) { |
101 | 84 | var index = converters.indexOf(converter); |
... | ... | @@ -103,12 +86,12 @@ export default function ExtensionFormHttpDirective($compile, $templateCache, $tr |
103 | 86 | converters.splice(index, 1); |
104 | 87 | } |
105 | 88 | scope.theForm.$setDirty(); |
106 | - } | |
89 | + }; | |
107 | 90 | |
108 | 91 | scope.addAttribute = function(attributes) { |
109 | 92 | var newAttribute = {type:"", key:"", value:""}; |
110 | 93 | attributes.push(newAttribute); |
111 | - } | |
94 | + }; | |
112 | 95 | |
113 | 96 | scope.removeAttribute = function(attribute, attributes) { |
114 | 97 | var index = attributes.indexOf(attribute); |
... | ... | @@ -116,11 +99,44 @@ export default function ExtensionFormHttpDirective($compile, $templateCache, $tr |
116 | 99 | attributes.splice(index, 1); |
117 | 100 | } |
118 | 101 | scope.theForm.$setDirty(); |
102 | + }; | |
103 | + | |
104 | + | |
105 | + | |
106 | + | |
107 | + | |
108 | + if(scope.isAdd) { | |
109 | + scope.converterConfigs = scope.config.converterConfigurations; | |
110 | + scope.addConverterConfig(); | |
111 | + } else { | |
112 | + scope.converterConfigs = scope.config.converterConfigurations; | |
119 | 113 | } |
120 | 114 | |
115 | + | |
116 | + | |
117 | + scope.updateValidity = function() { | |
118 | + let valid = scope.converterConfigs && scope.converterConfigs.length > 0; | |
119 | + scope.theForm.$setValidity('converterConfigs', valid); | |
120 | + if(scope.converterConfigs.length) { | |
121 | + for(let i=0; i<scope.converterConfigs.length; i++) { | |
122 | + if(!scope.converterConfigs[i].converters.length) { | |
123 | + scope.theForm.$setValidity('converters', false); | |
124 | + break; | |
125 | + } else { | |
126 | + scope.theForm.$setValidity('converters', true); | |
127 | + } | |
128 | + } | |
129 | + } | |
130 | + }; | |
131 | + | |
132 | + scope.$watch('converterConfigs', function() { | |
133 | + scope.updateValidity(); | |
134 | + }, true); | |
135 | + | |
136 | + | |
121 | 137 | scope.transformerTypeChange = function(attribute) { |
122 | 138 | attribute.transformer = ""; |
123 | - } | |
139 | + }; | |
124 | 140 | |
125 | 141 | scope.validateTransformer = function (model, editorName) { |
126 | 142 | if(model && model.length) { |
... | ... | @@ -131,10 +147,10 @@ export default function ExtensionFormHttpDirective($compile, $templateCache, $tr |
131 | 147 | scope.theForm[editorName].$setValidity('transformerJSON', false); |
132 | 148 | } |
133 | 149 | } |
134 | - } | |
150 | + }; | |
135 | 151 | |
136 | 152 | $compile(element.contents())(scope); |
137 | - } | |
153 | + }; | |
138 | 154 | |
139 | 155 | return { |
140 | 156 | restrict: "A", | ... | ... |
... | ... | @@ -33,8 +33,12 @@ |
33 | 33 | </div> |
34 | 34 | <div ng-if="converterConfigs.length > 0"> |
35 | 35 | <ol class="list-group"> |
36 | - <li class="list-group-item" ng-repeat="(configIndex,config) in converterConfigs"> | |
37 | - <md-button aria-label="{{ 'action.remove' | translate }}" class="md-icon-button" ng-click="removeConverterConfig(config)"> | |
36 | + <li class="list-group-item" ng-repeat="(configIndex, config) in converterConfigs"> | |
37 | + <md-button aria-label="{{ 'action.remove' | translate }}" | |
38 | + class="md-icon-button" | |
39 | + ng-click="removeConverterConfig(config)" | |
40 | + ng-hide="converterConfigs.length < 2" | |
41 | + > | |
38 | 42 | <ng-md-icon icon="close" aria-label="{{ 'action.remove' | translate }}"></ng-md-icon> |
39 | 43 | <md-tooltip md-direction="top"> |
40 | 44 | {{ 'action.remove' | translate }} |
... | ... | @@ -65,8 +69,14 @@ |
65 | 69 | </div> |
66 | 70 | <div ng-if="config.converters.length > 0"> |
67 | 71 | <ol class="list-group"> |
68 | - <li class="list-group-item" ng-repeat="(converterIndex,converter) in config.converters"> | |
69 | - <md-button aria-label="{{ 'action.remove' | translate }}" class="md-icon-button" ng-click="removeConverter(converter, config.converters)"> | |
72 | + <li class="list-group-item" | |
73 | + ng-repeat="(converterIndex,converter) in config.converters" | |
74 | + > | |
75 | + <md-button aria-label="{{ 'action.remove' | translate }}" | |
76 | + class="md-icon-button" | |
77 | + ng-click="removeConverter(converter, config.converters)" | |
78 | + ng-hide="config.converters.length < 2" | |
79 | + > | |
70 | 80 | <ng-md-icon icon="close" aria-label="{{ 'action.remove' | translate }}"></ng-md-icon> |
71 | 81 | <md-tooltip md-direction="top"> |
72 | 82 | {{ 'action.remove' | translate }} | ... | ... |
... | ... | @@ -216,7 +216,7 @@ |
216 | 216 | </div> |
217 | 217 | </md-input-container> |
218 | 218 | |
219 | - <div class="tb-container"> | |
219 | + <div class="tb-container" ng-class="{'ng-invalid':!server.keystore.file}"> | |
220 | 220 | <span ng-init='fieldsToFill = {"fileName":"fileName", "file":"file"}'></span> |
221 | 221 | <label class="tb-label" translate>extension.opc-keystore-location</label> |
222 | 222 | <div flow-init="{singleFile:true}" flow-file-added='fileAdded($file, server.keystore, fieldsToFill)' class="tb-file-select-container"> | ... | ... |