thingsboard-memoizeit

Fix Input Widgets: Update server string attribute and Update

11/8/2018 3:41:03 PM

Details

diff --git a/application/src/main/data/json/system/widget_bundles/input_widgets.json b/application/src/main/data/json/system/widget_bundles/input_widgets.json
index 62426c5..a352a94 100644
--- a/application/src/main/data/json/system/widget_bundles/input_widgets.json
+++ b/application/src/main/data/json/system/widget_bundles/input_widgets.json
@@ -13,9 +13,9 @@
         "sizeX": 7.5,
         "sizeY": 3.5,
         "resources": [],
-        "templateHtml": "<form class=\"attribute-update-form\"\n      name=\"attrUpdateForm\"\n      ng-submit=\"updateAttribute($event)\"\n>\n    <div style=\"padding: 0 8px; margin: auto 0;\">\n\n        <div class=\"attribute-update-form__grid\" ng-show=\"entityDetected && isValidParameter\">\n            <div class=\"grid__element\">\n                <md-input-container ng-class=\"{'show-label': settings.showLabel}\" class=\"md-block\" style=\"width: 100%;\">\n                    <label>{{labelValue}}</label>\n                    <input required\n                           name=\"attribute\"\n                           ng-model=\"currentValue\"\n                           ng-focus=\"isFocused = true\"\n                           ng-blur=\"changeFocus()\"\n                           maxlength=\"{{settings.maxLength}}\"\n                           minlength=\"{{settings.minLength}}\"\n                    >\n                    <div ng-messages=\"attrUpdateForm.attribute.$error\">\n                        <div ng-message=\"required\">{{requiredErrorMessage}}</div>\n                    </div>\n                </md-input-container>\n            </div>\n\n            <div class=\"grid__element\">\n                <md-button class=\"md-icon-button applyChanges\"\n                           aria-label=\"Update server attribute\"\n                           type=\"submit\"\n                           ng-disabled=\"originalValue === currentValue\"\n                           ng-click=\"isFocused = false\"\n                >\n                    <md-icon>check</md-icon>\n                    <md-tooltip md-direction=\"top\">Update server attribute</md-tooltip>\n                </md-button>\n                <md-button class=\"md-icon-button discardChanges\"\n                           aria-label=\"Discard changes\"\n                           ng-disabled=\"originalValue === currentValue\"\n                           ng-click=\"currentValue = originalValue; isFocused = false\"\n                >\n                    <md-icon>close</md-icon>\n                    <md-tooltip md-direction=\"top\">Discard changes</md-tooltip>\n                </md-button>\n            </div>\n        </div>\n        \n        <div style=\"text-align: center; font-size: 18px; color: #a0a0a0;\" ng-hide=\"entityDetected\">\n            No entity selected\n        </div>\n        <div style=\"text-align: center; font-size: 18px; color: #a0a0a0;\" ng-show=\"entityDetected && !isValidParameter\">\n            Timeseries parameter cannot be used in this widget\n        </div>\n    </div>\n</form>",
+        "templateHtml": "<form class=\"attribute-update-form\"\n      name=\"attrUpdateForm\"\n      ng-submit=\"updateAttribute($event)\"\n>\n    <div style=\"padding: 0 8px; margin: auto 0;\">\n\n        <div class=\"attribute-update-form__grid\" ng-show=\"entityDetected && isValidParameter && dataKeyDetected\">\n            <div class=\"grid__element\">\n                <md-input-container ng-class=\"{'show-label': settings.showLabel}\" class=\"md-block\" style=\"width: 100%;\">\n                    <label>{{labelValue}}</label>\n                    <input required\n                           name=\"attribute\"\n                           ng-model=\"currentValue\"\n                           ng-focus=\"isFocused = true\"\n                           ng-blur=\"changeFocus()\"\n                           maxlength=\"{{settings.maxLength}}\"\n                           minlength=\"{{settings.minLength}}\"\n                    >\n                    <div ng-messages=\"attrUpdateForm.attribute.$error\">\n                        <div ng-message=\"required\">{{requiredErrorMessage}}</div>\n                    </div>\n                </md-input-container>\n            </div>\n\n            <div class=\"grid__element\">\n                <md-button class=\"md-icon-button applyChanges\"\n                           aria-label=\"Update server attribute\"\n                           type=\"submit\"\n                           ng-disabled=\"originalValue === currentValue\"\n                           ng-click=\"isFocused = false\"\n                >\n                    <md-icon>check</md-icon>\n                    <md-tooltip md-direction=\"top\">Update server attribute</md-tooltip>\n                </md-button>\n                <md-button class=\"md-icon-button discardChanges\"\n                           aria-label=\"Discard changes\"\n                           ng-disabled=\"originalValue === currentValue\"\n                           ng-click=\"currentValue = originalValue; isFocused = false\"\n                >\n                    <md-icon>close</md-icon>\n                    <md-tooltip md-direction=\"top\">Discard changes</md-tooltip>\n                </md-button>\n            </div>\n        </div>\n        \n        <div style=\"text-align: center; font-size: 18px; color: #a0a0a0;\" ng-hide=\"entityDetected\">\n            No entity selected\n        </div>\n        <div style=\"text-align: center; font-size: 18px; color: #a0a0a0;\" ng-show=\"entityDetected && !dataKeyDetected\">\n            No attribute is selected\n        </div>\n        <div style=\"text-align: center; font-size: 18px; color: #a0a0a0;\" ng-show=\"entityDetected && !isValidParameter\">\n            Timeseries parameter cannot be used in this widget\n        </div>\n    </div>\n</form>",
         "templateCss": ".attribute-update-form {\n    overflow: hidden;\n    height: 100%;\n    display: flex;\n    flex-direction: column;\n}\n\n.entity-title {\n    font-weight: bold;\n    font-size: 22px;\n    padding-top: 12px;\n    padding-bottom: 6px;\n    color: #666;\n}\n\n.attribute-update-form__grid {\n    display: flex;\n}\n.grid__element:first-child {\n    flex: 1;\n}\n.grid__element:last-child {\n    margin-top: 19px;\n    margin-left: 7px;\n}\n.grid__element {\n    display: flex;\n}\n\n.attribute-update-form .md-button.md-icon-button {\n    margin: 0;\n}\n\n.attribute-update-form .md-button.md-icon-button {\n    width: 32px;\n    min-width: 32px;\n    height: 32px;\n    min-height: 32px;\n    padding: 0 !important;\n    margin: 0 !important;\n    line-height: 20px;\n}\n\n.attribute-update-form .md-icon-button md-icon {\n    width: 20px;\n    min-width: 20px;\n    height: 20px;\n    min-height: 20px;\n    font-size: 20px;\n}\n\n.show-label label {\n    display: block;\n}\n\nlabel {\n    display: none;\n}\n\nmd-toast{\n    min-width: 0;\n}\nmd-toast .md-toast-content {\n    font-size: 14px!important;\n}",
