Commit e253b6443c5aa3d08f4b8e3b4dccbbd062766cf2
Committed by
Andrew Shvayka
1 parent
9c5dd434
Update widget for backward compatibility
Showing
3 changed files
with
192 additions
and
120 deletions
@@ -319,7 +319,7 @@ | @@ -319,7 +319,7 @@ | ||
319 | "resources": [], | 319 | "resources": [], |
320 | "templateHtml": "<tb-multiple-input-widget \n form-id=\"formId\"\n ctx=\"ctx\">\n</tb-multiple-input-widget>", | 320 | "templateHtml": "<tb-multiple-input-widget \n form-id=\"formId\"\n ctx=\"ctx\">\n</tb-multiple-input-widget>", |
321 | "templateCss": "", | 321 | "templateCss": "", |
322 | - "controllerScript": "let $scope;\r\nlet settings;\r\nlet attributeService;\r\nlet toast;\r\nlet utils;\r\nlet types;\r\n\r\nself.onInit = function() {\r\n var scope = self.ctx.$scope;\r\n var id = self.ctx.$scope.$injector.get('utils').guid();\r\n scope.formId = \"form-\"+id;\r\n scope.ctx = self.ctx;\r\n}\r\n\r\nself.onDataUpdated = function() {\r\n self.ctx.$scope.$broadcast('multiple-input-data-updated', self.ctx.$scope.formId);\r\n}\r\n\r\nself.typeParameters = function() {\r\n return {\r\n maxDatasources: 1\r\n }\r\n}\r\n\r\nself.onResize = function() {\r\n self.ctx.$scope.$broadcast('multiple-input-resize', self.ctx.$scope.formId);\r\n}\r\n", | 322 | + "controllerScript": "let $scope;\r\nlet settings;\r\nlet attributeService;\r\nlet toast;\r\nlet utils;\r\nlet types;\r\n\r\nself.onInit = function() {\r\n var scope = self.ctx.$scope;\r\n var id = self.ctx.$scope.$injector.get('utils').guid();\r\n scope.formId = \"form-\"+id;\r\n scope.ctx = self.ctx;\r\n}\r\n\r\nself.onDataUpdated = function() {\r\n self.ctx.$scope.$broadcast('multiple-input-data-updated', self.ctx.$scope.formId);\r\n}\r\n\r\nself.onResize = function() {\r\n self.ctx.$scope.$broadcast('multiple-input-resize', self.ctx.$scope.formId);\r\n}\r\n", |
323 | "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"MultipleInput\",\n \"properties\": {\n \"widgetTitle\": {\n \"title\": \"Widget title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"showActionButtons\":{\n \"title\":\"Show action buttons\",\n \"type\":\"boolean\",\n \"default\": true\n },\n \"showResultMessage\":{\n \"title\":\"Show result message\",\n \"type\":\"boolean\",\n \"default\": true\n },\n \"fieldsAlignment\": {\n \"title\": \"Fields alignment\",\n \"type\": \"string\",\n \"default\": \"row\"\n },\n \"fieldsInRow\": {\n \"title\": \"Number of fields in the row\",\n \"type\": \"number\",\n \"default\": \"2\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"widgetTitle\",\n \"showActionButtons\",\n \"showResultMessage\",\n {\n \"key\": \"fieldsAlignment\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"row\",\n \"label\": \"Row (default)\"\n },\n {\n \"value\": \"column\",\n \"label\": \"Column\"\n }\n ]\n },\n \"fieldsInRow\"\n ]\n}", | 323 | "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"MultipleInput\",\n \"properties\": {\n \"widgetTitle\": {\n \"title\": \"Widget title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"showActionButtons\":{\n \"title\":\"Show action buttons\",\n \"type\":\"boolean\",\n \"default\": true\n },\n \"showResultMessage\":{\n \"title\":\"Show result message\",\n \"type\":\"boolean\",\n \"default\": true\n },\n \"fieldsAlignment\": {\n \"title\": \"Fields alignment\",\n \"type\": \"string\",\n \"default\": \"row\"\n },\n \"fieldsInRow\": {\n \"title\": \"Number of fields in the row\",\n \"type\": \"number\",\n \"default\": \"2\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"widgetTitle\",\n \"showActionButtons\",\n \"showResultMessage\",\n {\n \"key\": \"fieldsAlignment\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"row\",\n \"label\": \"Row (default)\"\n },\n {\n \"value\": \"column\",\n \"label\": \"Column\"\n }\n ]\n },\n \"fieldsInRow\"\n ]\n}", |
324 | "dataKeySettingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"DataKeySettings\",\n \"properties\": {\n \"dataKeyType\": {\n \"title\": \"Datakey type\",\n \"type\": \"string\",\n \"default\": \"server\"\n },\n \"dataKeyValueType\": {\n \"title\": \"Datakey value type\",\n \"type\": \"string\",\n \"default\": \"string\"\n },\n \"required\": {\n \"title\": \"Value is required\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"isEditable\": {\n \"title\": \"Ability to edit attribute\",\n \"type\": \"string\",\n \"default\": \"editable\"\n },\n \"disabledOnDataKey\": {\n \"title\": \"Disable on false value of another datakey (specify datakey name)\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"dataKeyHidden\": {\n \"title\": \"Hide input field\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"step\": {\n \"title\": \"Step interval between values (only for numbers)\",\n \"type\": \"number\",\n \"default\": \"1\"\n },\n \"requiredErrorMessage\": {\n \"title\": \"'Required' error message\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"icon\": {\n \"title\": \"Icon to show before input cell\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": []\n },\n \"form\": [\n {\n \"key\": \"dataKeyType\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"server\",\n \"label\": \"Server attribute (default)\"\n },\n {\n \"value\": \"shared\",\n \"label\": \"Shared attribute\"\n },\n {\n \"value\": \"timeseries\",\n \"label\": \"Timeseries\"\n }\n ]\n },\n {\n \"key\": \"dataKeyValueType\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"string\",\n \"label\": \"String\"\n },\n {\n \"value\": \"double\",\n \"label\": \"Double\"\n },\n {\n \"value\": \"integer\",\n \"label\": \"Integer\"\n },\n {\n \"value\": \"booleanCheckbox\",\n \"label\": \"Boolean (Checkbox)\"\n },\n {\n \"value\": \"booleanSwitch\",\n \"label\": \"Boolean (Switch)\"\n },\n {\n \"value\": \"dateTime\",\n \"label\": \"Date & Time\"\n },\n {\n \"value\": \"date\",\n \"label\": \"Date\"\n },\n {\n \"value\": \"time\",\n \"label\": \"Time\"\n }\n ]\n },\n \"required\",\n {\n \"key\": \"isEditable\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"editable\",\n \"label\": \"Editable (default)\"\n },\n {\n \"value\": \"disabled\",\n \"label\": \"Disabled\"\n },\n {\n \"value\": \"readonly\",\n \"label\": \"Read-only\"\n }\n ]\n },\n \"disabledOnDataKey\",\n \"dataKeyHidden\",\n \"step\",\n \"requiredErrorMessage\",\n\t\t{\n \t\t\"key\": \"icon\",\n\t\t\t\"type\": \"icon\"\n\t\t}\n ]\n}\n", | 324 | "dataKeySettingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"DataKeySettings\",\n \"properties\": {\n \"dataKeyType\": {\n \"title\": \"Datakey type\",\n \"type\": \"string\",\n \"default\": \"server\"\n },\n \"dataKeyValueType\": {\n \"title\": \"Datakey value type\",\n \"type\": \"string\",\n \"default\": \"string\"\n },\n \"required\": {\n \"title\": \"Value is required\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"isEditable\": {\n \"title\": \"Ability to edit attribute\",\n \"type\": \"string\",\n \"default\": \"editable\"\n },\n \"disabledOnDataKey\": {\n \"title\": \"Disable on false value of another datakey (specify datakey name)\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"dataKeyHidden\": {\n \"title\": \"Hide input field\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"step\": {\n \"title\": \"Step interval between values (only for numbers)\",\n \"type\": \"number\",\n \"default\": \"1\"\n },\n \"requiredErrorMessage\": {\n \"title\": \"'Required' error message\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"icon\": {\n \"title\": \"Icon to show before input cell\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": []\n },\n \"form\": [\n {\n \"key\": \"dataKeyType\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"server\",\n \"label\": \"Server attribute (default)\"\n },\n {\n \"value\": \"shared\",\n \"label\": \"Shared attribute\"\n },\n {\n \"value\": \"timeseries\",\n \"label\": \"Timeseries\"\n }\n ]\n },\n {\n \"key\": \"dataKeyValueType\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"string\",\n \"label\": \"String\"\n },\n {\n \"value\": \"double\",\n \"label\": \"Double\"\n },\n {\n \"value\": \"integer\",\n \"label\": \"Integer\"\n },\n {\n \"value\": \"booleanCheckbox\",\n \"label\": \"Boolean (Checkbox)\"\n },\n {\n \"value\": \"booleanSwitch\",\n \"label\": \"Boolean (Switch)\"\n },\n {\n \"value\": \"dateTime\",\n \"label\": \"Date & Time\"\n },\n {\n \"value\": \"date\",\n \"label\": \"Date\"\n },\n {\n \"value\": \"time\",\n \"label\": \"Time\"\n }\n ]\n },\n \"required\",\n {\n \"key\": \"isEditable\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"editable\",\n \"label\": \"Editable (default)\"\n },\n {\n \"value\": \"disabled\",\n \"label\": \"Disabled\"\n },\n {\n \"value\": \"readonly\",\n \"label\": \"Read-only\"\n }\n ]\n },\n \"disabledOnDataKey\",\n \"dataKeyHidden\",\n \"step\",\n \"requiredErrorMessage\",\n\t\t{\n \t\t\"key\": \"icon\",\n\t\t\t\"type\": \"icon\"\n\t\t}\n ]\n}\n", |
325 | "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Sin\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.23592248334107624,\"funcBody\":\"return Math.round(1000*Math.sin(time/5000));\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{},\"title\":\"Update Multiple Attributes\",\"dropShadow\":true,\"enableFullscreen\":false,\"enableDataExport\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{}}" | 325 | "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Sin\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.23592248334107624,\"funcBody\":\"return Math.round(1000*Math.sin(time/5000));\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{},\"title\":\"Update Multiple Attributes\",\"dropShadow\":true,\"enableFullscreen\":false,\"enableDataExport\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{}}" |
@@ -47,14 +47,14 @@ function MultipleInputWidgetController($q, $scope, $translate, attributeService, | @@ -47,14 +47,14 @@ function MultipleInputWidgetController($q, $scope, $translate, attributeService, | ||
47 | vm.entityDetected = false; | 47 | vm.entityDetected = false; |
48 | vm.isAllParametersValid = true; | 48 | vm.isAllParametersValid = true; |
49 | 49 | ||
50 | - vm.data = []; | 50 | + vm.sources = []; |
51 | vm.datasources = null; | 51 | vm.datasources = null; |
52 | 52 | ||
53 | vm.discardAll = discardAll; | 53 | vm.discardAll = discardAll; |
54 | vm.inputChanged = inputChanged; | 54 | vm.inputChanged = inputChanged; |
55 | vm.save = save; | 55 | vm.save = save; |
56 | 56 | ||
57 | - $scope.$watch('vm.ctx', function() { | 57 | + $scope.$watch('vm.ctx', function () { |
58 | if (vm.ctx && vm.ctx.defaultSubscription) { | 58 | if (vm.ctx && vm.ctx.defaultSubscription) { |
59 | vm.settings = vm.ctx.settings; | 59 | vm.settings = vm.ctx.settings; |
60 | vm.widgetConfig = vm.ctx.widgetConfig; | 60 | vm.widgetConfig = vm.ctx.widgetConfig; |
@@ -65,100 +65,113 @@ function MultipleInputWidgetController($q, $scope, $translate, attributeService, | @@ -65,100 +65,113 @@ function MultipleInputWidgetController($q, $scope, $translate, attributeService, | ||
65 | } | 65 | } |
66 | }); | 66 | }); |
67 | 67 | ||
68 | - $scope.$on('multiple-input-data-updated', function(event, formId) { | 68 | + $scope.$on('multiple-input-data-updated', function (event, formId) { |
69 | if (vm.formId == formId) { | 69 | if (vm.formId == formId) { |
70 | updateWidgetData(vm.subscription.data); | 70 | updateWidgetData(vm.subscription.data); |
71 | $scope.$digest(); | 71 | $scope.$digest(); |
72 | } | 72 | } |
73 | }); | 73 | }); |
74 | 74 | ||
75 | - $scope.$on('multiple-input-resize', function(event, formId) { | 75 | + $scope.$on('multiple-input-resize', function (event, formId) { |
76 | if (vm.formId == formId) { | 76 | if (vm.formId == formId) { |
77 | updateWidgetDisplaying(); | 77 | updateWidgetDisplaying(); |
78 | } | 78 | } |
79 | }); | 79 | }); |
80 | 80 | ||
81 | function discardAll() { | 81 | function discardAll() { |
82 | - for (var i = 0; i < vm.data.length; i++) { | ||
83 | - vm.data[i].data.currentValue = vm.data[i].data.originalValue; | 82 | + for (var i = 0; i < vm.sources.length; i++) { |
83 | + for (var j = 0; j < vm.sources[i].keys.length; j++) { | ||
84 | + vm.sources[i].keys[j].data.currentValue = vm.sources[i].keys[j].data.originalValue; | ||
85 | + } | ||
84 | } | 86 | } |
85 | $scope.multipleInputForm.$setPristine(); | 87 | $scope.multipleInputForm.$setPristine(); |
86 | } | 88 | } |
87 | 89 | ||
88 | - function inputChanged(key) { | 90 | + function inputChanged(source, key) { |
89 | if (!vm.settings.showActionButtons) { | 91 | if (!vm.settings.showActionButtons) { |
90 | if (!key.settings.required || (key.settings.required && key.data && angular.isDefined(key.data.currentValue))) { | 92 | if (!key.settings.required || (key.settings.required && key.data && angular.isDefined(key.data.currentValue))) { |
91 | - vm.save(key); | 93 | + var dataToSave = { |
94 | + datasource: source.datasource, | ||
95 | + keys: [key] | ||
96 | + }; | ||
97 | + vm.save(dataToSave); | ||
92 | } | 98 | } |
93 | } | 99 | } |
94 | } | 100 | } |
95 | 101 | ||
96 | - function save(key) { | 102 | + function save(dataToSave) { |
97 | var tasks = []; | 103 | var tasks = []; |
98 | - var serverAttributes = [], sharedAttributes = [], telemetry = []; | ||
99 | var config = { | 104 | var config = { |
100 | ignoreLoading: !vm.settings.showActionButtons | 105 | ignoreLoading: !vm.settings.showActionButtons |
101 | }; | 106 | }; |
102 | var data; | 107 | var data; |
103 | - if (key) { | ||
104 | - data = [key]; | 108 | + if (dataToSave) { |
109 | + data = [dataToSave]; | ||
105 | } else { | 110 | } else { |
106 | - data = vm.data; | 111 | + data = vm.sources; |
107 | } | 112 | } |
108 | for (let i = 0; i < data.length; i++) { | 113 | for (let i = 0; i < data.length; i++) { |
109 | - var item = data[i]; | ||
110 | - if (item.data.currentValue !== item.data.originalValue) { | ||
111 | - var attribute = { | ||
112 | - key: item.name | ||
113 | - }; | ||
114 | - switch (item.settings.dataKeyValueType) { | ||
115 | - case 'dateTime': | ||
116 | - case 'date': | ||
117 | - attribute.value = item.data.currentValue.getTime(); | ||
118 | - break; | ||
119 | - case 'time': | ||
120 | - attribute.value = item.data.currentValue.getTime() - moment().startOf('day').valueOf();//eslint-disable-line | ||
121 | - break; | ||
122 | - default: | ||
123 | - attribute.value = item.data.currentValue; | ||
124 | - } | 114 | + var serverAttributes = [], sharedAttributes = [], telemetry = []; |
115 | + for (let j = 0; j < data[i].keys.length; j++) { | ||
116 | + var key = data[i].keys[j]; | ||
117 | + if (key.data.currentValue !== key.data.originalValue) { | ||
118 | + var attribute = { | ||
119 | + key: key.name | ||
120 | + }; | ||
121 | + if (key.data.currentValue) { | ||
122 | + switch (key.settings.dataKeyValueType) { | ||
123 | + case 'dateTime': | ||
124 | + case 'date': | ||
125 | + attribute.value = key.data.currentValue.getTime(); | ||
126 | + break; | ||
127 | + case 'time': | ||
128 | + attribute.value = key.data.currentValue.getTime() - moment().startOf('day').valueOf();//eslint-disable-line | ||
129 | + break; | ||
130 | + default: | ||
131 | + attribute.value = key.data.currentValue; | ||
132 | + } | ||
133 | + } else { | ||
134 | + attribute.value = key.data.currentValue; | ||
135 | + } | ||
125 | 136 | ||
126 | - switch (item.settings.dataKeyType) { | ||
127 | - case 'shared': | ||
128 | - sharedAttributes.push(attribute); | ||
129 | - break; | ||
130 | - case 'timeseries': | ||
131 | - telemetry.push(attribute); | ||
132 | - break; | ||
133 | - default: | ||
134 | - serverAttributes.push(attribute); | 137 | + switch (key.settings.dataKeyType) { |
138 | + case 'shared': | ||
139 | + sharedAttributes.push(attribute); | ||
140 | + break; | ||
141 | + case 'timeseries': | ||
142 | + telemetry.push(attribute); | ||
143 | + break; | ||
144 | + default: | ||
145 | + serverAttributes.push(attribute); | ||
146 | + } | ||
135 | } | 147 | } |
136 | } | 148 | } |
149 | + if (serverAttributes.length) { | ||
150 | + tasks.push(attributeService.saveEntityAttributes( | ||
151 | + data[i].datasource.entityType, | ||
152 | + data[i].datasource.entityId, | ||
153 | + types.attributesScope.server.value, | ||
154 | + serverAttributes, | ||
155 | + config)); | ||
156 | + } | ||
157 | + if (sharedAttributes.length) { | ||
158 | + tasks.push(attributeService.saveEntityAttributes( | ||
159 | + data[i].datasource.entityType, | ||
160 | + data[i].datasource.entityId, | ||
161 | + types.attributesScope.shared.value, | ||
162 | + sharedAttributes, | ||
163 | + config)); | ||
164 | + } | ||
165 | + if (telemetry.length) { | ||
166 | + tasks.push(attributeService.saveEntityTimeseries( | ||
167 | + data[i].datasource.entityType, | ||
168 | + data[i].datasource.entityId, | ||
169 | + types.latestTelemetry.value, | ||
170 | + telemetry, | ||
171 | + config)); | ||
172 | + } | ||
137 | } | 173 | } |
138 | - for (let i = 0; i < serverAttributes.length; i++) { | ||
139 | - tasks.push(attributeService.saveEntityAttributes( | ||
140 | - vm.datasources[0].entityType, | ||
141 | - vm.datasources[0].entityId, | ||
142 | - types.attributesScope.server.value, | ||
143 | - serverAttributes, | ||
144 | - config)); | ||
145 | - } | ||
146 | - for (let i = 0; i < sharedAttributes.length; i++) { | ||
147 | - tasks.push(attributeService.saveEntityAttributes( | ||
148 | - vm.datasources[0].entityType, | ||
149 | - vm.datasources[0].entityId, | ||
150 | - types.attributesScope.shared.value, | ||
151 | - sharedAttributes, | ||
152 | - config)); | ||
153 | - } | ||
154 | - for (let i = 0; i < telemetry.length; i++) { | ||
155 | - tasks.push(attributeService.saveEntityTimeseries( | ||
156 | - vm.datasources[0].entityType, | ||
157 | - vm.datasources[0].entityId, | ||
158 | - types.latestTelemetry.value, | ||
159 | - telemetry, | ||
160 | - config)); | ||
161 | - } | 174 | + |
162 | if (tasks.length) { | 175 | if (tasks.length) { |
163 | $q.all(tasks).then( | 176 | $q.all(tasks).then( |
164 | function success() { | 177 | function success() { |
@@ -173,6 +186,8 @@ function MultipleInputWidgetController($q, $scope, $translate, attributeService, | @@ -173,6 +186,8 @@ function MultipleInputWidgetController($q, $scope, $translate, attributeService, | ||
173 | } | 186 | } |
174 | } | 187 | } |
175 | ); | 188 | ); |
189 | + } else { | ||
190 | + $scope.multipleInputForm.$setPristine(); | ||
176 | } | 191 | } |
177 | } | 192 | } |
178 | 193 | ||
@@ -186,6 +201,18 @@ function MultipleInputWidgetController($q, $scope, $translate, attributeService, | @@ -186,6 +201,18 @@ function MultipleInputWidgetController($q, $scope, $translate, attributeService, | ||
186 | 201 | ||
187 | vm.ctx.widgetTitle = vm.widgetTitle; | 202 | vm.ctx.widgetTitle = vm.widgetTitle; |
188 | 203 | ||
204 | + //For backward compatibility | ||
205 | + if (angular.isUndefined(vm.settings.showActionButtons)) { | ||
206 | + vm.settings.showActionButtons = true; | ||
207 | + } | ||
208 | + if (angular.isUndefined(vm.settings.fieldsAlignment)) { | ||
209 | + vm.settings.fieldsAlignment = 'row'; | ||
210 | + } | ||
211 | + if (angular.isUndefined(vm.settings.fieldsInRow)) { | ||
212 | + vm.settings.fieldsInRow = 2; | ||
213 | + } | ||
214 | + //For backward compatibility | ||
215 | + | ||
189 | vm.isVerticalAlignment = !(vm.settings.fieldsAlignment === 'row'); | 216 | vm.isVerticalAlignment = !(vm.settings.fieldsAlignment === 'row'); |
190 | 217 | ||
191 | if (!vm.isVerticalAlignment && vm.settings.fieldsInRow) { | 218 | if (!vm.isVerticalAlignment && vm.settings.fieldsInRow) { |
@@ -195,60 +222,105 @@ function MultipleInputWidgetController($q, $scope, $translate, attributeService, | @@ -195,60 +222,105 @@ function MultipleInputWidgetController($q, $scope, $translate, attributeService, | ||
195 | 222 | ||
196 | function updateDatasources() { | 223 | function updateDatasources() { |
197 | if (vm.datasources && vm.datasources.length) { | 224 | if (vm.datasources && vm.datasources.length) { |
198 | - var datasource = vm.datasources[0]; | ||
199 | - if (datasource.type === types.datasourceType.entity) { | ||
200 | - for (var i = 0; i < datasource.dataKeys.length; i++) { | ||
201 | - if ((datasource.entityType !== types.entityType.device) && (datasource.dataKeys[i].settings.dataKeyType == 'shared')) { | ||
202 | - vm.isAllParametersValid = false; | 225 | + vm.entityDetected = true; |
226 | + for (var i = 0; i < vm.datasources.length; i++) { | ||
227 | + var datasource = vm.datasources[i]; | ||
228 | + var source = { | ||
229 | + datasource: datasource, | ||
230 | + keys: [] | ||
231 | + }; | ||
232 | + if (datasource.type === types.datasourceType.entity) { | ||
233 | + for (var j = 0; j < datasource.dataKeys.length; j++) { | ||
234 | + if ((datasource.entityType !== types.entityType.device) && (datasource.dataKeys[j].settings.dataKeyType == 'shared')) { | ||
235 | + vm.isAllParametersValid = false; | ||
236 | + } | ||
237 | + source.keys.push(datasource.dataKeys[j]); | ||
238 | + if (source.keys[j].units) { | ||
239 | + source.keys[j].label += ' (' + source.keys[j].units + ')'; | ||
240 | + } | ||
241 | + source.keys[j].data = {}; | ||
242 | + | ||
243 | + //For backward compatibility | ||
244 | + if (angular.isUndefined(source.keys[j].settings.dataKeyType)) { | ||
245 | + if (vm.settings.attributesShared === true) { | ||
246 | + source.keys[j].settings.dataKeyType = 'shared'; | ||
247 | + } else { | ||
248 | + source.keys[j].settings.dataKeyType = 'server'; | ||
249 | + } | ||
250 | + } | ||
251 | + | ||
252 | + if (angular.isUndefined(source.keys[j].settings.dataKeyValueType)) { | ||
253 | + if (source.keys[j].settings.inputTypeNumber === true) { | ||
254 | + source.keys[j].settings.dataKeyValueType = 'double'; | ||
255 | + } else { | ||
256 | + source.keys[j].settings.dataKeyValueType = 'string'; | ||
257 | + } | ||
258 | + } | ||
259 | + | ||
260 | + if (angular.isUndefined(source.keys[j].settings.isEditable)) { | ||
261 | + if (source.keys[j].settings.readOnly === true) { | ||
262 | + source.keys[j].settings.isEditable = 'readonly'; | ||
263 | + } else { | ||
264 | + source.keys[j].settings.isEditable = 'editable'; | ||
265 | + } | ||
266 | + } | ||
267 | + //For backward compatibility | ||
268 | + | ||
203 | } | 269 | } |
204 | - vm.data.push(datasource.dataKeys[i]); | ||
205 | - vm.data[i].data = {}; | 270 | + } else { |
271 | + vm.entityDetected = false; | ||
206 | } | 272 | } |
207 | - vm.entityDetected = true; | 273 | + vm.sources.push(source); |
208 | } | 274 | } |
209 | } | 275 | } |
210 | } | 276 | } |
211 | 277 | ||
212 | function updateWidgetData(data) { | 278 | function updateWidgetData(data) { |
213 | - for (var i = 0; i < vm.data.length; i++) { | ||
214 | - var keyData = data[i].data; | ||
215 | - if (keyData && keyData.length) { | ||
216 | - var value; | ||
217 | - switch (vm.data[i].settings.dataKeyValueType) { | ||
218 | - case 'dateTime': | ||
219 | - case 'date': | ||
220 | - value = moment(keyData[0][1]).toDate(); // eslint-disable-line | ||
221 | - break; | ||
222 | - case 'time': | ||
223 | - value = moment().startOf('day').add(keyData[0][1], 'ms').toDate(); // eslint-disable-line | ||
224 | - break; | ||
225 | - case 'booleanCheckbox': | ||
226 | - case 'booleanSwitch': | ||
227 | - value = (keyData[0][1] === 'true'); | ||
228 | - break; | ||
229 | - default: | ||
230 | - value = keyData[0][1]; | ||
231 | - } | 279 | + var dataIndex = 0; |
280 | + for (var i = 0; i < vm.sources.length; i++) { | ||
281 | + var source = vm.sources[i]; | ||
282 | + for (var j = 0; j < source.keys.length; j++) { | ||
283 | + var keyData = data[dataIndex].data; | ||
284 | + var key = source.keys[j]; | ||
285 | + if (keyData && keyData.length) { | ||
286 | + var value; | ||
287 | + switch (key.settings.dataKeyValueType) { | ||
288 | + case 'dateTime': | ||
289 | + case 'date': | ||
290 | + value = moment(keyData[0][1]).toDate(); // eslint-disable-line | ||
291 | + break; | ||
292 | + case 'time': | ||
293 | + value = moment().startOf('day').add(keyData[0][1], 'ms').toDate(); // eslint-disable-line | ||
294 | + break; | ||
295 | + case 'booleanCheckbox': | ||
296 | + case 'booleanSwitch': | ||
297 | + value = (keyData[0][1] === 'true'); | ||
298 | + break; | ||
299 | + default: | ||
300 | + value = keyData[0][1]; | ||
301 | + } | ||
232 | 302 | ||
233 | - vm.data[i].data = { | ||
234 | - currentValue: value, | ||
235 | - originalValue: value | ||
236 | - }; | ||
237 | - } | 303 | + key.data = { |
304 | + currentValue: value, | ||
305 | + originalValue: value | ||
306 | + }; | ||
307 | + } | ||
238 | 308 | ||
239 | - if (vm.data[i].settings.isEditable === 'editable' && vm.data[i].settings.disabledOnDataKey) { | ||
240 | - var conditions = data.filter((item) => { | ||
241 | - return item.dataKey.name === vm.data[i].settings.disabledOnDataKey; | ||
242 | - }); | ||
243 | - if (conditions && conditions.length) { | ||
244 | - if (conditions[0].data.length) { | ||
245 | - if (conditions[0].data[0][1] === 'false') { | ||
246 | - vm.data[i].settings.disabledOnCondition = true; | ||
247 | - } else { | ||
248 | - vm.data[i].settings.disabledOnCondition = !conditions[0].data[0][1]; | 309 | + if (key.settings.isEditable === 'editable' && key.settings.disabledOnDataKey) { |
310 | + var conditions = data.filter((item) => { | ||
311 | + return item.dataKey.name === key.settings.disabledOnDataKey; | ||
312 | + }); | ||
313 | + if (conditions && conditions.length) { | ||
314 | + if (conditions[0].data.length) { | ||
315 | + if (conditions[0].data[0][1] === 'false') { | ||
316 | + key.settings.disabledOnCondition = true; | ||
317 | + } else { | ||
318 | + key.settings.disabledOnCondition = !conditions[0].data[0][1]; | ||
319 | + } | ||
249 | } | 320 | } |
250 | } | 321 | } |
251 | } | 322 | } |
323 | + dataIndex++; | ||
252 | } | 324 | } |
253 | } | 325 | } |
254 | } | 326 | } |
@@ -17,9 +17,9 @@ | @@ -17,9 +17,9 @@ | ||
17 | --> | 17 | --> |
18 | <form class="tb-multiple-input" name="multipleInputForm" ng-submit="vm.save()" novalidate autocomplete="off"> | 18 | <form class="tb-multiple-input" name="multipleInputForm" ng-submit="vm.save()" novalidate autocomplete="off"> |
19 | <div style="padding: 0 8px;" ng-if="vm.entityDetected && vm.isAllParametersValid"> | 19 | <div style="padding: 0 8px;" ng-if="vm.entityDetected && vm.isAllParametersValid"> |
20 | - <div layout="row" layout-wrap ng-class="{'vertical-alignment': vm.isVerticalAlignment || vm.changeAlignment}"> | ||
21 | - <div ng-repeat="key in vm.data" ng-style="{'width': (vm.isVerticalAlignment || vm.changeAlignment) ? '100%' : vm.inputWidthSettings}"> | ||
22 | - <div class="input-field" ng-if="(key.settings.dataKeyValueType === 'string') && !key.settings.dataKeyHidden"> | 20 | + <div layout="row" ng-repeat="source in vm.sources" layout-wrap ng-class="{'vertical-alignment': vm.isVerticalAlignment || vm.changeAlignment}"> |
21 | + <div ng-repeat="key in source.keys" ng-if="!key.settings.dataKeyHidden" ng-style="{'width': (vm.isVerticalAlignment || vm.changeAlignment) ? '100%' : vm.inputWidthSettings}"> | ||
22 | + <div class="input-field" ng-if="(key.settings.dataKeyValueType === 'string')"> | ||
23 | <md-input-container class="md-block"> | 23 | <md-input-container class="md-block"> |
24 | <label>{{key.label}}</label> | 24 | <label>{{key.label}}</label> |
25 | <md-icon class="material-icons" ng-if="key.settings.icon"> | 25 | <md-icon class="material-icons" ng-if="key.settings.icon"> |
@@ -32,13 +32,13 @@ | @@ -32,13 +32,13 @@ | ||
32 | ng-required="key.settings.required" | 32 | ng-required="key.settings.required" |
33 | type="text" | 33 | type="text" |
34 | md-select-on-focus | 34 | md-select-on-focus |
35 | - ng-blur="vm.inputChanged(key)"> | 35 | + ng-blur="vm.inputChanged(source,key)"> |
36 | <div ng-messages="multipleInputForm[key.name].$error"> | 36 | <div ng-messages="multipleInputForm[key.name].$error"> |
37 | <div ng-message="required">{{ key.settings.requiredErrorMessage }}</div> | 37 | <div ng-message="required">{{ key.settings.requiredErrorMessage }}</div> |
38 | </div> | 38 | </div> |
39 | </md-input-container> | 39 | </md-input-container> |
40 | </div> | 40 | </div> |
41 | - <div class="input-field" ng-if="(key.settings.dataKeyValueType === 'double') && !key.settings.dataKeyHidden"> | 41 | + <div class="input-field" ng-if="(key.settings.dataKeyValueType === 'double')"> |
42 | <md-input-container class="md-block"> | 42 | <md-input-container class="md-block"> |
43 | <label>{{key.label}}</label> | 43 | <label>{{key.label}}</label> |
44 | <md-icon class="material-icons" ng-if="key.settings.icon"> | 44 | <md-icon class="material-icons" ng-if="key.settings.icon"> |
@@ -52,13 +52,13 @@ | @@ -52,13 +52,13 @@ | ||
52 | type="number" | 52 | type="number" |
53 | step="key.settings.step" | 53 | step="key.settings.step" |
54 | md-select-on-focus | 54 | md-select-on-focus |
55 | - ng-blur="vm.inputChanged(key)"> | 55 | + ng-blur="vm.inputChanged(source,key)"> |
56 | <div ng-messages="multipleInputForm[key.name].$error"> | 56 | <div ng-messages="multipleInputForm[key.name].$error"> |
57 | <div ng-message="required">{{ key.settings.requiredErrorMessage }}</div> | 57 | <div ng-message="required">{{ key.settings.requiredErrorMessage }}</div> |
58 | </div> | 58 | </div> |
59 | </md-input-container> | 59 | </md-input-container> |
60 | </div> | 60 | </div> |
61 | - <div class="input-field" ng-if="(key.settings.dataKeyValueType === 'integer') && !key.settings.dataKeyHidden"> | 61 | + <div class="input-field" ng-if="(key.settings.dataKeyValueType === 'integer')"> |
62 | <md-input-container class="md-block"> | 62 | <md-input-container class="md-block"> |
63 | <label>{{key.label}}</label> | 63 | <label>{{key.label}}</label> |
64 | <md-icon class="material-icons" ng-if="key.settings.icon"> | 64 | <md-icon class="material-icons" ng-if="key.settings.icon"> |
@@ -73,26 +73,26 @@ | @@ -73,26 +73,26 @@ | ||
73 | step="key.settings.step" | 73 | step="key.settings.step" |
74 | md-select-on-focus | 74 | md-select-on-focus |
75 | ng-pattern="/^-?[0-9]+$/" | 75 | ng-pattern="/^-?[0-9]+$/" |
76 | - ng-blur="vm.inputChanged(key)"> | 76 | + ng-blur="vm.inputChanged(source,key)"> |
77 | <div ng-messages="multipleInputForm[key.name].$error"> | 77 | <div ng-messages="multipleInputForm[key.name].$error"> |
78 | <div ng-message="required">{{ key.settings.requiredErrorMessage }}</div> | 78 | <div ng-message="required">{{ key.settings.requiredErrorMessage }}</div> |
79 | <div translate ng-message="pattern">value.invalid-integer-value</div> | 79 | <div translate ng-message="pattern">value.invalid-integer-value</div> |
80 | </div> | 80 | </div> |
81 | </md-input-container> | 81 | </md-input-container> |
82 | </div> | 82 | </div> |
83 | - <div class="input-field" ng-if="(key.settings.dataKeyValueType === 'booleanCheckbox') && !key.settings.dataKeyHidden" class="md-block"> | 83 | + <div class="input-field" ng-if="(key.settings.dataKeyValueType === 'booleanCheckbox')" class="md-block"> |
84 | <md-checkbox name="{{key.name}}" | 84 | <md-checkbox name="{{key.name}}" |
85 | ng-disabled="key.settings.isEditable === 'disabled' || key.settings.disabledOnCondition" | 85 | ng-disabled="key.settings.isEditable === 'disabled' || key.settings.disabledOnCondition" |
86 | ng-model="key.data.currentValue" | 86 | ng-model="key.data.currentValue" |
87 | - ng-change="vm.inputChanged(key)"> | 87 | + ng-change="vm.inputChanged(source,key)"> |
88 | {{key.label}} | 88 | {{key.label}} |
89 | </md-checkbox> | 89 | </md-checkbox> |
90 | </div> | 90 | </div> |
91 | - <div class="input-field" ng-if="(key.settings.dataKeyValueType === 'booleanSwitch') && !key.settings.dataKeyHidden" class="md-block"> | 91 | + <div class="input-field" ng-if="(key.settings.dataKeyValueType === 'booleanSwitch')" class="md-block"> |
92 | <md-switch name="{{key.name}}" | 92 | <md-switch name="{{key.name}}" |
93 | ng-disabled="key.settings.isEditable === 'disabled' || key.settings.disabledOnCondition" | 93 | ng-disabled="key.settings.isEditable === 'disabled' || key.settings.disabledOnCondition" |
94 | ng-model="key.data.currentValue" | 94 | ng-model="key.data.currentValue" |
95 | - ng-change="vm.inputChanged(key)" | 95 | + ng-change="vm.inputChanged(source,key)" |
96 | aria-label="{{key.label}}" | 96 | aria-label="{{key.label}}" |
97 | md-invert> | 97 | md-invert> |
98 | {{key.label}} | 98 | {{key.label}} |
@@ -100,7 +100,7 @@ | @@ -100,7 +100,7 @@ | ||
100 | </div> | 100 | </div> |
101 | <div ng-if="(key.settings.dataKeyValueType === 'dateTime') || | 101 | <div ng-if="(key.settings.dataKeyValueType === 'dateTime') || |
102 | (key.settings.dataKeyValueType === 'date') || | 102 | (key.settings.dataKeyValueType === 'date') || |
103 | - (key.settings.dataKeyValueType === 'time') && !key.settings.dataKeyHidden" | 103 | + (key.settings.dataKeyValueType === 'time')" |
104 | class="md-block input-field date-time-input" layout="column"> | 104 | class="md-block input-field date-time-input" layout="column"> |
105 | <label class="date-time-input__label">{{key.label}}</label> | 105 | <label class="date-time-input__label">{{key.label}}</label> |
106 | <div layout="row" ng-class="{'vertically-aligned': vm.smallWidthContainer}"> | 106 | <div layout="row" ng-class="{'vertically-aligned': vm.smallWidthContainer}"> |
@@ -108,7 +108,7 @@ | @@ -108,7 +108,7 @@ | ||
108 | ng-if="key.settings.dataKeyValueType !== 'time'" | 108 | ng-if="key.settings.dataKeyValueType !== 'time'" |
109 | mdp-disabled="key.settings.isEditable === 'disabled' || key.settings.disabledOnCondition" | 109 | mdp-disabled="key.settings.isEditable === 'disabled' || key.settings.disabledOnCondition" |
110 | ng-model="key.data.currentValue" | 110 | ng-model="key.data.currentValue" |
111 | - ng-change="vm.inputChanged(key)" | 111 | + ng-change="vm.inputChanged(source,key)" |
112 | mdp-placeholder="{{ 'widgets.input-widgets.date' | translate }}"> | 112 | mdp-placeholder="{{ 'widgets.input-widgets.date' | translate }}"> |
113 | <div ng-messages="multipleInputForm[key.name].$error"> | 113 | <div ng-messages="multipleInputForm[key.name].$error"> |
114 | <div ng-message="required">{{ key.settings.requiredErrorMessage }}</div> | 114 | <div ng-message="required">{{ key.settings.requiredErrorMessage }}</div> |
@@ -118,7 +118,7 @@ | @@ -118,7 +118,7 @@ | ||
118 | ng-if="key.settings.dataKeyValueType !== 'date'" | 118 | ng-if="key.settings.dataKeyValueType !== 'date'" |
119 | mdp-disabled="key.settings.isEditable === 'disabled' || key.settings.disabledOnCondition" | 119 | mdp-disabled="key.settings.isEditable === 'disabled' || key.settings.disabledOnCondition" |
120 | ng-model="key.data.currentValue" | 120 | ng-model="key.data.currentValue" |
121 | - ng-change="vm.inputChanged(key)" | 121 | + ng-change="vm.inputChanged(source,key)" |
122 | mdp-placeholder="{{ 'widgets.input-widgets.time' | translate }}" | 122 | mdp-placeholder="{{ 'widgets.input-widgets.time' | translate }}" |
123 | mdp-auto-switch="true"> | 123 | mdp-auto-switch="true"> |
124 | <div ng-messages="multipleInputForm[key.name].$error"> | 124 | <div ng-messages="multipleInputForm[key.name].$error"> |