-        "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\r\n    $scope = self.ctx.$scope;\r\n    attributeService = $scope.$injector.get('attributeService');\r\n    toast = $scope.$injector.get('toast');\r\n    utils = $scope.$injector.get('utils');\r\n    types = $scope.$injector.get('types');\r\n    settings = self.ctx.settings || {};\r\n    $scope.settings = settings;\r\n    $scope.isValidParameter = true;\r\n    $scope.requiredErrorMessage = settings.requiredErrorMessage || \"Entity attribute is required\";\r\n    $scope.labelValue = settings.labelValue || \"Value\";\r\n\r\n    if (self.ctx.datasources && self.ctx.datasources.length) {\r\n        var datasource = self.ctx.datasources[0];\r\n        if (datasource.type === 'entity') {\r\n            if (datasource.entityType && datasource.entityId) {\r\n                $scope.entityName = datasource.entityName;\r\n                if (settings.widgetTitle && settings.widgetTitle.length) {\r\n                    $scope.titleTemplate = utils.customTranslation(settings.widgetTitle, settings.widgetTitle);\r\n                } else {\r\n                    $scope.titleTemplate = self.ctx.widgetConfig.title;\r\n                }\r\n\r\n                $scope.entityDetected = true;\r\n            }\r\n        }\r\n        if (datasource.dataKeys[0].type != \"attribute\") {\r\n            $scope.isValidParameter = false;\r\n        }\r\n    }\r\n\r\n    self.ctx.widgetTitle = utils.createLabelFromDatasource(self.ctx.datasources[0], $scope.titleTemplate);\r\n\r\n    $scope.updateAttribute = function () {\r\n        if ($scope.entityDetected) {\r\n            var datasource = self.ctx.datasources[0];\r\n\r\n            attributeService.saveEntityAttributes(\r\n                datasource.entityType,\r\n                datasource.entityId,\r\n                types.attributesScope.server.value,\r\n                [\r\n                    {\r\n                        key: $scope.currentKey,\r\n                        value: $scope.currentValue\r\n                    }\r\n                ]\r\n            ).then(\r\n                function success() {\r\n                    $scope.originalValue = $scope.currentValue;\r\n                    if (settings.showResultMessage) {\r\n                        toast.showSuccess('Update successful', 1000, angular.element(self.ctx.$container), 'bottom left');\r\n                    }\r\n                },\r\n                function fail() {\r\n                    if (settings.showResultMessage) {\r\n                        toast.showError('Update failed', angular.element(self.ctx.$container), 'bottom left');\r\n                    }\r\n                }\r\n            );\r\n        }\r\n    };\r\n\r\n    $scope.changeFocus = function () {\r\n        if ($scope.currentValue === $scope.originalValue) {\r\n            $scope.isFocused = false;\r\n        }\r\n    }\r\n}\r\n\r\nself.onDataUpdated = function() {\r\n\r\n    try {\r\n        $scope.currentKey = self.ctx.datasources[0].dataKeys[0].label;\r\n        $scope.dataKeyType = self.ctx.datasources[0].dataKeys[0].type;\r\n\r\n        if (!$scope.isFocused) {\r\n            $scope.currentValue = $scope.originalValue = self.ctx.data[0].data[0][1];\r\n            $scope.$digest();\r\n        }\r\n\r\n    } catch (e) {\r\n        console.log(e);\r\n    }\r\n}\r\n\r\nself.onResize = function() {\r\n\r\n}\r\n\r\nself.typeParameters = function() {\r\n    return {\r\n        maxDatasources: 1,\r\n        maxDataKeys: 1,\r\n        dataKeysOptional: true\r\n    }\r\n}\r\n\r\nself.onDestroy = function() {\r\n\r\n}\r\n",
+        "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\r\n    $scope = self.ctx.$scope;\r\n    attributeService = $scope.$injector.get('attributeService');\r\n    toast = $scope.$injector.get('toast');\r\n    utils = $scope.$injector.get('utils');\r\n    types = $scope.$injector.get('types');\r\n    settings = self.ctx.settings || {};\r\n    $scope.settings = settings;\r\n    $scope.isValidParameter = true;\r\n    $scope.dataKeyDetected = false;\r\n    $scope.requiredErrorMessage = settings.requiredErrorMessage || \"Entity attribute is required\";\r\n    $scope.labelValue = settings.labelValue || \"Value\";\r\n\r\n    if (self.ctx.datasources && self.ctx.datasources.length) {\r\n        var datasource = self.ctx.datasources[0];\r\n        if (datasource.type === 'entity') {\r\n            if (datasource.entityType && datasource.entityId) {\r\n                $scope.entityName = datasource.entityName;\r\n                if (settings.widgetTitle && settings.widgetTitle.length) {\r\n                    $scope.titleTemplate = utils.customTranslation(settings.widgetTitle, settings.widgetTitle);\r\n                } else {\r\n                    $scope.titleTemplate = self.ctx.widgetConfig.title;\r\n                }\r\n\r\n                $scope.entityDetected = true;\r\n            }\r\n        }\r\n        if (datasource.dataKeys.length) {\r\n            if (datasource.dataKeys[0].type != \"attribute\") {\r\n                $scope.isValidParameter = false;\r\n            } else {\r\n                $scope.currentKey = datasource.dataKeys[0].name;\r\n                $scope.dataKeyType = datasource.dataKeys[0].type;\r\n                $scope.dataKeyDetected = true;\r\n            }\r\n        }\r\n    }\r\n\r\n    self.ctx.widgetTitle = utils.createLabelFromDatasource(self.ctx.datasources[0], $scope.titleTemplate);\r\n\r\n    $scope.updateAttribute = function () {\r\n        if ($scope.entityDetected) {\r\n            var datasource = self.ctx.datasources[0];\r\n\r\n            attributeService.saveEntityAttributes(\r\n                datasource.entityType,\r\n                datasource.entityId,\r\n                types.attributesScope.server.value,\r\n                [\r\n                    {\r\n                        key: $scope.currentKey,\r\n                        value: $scope.currentValue\r\n                    }\r\n                ]\r\n            ).then(\r\n                function success() {\r\n                    $scope.originalValue = $scope.currentValue;\r\n                    if (settings.showResultMessage) {\r\n                        toast.showSuccess('Update successful', 1000, angular.element(self.ctx.$container), 'bottom left');\r\n                    }\r\n                },\r\n                function fail() {\r\n                    if (settings.showResultMessage) {\r\n                        toast.showError('Update failed', angular.element(self.ctx.$container), 'bottom left');\r\n                    }\r\n                }\r\n            );\r\n        }\r\n    };\r\n\r\n    $scope.changeFocus = function () {\r\n        if ($scope.currentValue === $scope.originalValue) {\r\n            $scope.isFocused = false;\r\n        }\r\n    }\r\n}\r\n\r\nself.onDataUpdated = function() {\r\n\r\n    try {\r\n        if ($scope.dataKeyDetected) {\r\n            if (!$scope.isFocused) {\r\n                $scope.currentValue = $scope.originalValue = self.ctx.data[0].data[0][1];\r\n                $scope.$digest();\r\n            }\r\n        }\r\n\r\n    } catch (e) {\r\n        console.log(e);\r\n    }\r\n}\r\n\r\nself.onResize = function() {\r\n\r\n}\r\n\r\nself.typeParameters = function() {\r\n    return {\r\n        maxDatasources: 1,\r\n        maxDataKeys: 1,\r\n        dataKeysOptional: true\r\n    }\r\n}\r\n\r\nself.onDestroy = function() {\r\n\r\n}\r\n",
         "settingsSchema": "{\n    \"schema\": {\n        \"type\": \"object\",\n        \"title\": \"EntitiesTableSettings\",\n        \"properties\": {\n            \"widgetTitle\": {\n                \"title\": \"Widget title\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            },\n            \"showLabel\":{\n                \"title\":\"Show label\",\n                \"type\":\"boolean\",\n                \"default\":true\n            },\n            \"labelValue\": {\n                \"title\": \"Label\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            },\n            \"requiredErrorMessage\": {\n                \"title\": \"'Required' error message\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            },\n            \"maxLength\": {\n                \"title\": \"Max length\",\n                \"type\": \"number\",\n                \"default\": \"\"\n            },\n            \"minLength\": {\n                \"title\": \"Min length\",\n                \"type\": \"number\",\n                \"default\": \"\"\n            },\n            \"showResultMessage\":{\n                \"title\":\"Show result message\",\n                \"type\":\"boolean\",\n                \"default\":true\n            }\n        },\n        \"required\": []\n    },\n    \"form\": [\n        \"widgetTitle\",\n        \"showResultMessage\",\n        \"showLabel\",\n        \"labelValue\",\n        \"requiredErrorMessage\",\n        \"maxLength\",\n        \"minLength\"\n    ]\n}",
         "dataKeySettingsSchema": "{}\n",
         "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 server string attribute\",\"dropShadow\":true,\"enableFullscreen\":false,\"enableDataExport\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{}}"
@@ -29,9 +29,9 @@
         "sizeX": 7.5,
         "sizeY": 3,
         "resources": [],
-        "templateHtml": "<form class=\"attribute-update-form\"\n      name=\"attrUpdateForm\"\n      ng-submit=\"updateAttribute($event)\"\n>\n    <div style=\"padding: 0 8px; margin: auto 0;\">\n\n        <div class=\"attribute-update-form__grid\" ng-show=\"entityDetected && isValidParameter\">\n            <div class=\"grid__element\">\n                <md-input-container ng-class=\"{'show-label': settings.showLabel}\" class=\"md-block\" style=\"width: 100%;\">\n                    <label>{{labelValue}}</label>\n                    <input required\n                           name=\"attribute\"\n                           ng-model=\"currentValue\"\n                           ng-focus=\"isFocused = true\"\n                           ng-blur=\"changeFocus()\"\n                           type=\"number\"\n                           max=\"{{settings.maxValue}}\"\n                           min=\"{{settings.minValue}}\"\n                    >\n                    <div ng-messages=\"attrUpdateForm.attribute.$error\">\n                        <div ng-message=\"required\">{{requiredErrorMessage}}</div>\n                    </div>\n                </md-input-container>\n            </div>\n\n            <div class=\"grid__element\">\n                <md-button class=\"md-icon-button applyChanges\"\n                           aria-label=\"Update server attribute\"\n                           type=\"submit\"\n                           ng-disabled=\"originalValue === currentValue\"\n                           ng-click=\"isFocused = false\"\n                >\n                    <md-icon>check</md-icon>\n                    <md-tooltip md-direction=\"top\">Update server attribute</md-tooltip>\n                </md-button>\n                <md-button class=\"md-icon-button discardChanges\"\n                           aria-label=\"Discard changes\"\n                           ng-disabled=\"originalValue === currentValue\"\n                           ng-click=\"currentValue = originalValue; isFocused = false\"\n                >\n                    <md-icon>close</md-icon>\n                    <md-tooltip md-direction=\"top\">Discard changes</md-tooltip>\n                </md-button>\n            </div>\n        </div>\n\n        <div style=\"text-align: center; font-size: 18px; color: #a0a0a0;\" ng-hide=\"entityDetected\">\n            No entity selected\n        </div>\n        <div style=\"text-align: center; font-size: 18px; color: #a0a0a0;\" ng-show=\"entityDetected && !isValidParameter\">\n            Timeseries parameter cannot be used in this widget\n        </div>\n    </div>\n</form>",
+        "templateHtml": "<form class=\"attribute-update-form\"\n      name=\"attrUpdateForm\"\n      ng-submit=\"updateAttribute($event)\"\n>\n    <div style=\"padding: 0 8px; margin: auto 0;\">\n\n        <div class=\"attribute-update-form__grid\" ng-show=\"entityDetected && isValidParameter && dataKeyDetected\">\n            <div class=\"grid__element\">\n                <md-input-container ng-class=\"{'show-label': settings.showLabel}\" class=\"md-block\" style=\"width: 100%;\">\n                    <label>{{labelValue}}</label>\n                    <input required\n                           name=\"attribute\"\n                           ng-model=\"currentValue\"\n                           ng-focus=\"isFocused = true\"\n                           ng-blur=\"changeFocus()\"\n                           type=\"number\"\n                           max=\"{{settings.maxValue}}\"\n                           min=\"{{settings.minValue}}\"\n                    >\n                    <div ng-messages=\"attrUpdateForm.attribute.$error\">\n                        <div ng-message=\"required\">{{requiredErrorMessage}}</div>\n                    </div>\n                </md-input-container>\n            </div>\n\n            <div class=\"grid__element\">\n                <md-button class=\"md-icon-button applyChanges\"\n                           aria-label=\"Update server attribute\"\n                           type=\"submit\"\n                           ng-disabled=\"originalValue === currentValue\"\n                           ng-click=\"isFocused = false\"\n                >\n                    <md-icon>check</md-icon>\n                    <md-tooltip md-direction=\"top\">Update server attribute</md-tooltip>\n                </md-button>\n                <md-button class=\"md-icon-button discardChanges\"\n                           aria-label=\"Discard changes\"\n                           ng-disabled=\"originalValue === currentValue\"\n                           ng-click=\"currentValue = originalValue; isFocused = false\"\n                >\n                    <md-icon>close</md-icon>\n                    <md-tooltip md-direction=\"top\">Discard changes</md-tooltip>\n                </md-button>\n            </div>\n        </div>\n\n        <div style=\"text-align: center; font-size: 18px; color: #a0a0a0;\" ng-hide=\"entityDetected\">\n            No entity selected\n        </div>\n        <div style=\"text-align: center; font-size: 18px; color: #a0a0a0;\" ng-show=\"entityDetected && !dataKeyDetected\">\n            No attribute is selected\n        </div>\n        <div style=\"text-align: center; font-size: 18px; color: #a0a0a0;\" ng-show=\"entityDetected && !isValidParameter\">\n            Timeseries parameter cannot be used in this widget\n        </div>\n    </div>\n</form>",
         "templateCss": ".attribute-update-form {\n    overflow: hidden;\n    height: 100%;\n    display: flex;\n    flex-direction: column;\n}\n\n.entity-title {\n    font-weight: bold;\n    font-size: 22px;\n    padding-top: 12px;\n    padding-bottom: 6px;\n    color: #666;\n}\n\n.attribute-update-form__grid {\n    display: flex;\n}\n.grid__element:first-child {\n    flex: 1;\n}\n.grid__element:last-child {\n    margin-top: 19px;\n    margin-left: 7px;\n}\n.grid__element {\n    display: flex;\n}\n\n.attribute-update-form .md-button.md-icon-button {\n    margin: 0;\n}\n\n.attribute-update-form .md-button.md-icon-button {\n    width: 32px;\n    min-width: 32px;\n    height: 32px;\n    min-height: 32px;\n    padding: 0 !important;\n    margin: 0 !important;\n    line-height: 20px;\n}\n\n.attribute-update-form .md-icon-button md-icon {\n    width: 20px;\n    min-width: 20px;\n    height: 20px;\n    min-height: 20px;\n    font-size: 20px;\n}\n\n.show-label label {\n    display: block;\n}\n\nlabel {\n    display: none;\n}\n\nmd-toast{\n    min-width: 0;\n}\nmd-toast .md-toast-content {\n    font-size: 14px!important;\n}",
-        "controllerScript": "let $scope;\nlet settings;\nlet attributeService;\nlet toast;\nlet utils;\nlet types;\n\nself.onInit = function() {\n\n    $scope = self.ctx.$scope;\n    attributeService = $scope.$injector.get('attributeService');\n    toast = $scope.$injector.get('toast');\n    utils = $scope.$injector.get('utils');\n    types = $scope.$injector.get('types');\n    settings = self.ctx.settings || {};\n    $scope.settings = settings;\n    $scope.isValidParameter = true;\n    $scope.requiredErrorMessage = settings.requiredErrorMessage || \"Entity attribute is required\";\n    $scope.labelValue = settings.labelValue || \"Value\";\n\n    if (self.ctx.datasources && self.ctx.datasources.length) {\n        var datasource = self.ctx.datasources[0];\n        if (datasource.type === 'entity') {\n            if (datasource.entityType && datasource.entityId) {\n                $scope.entityName = datasource.entityName;\n                if (settings.widgetTitle && settings.widgetTitle.length) {\n                    $scope.titleTemplate = utils.customTranslation(settings.widgetTitle, settings.widgetTitle);\n                } else {\n                    $scope.titleTemplate = self.ctx.widgetConfig.title;\n                }\n\n                $scope.entityDetected = true;\n            }\n        }\n        if (datasource.dataKeys[0].type != \"attribute\") {\n            $scope.isValidParameter = false;\n        }\n    }\n\n    self.ctx.widgetTitle = utils.createLabelFromDatasource(self.ctx.datasources[0], $scope.titleTemplate);\n\n    $scope.updateAttribute = function () {\n        if ($scope.entityDetected) {\n            var datasource = self.ctx.datasources[0];\n\n            attributeService.saveEntityAttributes(\n                datasource.entityType,\n                datasource.entityId,\n                types.attributesScope.server.value,\n                [\n                    {\n                        key: $scope.currentKey,\n                        value: $scope.currentValue\n                    }\n                ]\n            ).then(\n                function success() {\n                    $scope.originalValue = $scope.currentValue;\n                    if (settings.showResultMessage) {\n                        toast.showSuccess('Update successful', 1000, angular.element(self.ctx.$container), 'bottom left');\n                    }\n                },\n                function fail() {\n                   if (settings.showResultMessage) {\n                        toast.showError('Update failed', angular.element(self.ctx.$container), 'bottom left');\n                    }\n                }\n            );\n        }\n    };\n\n    $scope.changeFocus = function () {\n        if ($scope.currentValue === $scope.originalValue) {\n            $scope.isFocused = false;\n        }\n    }\n}\n\nself.onDataUpdated = function() {\n\n    try {\n        $scope.currentKey = self.ctx.datasources[0].dataKeys[0].label;\n        $scope.dataKeyType = self.ctx.datasources[0].dataKeys[0].type;\n\n        if (!$scope.isFocused) {\n            $scope.currentValue = $scope.originalValue = self.ctx.data[0].data[0][1];\n            correctValue($scope.currentValue);\n            $scope.$digest();\n        }\n\n    } catch (e) {\n        console.log(e);\n    }\n}\n\nfunction correctValue(value) {\n    if (typeof value !== \"number\") {\n        $scope.currentValue = 0;\n    }\n}\n\nself.onResize = function() {\n\n}\n\nself.typeParameters = function() {\n    return {\n        maxDatasources: 1,\n        maxDataKeys: 1,\n        dataKeysOptional: true\n    }\n}\n\nself.onDestroy = function() {\n\n}\n",
+        "controllerScript": "let $scope;\nlet settings;\nlet attributeService;\nlet toast;\nlet utils;\nlet types;\n\nself.onInit = function() {\n\n    $scope = self.ctx.$scope;\n    attributeService = $scope.$injector.get('attributeService');\n    toast = $scope.$injector.get('toast');\n    utils = $scope.$injector.get('utils');\n    types = $scope.$injector.get('types');\n    settings = self.ctx.settings || {};\n    $scope.settings = settings;\n    $scope.isValidParameter = true;\n    $scope.dataKeyDetected = false;\n    $scope.requiredErrorMessage = settings.requiredErrorMessage || \"Entity attribute is required\";\n    $scope.labelValue = settings.labelValue || \"Value\";\n\n    if (self.ctx.datasources && self.ctx.datasources.length) {\n        var datasource = self.ctx.datasources[0];\n        if (datasource.type === 'entity') {\n            if (datasource.entityType && datasource.entityId) {\n                $scope.entityName = datasource.entityName;\n                if (settings.widgetTitle && settings.widgetTitle.length) {\n                    $scope.titleTemplate = utils.customTranslation(settings.widgetTitle, settings.widgetTitle);\n                } else {\n                    $scope.titleTemplate = self.ctx.widgetConfig.title;\n                }\n\n                $scope.entityDetected = true;\n            }\n        }\n        if (datasource.dataKeys.length) {\n            if (datasource.dataKeys[0].type != \"attribute\") {\n                $scope.isValidParameter = false;\n            } else {\n                $scope.currentKey = datasource.dataKeys[0].name;\n                $scope.dataKeyType = datasource.dataKeys[0].type;\n                $scope.dataKeyDetected = true;\n            }\n        }\n    }\n\n    self.ctx.widgetTitle = utils.createLabelFromDatasource(self.ctx.datasources[0], $scope.titleTemplate);\n\n    $scope.updateAttribute = function () {\n        if ($scope.entityDetected) {\n            var datasource = self.ctx.datasources[0];\n\n            attributeService.saveEntityAttributes(\n                datasource.entityType,\n                datasource.entityId,\n                types.attributesScope.server.value,\n                [\n                    {\n                        key: $scope.currentKey,\n                        value: $scope.currentValue\n                    }\n                ]\n            ).then(\n                function success() {\n                    $scope.originalValue = $scope.currentValue;\n                    if (settings.showResultMessage) {\n                        toast.showSuccess('Update successful', 1000, angular.element(self.ctx.$container), 'bottom left');\n                    }\n                },\n                function fail() {\n                   if (settings.showResultMessage) {\n                        toast.showError('Update failed', angular.element(self.ctx.$container), 'bottom left');\n                    }\n                }\n            );\n        }\n    };\n\n    $scope.changeFocus = function () {\n        if ($scope.currentValue === $scope.originalValue) {\n            $scope.isFocused = false;\n        }\n    }\n}\n\nself.onDataUpdated = function() {\n\n    try {\n        if ($scope.dataKeyDetected) {\n            if (!$scope.isFocused) {\n                $scope.currentValue = $scope.originalValue = self.ctx.data[0].data[0][1];\n                correctValue($scope.currentValue);\n                $scope.$digest();\n            }\n        }\n\n    } catch (e) {\n        console.log(e);\n    }\n}\n\nfunction correctValue(value) {\n    if (typeof value !== \"number\") {\n        $scope.currentValue = 0;\n    }\n}\n\nself.onResize = function() {\n\n}\n\nself.typeParameters = function() {\n    return {\n        maxDatasources: 1,\n        maxDataKeys: 1,\n        dataKeysOptional: true\n    }\n}\n\nself.onDestroy = function() {\n\n}\n",
         "settingsSchema": "{\n    \"schema\": {\n        \"type\": \"object\",\n        \"title\": \"EntitiesTableSettings\",\n        \"properties\": {\n            \"widgetTitle\": {\n                \"title\": \"Widget title\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            },\n            \"showLabel\":{\n                \"title\":\"Show label\",\n                \"type\":\"boolean\",\n                \"default\":true\n            },\n            \"labelValue\": {\n                \"title\": \"Label\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            },\n            \"requiredErrorMessage\": {\n                \"title\": \"'Required' error message\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            },\n            \"maxValue\": {\n                \"title\": \"Max value\",\n                \"type\": \"number\",\n                \"default\": \"\"\n            },\n            \"minValue\": {\n                \"title\": \"Min value\",\n                \"type\": \"number\",\n                \"default\": \"\"\n            },\n            \"showResultMessage\":{\n                \"title\":\"Show result message\",\n                \"type\":\"boolean\",\n                \"default\":true\n            }\n        },\n        \"required\": []\n    },\n    \"form\": [\n        \"widgetTitle\",\n        \"showResultMessage\",\n        \"showLabel\",\n        \"labelValue\",\n        \"requiredErrorMessage\",\n        \"maxValue\",\n        \"minValue\"\n    ]\n}",
         "dataKeySettingsSchema": "{}\n",
         "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{},\"title\":\"Update server integer attribute\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{}}"
diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java
index 2486cd8..f87f046 100644
--- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java
+++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java
@@ -118,6 +118,7 @@ public class ThingsboardInstallService {
                         systemDataLoaderService.deleteSystemWidgetBundle("control_widgets");
                         systemDataLoaderService.deleteSystemWidgetBundle("maps_v2");
                         systemDataLoaderService.deleteSystemWidgetBundle("gateway_widgets");
+                        systemDataLoaderService.deleteSystemWidgetBundle("input_widgets");
 
                         systemDataLoaderService.loadSystemWidgets();
 
diff --git a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java
index 757eb95..b1b7f81 100644
--- a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java
+++ b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java
@@ -156,7 +156,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
 
     @Override
     public void deleteSystemWidgetBundle(String bundleAlias) throws Exception {
-        WidgetsBundle widgetsBundle = widgetsBundleService.findWidgetsBundleByTenantIdAndAlias(new TenantId(ModelConstants.NULL_UUID), bundleAlias);
+        WidgetsBundle widgetsBundle = widgetsBundleService.findWidgetsBundleByTenantIdAndAlias(TenantId.SYS_TENANT_ID, bundleAlias);
         if (widgetsBundle != null) {
             widgetsBundleService.deleteWidgetsBundle(TenantId.SYS_TENANT_ID, widgetsBundle.getId());
         }