Commit d965df8c271f0569b02908ea486922e18465543a
Merge remote-tracking branch 'origin/master' into develop/2.5
Showing
8 changed files
with
164 additions
and
69 deletions
... | ... | @@ -6,6 +6,38 @@ |
6 | 6 | }, |
7 | 7 | "widgetTypes": [ |
8 | 8 | { |
9 | + "alias": "attributes_card", | |
10 | + "name": "Gateway events", | |
11 | + "descriptor": { | |
12 | + "type": "latest", | |
13 | + "sizeX": 7.5, | |
14 | + "sizeY": 8, | |
15 | + "resources": [], | |
16 | + "templateHtml": "", | |
17 | + "templateCss": "#container {\n overflow: auto;\n}\n\n.tbDatasource-container {\n margin: 5px;\n padding: 8px;\n}\n\n.tbDatasource-title {\n font-size: 1.200rem;\n font-weight: 500;\n padding-bottom: 10px;\n}\n\n.tbDatasource-table {\n width: 100%;\n box-shadow: 0 0 10px #ccc;\n border-collapse: collapse;\n white-space: nowrap;\n font-size: 1.000rem;\n color: #757575;\n}\n\n.tbDatasource-table td {\n position: relative;\n border-top: 1px solid rgba(0, 0, 0, 0.12);\n border-bottom: 1px solid rgba(0, 0, 0, 0.12);\n padding: 0px 18px;\n box-sizing: border-box;\n}", | |
18 | + "controllerScript": "let types;\nlet eventsReg = \"eventsReg\";\n\nself.onInit = function() {\n \n self.ctx.datasourceTitleCells = [];\n self.ctx.valueCells = [];\n self.ctx.labelCells = [];\n types = self.ctx.$scope.$injector.get('types');\n \n if (self.ctx.datasources.length && self.ctx.datasources[0].type === types.datasourceType.entity) {\n getDatasourceKeys(self.ctx.datasources[0]);\n } else {\n processDatasources(self.ctx.datasources);\n }\n}\n\nself.onDataUpdated = function() {\n for (var i = 0; i < self.ctx.valueCells.length; i++) {\n var cellData = self.ctx.data[i];\n if (cellData && cellData.data && cellData.data.length > 0) {\n var tvPair = cellData.data[cellData.data.length -\n 1];\n var value = tvPair[1];\n var textValue;\n //toDo -> + IsNumber\n \n if (isNumber(value)) {\n var decimals = self.ctx.decimals;\n var units = self.ctx.units;\n if (cellData.dataKey.decimals || cellData.dataKey.decimals === 0) {\n decimals = cellData.dataKey.decimals;\n }\n if (cellData.dataKey.units) {\n units = cellData.dataKey.units;\n }\n txtValue = self.ctx.utils.formatValue(value, decimals, units, false);\n }\n else {\n txtValue = value;\n }\n self.ctx.valueCells[i].html(txtValue);\n }\n }\n \n function isNumber(n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n}\n\nself.onResize = function() {\n var datasourceTitleFontSize = self.ctx.height/8;\n if (self.ctx.width/self.ctx.height <= 1.5) {\n datasourceTitleFontSize = self.ctx.width/12;\n }\n datasourceTitleFontSize = Math.min(datasourceTitleFontSize, 20);\n for (var i = 0; i < self.ctx.datasourceTitleCells.length; i++) {\n self.ctx.datasourceTitleCells[i].css('font-size', datasourceTitleFontSize+'px');\n }\n var valueFontSize = self.ctx.height/9;\n var labelFontSize = self.ctx.height/9;\n if (self.ctx.width/self.ctx.height <= 1.5) {\n valueFontSize = self.ctx.width/15;\n labelFontSize = self.ctx.width/15;\n }\n valueFontSize = Math.min(valueFontSize, 18);\n labelFontSize = Math.min(labelFontSize, 18);\n\n for (i = 0; i < self.ctx.valueCells; i++) {\n self.ctx.valueCells[i].css('font-size', valueFontSize+'px');\n self.ctx.valueCells[i].css('height', valueFontSize*2.5+'px');\n self.ctx.valueCells[i].css('padding', '0px ' + valueFontSize + 'px');\n self.ctx.labelCells[i].css('font-size', labelFontSize+'px');\n self.ctx.labelCells[i].css('height', labelFontSize*2.5+'px');\n self.ctx.labelCells[i].css('padding', '0px ' + labelFontSize + 'px');\n } \n}\n\nfunction processDatasources(datasources) {\n var i = 0;\n var tbDatasource = datasources[i];\n var datasourceId = 'tbDatasource' + i;\n self.ctx.$container.append(\n \"<div id='\" + datasourceId +\n \"' class='tbDatasource-container'></div>\"\n );\n\n var datasourceContainer = $('#' + datasourceId,\n self.ctx.$container);\n\n datasourceContainer.append(\n \"<div class='tbDatasource-title'>\" +\n tbDatasource.name + \"</div>\"\n );\n \n var datasourceTitleCell = $('.tbDatasource-title', datasourceContainer);\n self.ctx.datasourceTitleCells.push(datasourceTitleCell);\n \n var tableId = 'table' + i;\n datasourceContainer.append(\n \"<table id='\" + tableId +\n \"' class='tbDatasource-table'><col width='30%'><col width='70%'></table>\"\n );\n var table = $('#' + tableId, self.ctx.$container);\n\n for (var a = 0; a < tbDatasource.dataKeys.length; a++) {\n var dataKey = tbDatasource.dataKeys[a];\n var labelCellId = 'labelCell' + a;\n var cellId = 'cell' + a;\n table.append(\"<tr><td id='\" + labelCellId + \"'>\" + dataKey.label +\n \"</td><td id='\" + cellId +\n \"'></td></tr>\");\n var labelCell = $('#' + labelCellId, table);\n self.ctx.labelCells.push(labelCell);\n var valueCell = $('#' + cellId, table);\n self.ctx.valueCells.push(valueCell);\n }\n self.onResize();\n}\n\nfunction getDatasourceKeys (datasource) {\n let attributeService = self.ctx.$scope.$injector.get('attributeService');\n if (datasource.entityId && datasource.entityType) {\n attributeService.getEntityKeys(datasource.entityType, datasource.entityId, \"\" , types.dataKeyType.timeseries).then(\n function(data){\n if (data.length) {\n subscribeForKeys (datasource, data);\n }\n });\n }\n}\n\nfunction subscribeForKeys (datasource, data) {\n let eventsRegVals = self.ctx.settings[eventsReg];\n if (eventsRegVals && eventsRegVals.length > 0) {\n var dataKeys = [];\n data.sort();\n data.forEach(dataValue => {eventsRegVals.forEach(event => {\n if (dataValue.toLowerCase().includes(event.toLowerCase())) {\n var dataKey = {\n type: types.dataKeyType.timeseries,\n name: dataValue,\n label: dataValue,\n settings: {},\n _hash: Math.random()\n };\n dataKeys.push(dataKey);\n }\n })});\n\n if (dataKeys.length) {\n updateSubscription (datasource, dataKeys);\n }\n }\n}\n\nfunction updateSubscription (datasource, dataKeys) {\n var datasources = [\n {\n type: types.datasourceType.entity,\n name: datasource.aliasName,\n aliasName: datasource.aliasName,\n entityAliasId: datasource.entityAliasId,\n dataKeys: dataKeys\n }\n ];\n \n var subscriptionOptions = {\n datasources: datasources,\n useDashboardTimewindow: false,\n type: types.widgetType.latest.value,\n callbacks: {\n onDataUpdated: (subscription) => {\n self.ctx.data = subscription.data;\n self.onDataUpdated();\n }\n }\n };\n \n processDatasources(datasources);\n self.ctx.subscriptionApi.createSubscription(subscriptionOptions, true).then(\n (subscription) => {\n self.ctx.defaultSubscription = subscription;\n }\n );\n}\n\nself.onDestroy = function() {\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\t\n dataKeysOptional: true\n };\n}\n\n", | |
19 | + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"GatewayEventsForm\",\n \"properties\": {\n \"eventsTitle\": {\n \"title\": \"Gateway events form title\",\n \"type\": \"string\",\n \"default\": \"Gateway Events Form\"\n },\n \"eventsReg\": {\n \"title\": \"Events filten.\",\n \"type\": \"array\",\n \"items\": {\n \"title\": \"Event key contains\",\n \"type\": \"string\"\n }\n }\n }\n },\n \"form\": [\n \"eventsTitle\",\n \"eventsReg\"\n ]\n}", | |
20 | + "dataKeySettingsSchema": "{}\n", | |
21 | + "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Function Math.round\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.826503672916844,\"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\":{\"eventsTitle\":\"Gateway Events Form\",\"eventsReg\":[]},\"title\":\"Gateway events\",\"showTitleIcon\":false,\"titleIcon\":\"more_horiz\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"displayTimewindow\":true,\"showLegend\":false,\"actions\":{}}" | |
22 | + } | |
23 | + }, | |
24 | + { | |
25 | + "alias": "config_form_latest", | |
26 | + "name": "Gateway configuration (Single device)", | |
27 | + "descriptor": { | |
28 | + "type": "latest", | |
29 | + "sizeX": 7.5, | |
30 | + "sizeY": 9, | |
31 | + "resources": [], | |
32 | + "templateHtml": "<tb-gateway-form\n form-id=\"formId\"\n ctx=\"ctx\"\n is-state-form=\"isStateForm\">\n</tb-gateway-form>", | |
33 | + "templateCss": "#container {\n overflow: auto;\n}\n\n.tbDatasource-container {\n margin: 5px;\n padding: 8px;\n}\n\n.tbDatasource-title {\n font-size: 1.200rem;\n font-weight: 500;\n padding-bottom: 10px;\n}\n\n.tbDatasource-table {\n width: 100%;\n box-shadow: 0 0 10px #ccc;\n border-collapse: collapse;\n white-space: nowrap;\n font-size: 1.000rem;\n color: #757575;\n}\n\n.tbDatasource-table td {\n position: relative;\n border-top: 1px solid rgba(0, 0, 0, 0.12);\n border-bottom: 1px solid rgba(0, 0, 0, 0.12);\n padding: 0px 18px;\n box-sizing: border-box;\n}", | |
34 | + "controllerScript": "self.onInit = function() {\n var scope = self.ctx.$scope;\n var id = self.ctx.$scope.$injector.get('utils').guid();\n scope.formId = \"form-\"+id;\n scope.ctx = self.ctx;\n scope.isStateForm = true;\n}\n\nself.onResize = function() {\n self.ctx.$scope.$broadcast('gateway-form-resize', self.ctx.$scope.formId);\n}\n\n\nself.onDestroy = function() {\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\t\t\t\n dataKeysOptional: true\t\t\n };\n}\n\n", | |
35 | + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"GatewayConfigForm\",\n \"properties\": {\n \"gatewayTitle\": {\n \"title\": \"Gateway form\",\n \"type\": \"string\",\n \"default\": \"Gateway configuration (Single device)\"\n },\n \"readOnly\": {\n \"title\": \"Read Only\",\n \"type\": \"boolean\",\n \"default\": false\n }\n }\n },\n \"form\": [\n \"gatewayTitle\",\n \"readOnly\"\n ]\n}\n", | |
36 | + "dataKeySettingsSchema": "{}\n", | |
37 | + "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\":\"Gateway configuration (Single device)\"}" | |
38 | + } | |
39 | + }, | |
40 | + { | |
9 | 41 | "alias": "extension_configuration_widget", |
10 | 42 | "name": "Extensions table", |
11 | 43 | "descriptor": { | ... | ... |
... | ... | @@ -1645,7 +1645,7 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable { |
1645 | 1645 | addPageLinkToParam(params, pageLink); |
1646 | 1646 | |
1647 | 1647 | Map<String, List<JsonNode>> timeseries = restTemplate.exchange( |
1648 | - baseURL + "/api/plugins/telemetry/{entityType}/{entityId}/values/timeseries?keys={keys}&interval={interval}&agg={agg}&useStrictDataTypes={useStrictDataTypes}&" + getUrlParams(pageLink), | |
1648 | + baseURL + "/api/plugins/telemetry/{entityType}/{entityId}/values/timeseries?keys={keys}&interval={interval}&agg={agg}&useStrictDataTypes={useStrictDataTypes}&" + getUrlParamsTs(pageLink), | |
1649 | 1649 | HttpMethod.GET, |
1650 | 1650 | HttpEntity.EMPTY, |
1651 | 1651 | new ParameterizedTypeReference<Map<String, List<JsonNode>>>() { |
... | ... | @@ -1997,12 +1997,20 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable { |
1997 | 1997 | } |
1998 | 1998 | |
1999 | 1999 | private String getUrlParams(TimePageLink pageLink) { |
2000 | + return getUrlParams(pageLink, "startTime", "endTime"); | |
2001 | + } | |
2002 | + | |
2003 | + private String getUrlParamsTs(TimePageLink pageLink) { | |
2004 | + return getUrlParams(pageLink, "startTs", "endTs"); | |
2005 | + } | |
2006 | + | |
2007 | + private String getUrlParams(TimePageLink pageLink, String startTime, String endTime) { | |
2000 | 2008 | String urlParams = "limit={limit}&ascOrder={ascOrder}"; |
2001 | 2009 | if (pageLink.getStartTime() != null) { |
2002 | - urlParams += "&startTime={startTime}"; | |
2010 | + urlParams += "&" + startTime + "={startTime}"; | |
2003 | 2011 | } |
2004 | 2012 | if (pageLink.getEndTime() != null) { |
2005 | - urlParams += "&endTime={endTime}"; | |
2013 | + urlParams += "&" + endTime + "={endTime}"; | |
2006 | 2014 | } |
2007 | 2015 | if (pageLink.getIdOffset() != null) { |
2008 | 2016 | urlParams += "&offset={offset}"; | ... | ... |
... | ... | @@ -606,13 +606,29 @@ export default angular.module('thingsboard.types', []) |
606 | 606 | value: "modbus", |
607 | 607 | name: "Modbus" |
608 | 608 | }, |
609 | - opc_ua: { | |
609 | + opcua: { | |
610 | 610 | value: "opcua", |
611 | 611 | name: "OPC-UA" |
612 | 612 | }, |
613 | 613 | ble: { |
614 | 614 | value: "ble", |
615 | 615 | name: "BLE" |
616 | + }, | |
617 | + request: { | |
618 | + value: "request", | |
619 | + name: "Request" | |
620 | + }, | |
621 | + can: { | |
622 | + value: "can", | |
623 | + name: "CAN" | |
624 | + }, | |
625 | + bacnet: { | |
626 | + value: "bacnet", | |
627 | + name: "BACnet" | |
628 | + }, | |
629 | + custom: { | |
630 | + value: "custom", | |
631 | + name: "Custom" | |
616 | 632 | } |
617 | 633 | }, |
618 | 634 | gatewayLogLevel: { | ... | ... |
... | ... | @@ -37,7 +37,8 @@ function GatewayConfig() { |
37 | 37 | disabled: '=ngDisabled', |
38 | 38 | gatewayConfig: '=', |
39 | 39 | changeAlignment: '=', |
40 | - theForm: '=' | |
40 | + theForm: '=', | |
41 | + isReadOnly: '=' | |
41 | 42 | }, |
42 | 43 | controller: GatewayConfigController, |
43 | 44 | controllerAs: 'vm', |
... | ... | @@ -83,6 +84,10 @@ function GatewayConfigController($scope, $document, $mdDialog, $mdUtil, $window, |
83 | 84 | multiple: true, |
84 | 85 | }).then(function (config) { |
85 | 86 | if (config && index > -1) { |
87 | + console.log(config); //eslint-disable-line | |
88 | + if (!angular.equals(vm.gatewayConfig[index].config, config)) { | |
89 | + $scope.gatewayConfiguration.$setDirty(); | |
90 | + } | |
86 | 91 | vm.gatewayConfig[index].config = config; |
87 | 92 | } |
88 | 93 | }); | ... | ... |
... | ... | @@ -18,7 +18,7 @@ |
18 | 18 | <section name="gatewayConfig" layout="column" class="gateway-config"> |
19 | 19 | <section layout="row" ng-form="gatewayConfig_{{$index}}" ng-repeat="connector in vm.gatewayConfig track by $index"> |
20 | 20 | <div layout="column" layout-align="center start" class="gateway-config-row"> |
21 | - <md-switch ng-model="connector.enabled" ng-disabled="gatewayConfig_{{$index}}.$invalid || vm.validateJSON(connector.config)" | |
21 | + <md-switch ng-disabled="vm.isReadOnly" ng-model="connector.enabled" ng-disabled="gatewayConfig_{{$index}}.$invalid || vm.validateJSON(connector.config)" | |
22 | 22 | aria-label="{{ 'gateway.connector-enabled' | translate }}"> |
23 | 23 | </md-switch> |
24 | 24 | </div> |
... | ... | @@ -26,7 +26,7 @@ |
26 | 26 | ng-class="{'gateway-config-row-vertical': vm.changeAlignment}"> |
27 | 27 | <md-input-container class="md-block" flex> |
28 | 28 | <label>{{'gateway.connector-type' | translate }}</label> |
29 | - <md-select name="connectorType" | |
29 | + <md-select ng-disabled="vm.isReadOnly" name="connectorType" | |
30 | 30 | ng-change="vm.changeConnectorType(connector)" |
31 | 31 | aria-label="{{ 'gateway.gateway.connector-type' | translate }}" |
32 | 32 | ng-model="connector.configType" required> |
... | ... | @@ -39,7 +39,7 @@ |
39 | 39 | </div> |
40 | 40 | </md-input-container> |
41 | 41 | <md-input-container class="md-block" flex> |
42 | - <input placeholder="{{'gateway.connector-name' | translate }}" | |
42 | + <input ng-disabled="vm.isReadOnly" placeholder="{{'gateway.connector-name' | translate }}" | |
43 | 43 | ng-model-options="{ updateOn: 'blur' }" |
44 | 44 | ng-change="vm.changeConnectorName(connector, $index)" name="connectorName" ng-model="connector.name" required/> |
45 | 45 | <div ng-messages="vm.theForm.connectorName.$error"> |
... | ... | @@ -49,7 +49,7 @@ |
49 | 49 | </div> |
50 | 50 | <div layout="row" layout-align="end center" class="action-buttons" |
51 | 51 | ng-class="{'gateway-config-row-vertical': vm.changeAlignment}"> |
52 | - <md-button class="md-icon-button md-mini" ng-click="vm.openConfigDialog($event, $index, connector.config, connector.name)" | |
52 | + <md-button ng-disabled="vm.isReadOnly" class="md-icon-button md-mini" ng-click="vm.openConfigDialog($event, $index, connector.config, connector.name)" | |
53 | 53 | aria-label="{{ 'gateway.update-config' | translate }}" |
54 | 54 | ng-class="{'md-warn': vm.validateJSON(connector.config)}"> |
55 | 55 | <md-icon class="material-icons">more_horiz</md-icon> |
... | ... | @@ -57,7 +57,7 @@ |
57 | 57 | {{ 'gateway.update-config' | translate }} |
58 | 58 | </md-tooltip> |
59 | 59 | </md-button> |
60 | - <md-button class="md-icon-button md-mini" ng-click="vm.removeConnector($index)" | |
60 | + <md-button ng-disabled="vm.isReadOnly" class="md-icon-button md-mini" ng-click="vm.removeConnector($index)" | |
61 | 61 | aria-label="{{ 'gateway.delete' | translate }}"> |
62 | 62 | <md-icon class="material-icons">close</md-icon> |
63 | 63 | <md-tooltip md-direction="top"> |
... | ... | @@ -70,7 +70,7 @@ |
70 | 70 | layout-align="center center" ng-class="{'disabled': vm.disabled}" |
71 | 71 | class="no-data-found" translate>{{'gateway.no-connectors'}}</span> |
72 | 72 | <div> |
73 | - <md-button class="md-raised" ng-click="vm.addNewConnector()" | |
73 | + <md-button ng-show="!vm.isReadOnly" class="md-raised" ng-click="vm.addNewConnector()" | |
74 | 74 | aria-label="{{ 'gateway.connector-add' | translate }}"> |
75 | 75 | <md-tooltip md-direction="top"> |
76 | 76 | {{ 'gateway.connector-add' | translate }} | ... | ... |
... | ... | @@ -31,11 +31,15 @@ function GatewayForm() { |
31 | 31 | scope: true, |
32 | 32 | bindToController: { |
33 | 33 | formId: '=', |
34 | - ctx: '=' | |
34 | + ctx: '=', | |
35 | + isStateForm: '=', | |
36 | + deviceName: '=', | |
37 | + isReadOnly: '=', | |
38 | + isState: '=' | |
35 | 39 | }, |
36 | 40 | controller: GatewayFormController, |
37 | 41 | controllerAs: 'vm', |
38 | - templateUrl: gatewayFormTemplate | |
42 | + templateUrl: gatewayFormTemplate, | |
39 | 43 | }; |
40 | 44 | } |
41 | 45 | |
... | ... | @@ -47,10 +51,11 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel, |
47 | 51 | const configurationAttribute = "configuration"; |
48 | 52 | const remoteLoggingLevelAttribute = "RemoteLoggingLevel"; |
49 | 53 | |
50 | - const templateLogsConfig = '[loggers]}}keys=root, service, connector, converter, tb_connection, storage, extension}}[handlers]}}keys=consoleHandler, serviceHandler, connectorHandler, converterHandler, tb_connectionHandler, storageHandler, extensionHandler}}[formatters]}}keys=LogFormatter}}[logger_root]}}level=ERROR}}handlers=consoleHandler}}[logger_connector]}}level={ERROR}}}handlers=connectorHandler}}formatter=LogFormatter}}qualname=connector}}[logger_storage]}}level={ERROR}}}handlers=storageHandler}}formatter=LogFormatter}}qualname=storage}}[logger_tb_connection]}}level={ERROR}}}handlers=tb_connectionHandler}}formatter=LogFormatter}}qualname=tb_connection}}[logger_service]}}level={ERROR}}}handlers=serviceHandler}}formatter=LogFormatter}}qualname=service}}[logger_converter]}}level={ERROR}}}handlers=connectorHandler}}formatter=LogFormatter}}qualname=converter}}[logger_extension]}}level={ERROR}}}handlers=connectorHandler}}formatter=LogFormatter}}qualname=extension}}[handler_consoleHandler]}}class=StreamHandler}}level={ERROR}}}formatter=LogFormatter}}args=(sys.stdout,)}}[handler_connectorHandler]}}level={ERROR}}}class=logging.handlers.TimedRotatingFileHandler}}formatter=LogFormatter}}args=("{./logs/}connector.log", "d", 1, 7,)}}[handler_storageHandler]}}level={ERROR}}}class=logging.handlers.TimedRotatingFileHandler}}formatter=LogFormatter}}args=("{./logs/}storage.log", "d", 1, 7,)}}[handler_serviceHandler]}}level={ERROR}}}class=logging.handlers.TimedRotatingFileHandler}}formatter=LogFormatter}}args=("{./logs/}service.log", "d", 1, 7,)}}[handler_converterHandler]}}level={ERROR}}}class=logging.handlers.TimedRotatingFileHandler}}formatter=LogFormatter}}args=("{./logs/}converter.log", "d", 1, 3,)}}[handler_extensionHandler]}}level={ERROR}}}class=logging.handlers.TimedRotatingFileHandler}}formatter=LogFormatter}}args=("{./logs/}extension.log", "d", 1, 3,)}}[handler_tb_connectionHandler]}}level={ERROR}}}class=logging.handlers.TimedRotatingFileHandler}}formatter=LogFormatter}}args=("{./logs/}tb_connection.log", "d", 1, 3,)}}[formatter_LogFormatter]}}format="%(asctime)s - %(levelname)s - [%(filename)s] - %(module)s - %(lineno)d - %(message)s" }}datefmt="%Y-%m-%d %H:%M:%S"'; | |
54 | + const templateLogsConfig = '[loggers]}}keys=root, service, connector, converter, tb_connection, storage, extension}}[handlers]}}keys=consoleHandler, serviceHandler, connectorHandler, converterHandler, tb_connectionHandler, storageHandler, extensionHandler}}[formatters]}}keys=LogFormatter}}[logger_root]}}level=ERROR}}handlers=consoleHandler}}[logger_connector]}}level={ERROR}}}handlers=connectorHandler}}formatter=LogFormatter}}qualname=connector}}[logger_storage]}}level={ERROR}}}handlers=storageHandler}}formatter=LogFormatter}}qualname=storage}}[logger_tb_connection]}}level={ERROR}}}handlers=tb_connectionHandler}}formatter=LogFormatter}}qualname=tb_connection}}[logger_service]}}level={ERROR}}}handlers=serviceHandler}}formatter=LogFormatter}}qualname=service}}[logger_converter]}}level={ERROR}}}handlers=converterHandler}}formatter=LogFormatter}}qualname=converter}}[logger_extension]}}level={ERROR}}}handlers=connectorHandler}}formatter=LogFormatter}}qualname=extension}}[handler_consoleHandler]}}class=StreamHandler}}level={ERROR}}}formatter=LogFormatter}}args=(sys.stdout,)}}[handler_connectorHandler]}}level={ERROR}}}class=logging.handlers.TimedRotatingFileHandler}}formatter=LogFormatter}}args=("{./logs/}connector.log", "d", 1, 7,)}}[handler_storageHandler]}}level={ERROR}}}class=logging.handlers.TimedRotatingFileHandler}}formatter=LogFormatter}}args=("{./logs/}storage.log", "d", 1, 7,)}}[handler_serviceHandler]}}level={ERROR}}}class=logging.handlers.TimedRotatingFileHandler}}formatter=LogFormatter}}args=("{./logs/}service.log", "d", 1, 7,)}}[handler_converterHandler]}}level={ERROR}}}class=logging.handlers.TimedRotatingFileHandler}}formatter=LogFormatter}}args=("{./logs/}converter.log", "d", 1, 3,)}}[handler_extensionHandler]}}level={ERROR}}}class=logging.handlers.TimedRotatingFileHandler}}formatter=LogFormatter}}args=("{./logs/}extension.log", "d", 1, 3,)}}[handler_tb_connectionHandler]}}level={ERROR}}}class=logging.handlers.TimedRotatingFileHandler}}formatter=LogFormatter}}args=("{./logs/}tb_connection.log", "d", 1, 3,)}}[formatter_LogFormatter]}}format="%(asctime)s - %(levelname)s - [%(filename)s] - %(module)s - %(lineno)d - %(message)s" }}datefmt="%Y-%m-%d %H:%M:%S"'; | |
51 | 55 | |
52 | 56 | vm.types = types; |
53 | - | |
57 | + vm.deviceNameForm = (vm.deviceName) ? vm.deviceName : null; | |
58 | + vm.idForm = Math.random().toString(36).replace(/^0\.[0-9]*/, ''); | |
54 | 59 | vm.configurations = { |
55 | 60 | gateway: '', |
56 | 61 | host: $document[0].domain, |
... | ... | @@ -74,7 +79,6 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel, |
74 | 79 | let archiveFileName = ''; |
75 | 80 | let gatewayNameExists = ''; |
76 | 81 | let successfulSaved = ''; |
77 | - | |
78 | 82 | vm.securityTypes = [{ |
79 | 83 | name: 'gateway.security-types.access-token', |
80 | 84 | value: 'accessToken' |
... | ... | @@ -92,13 +96,18 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel, |
92 | 96 | }]; |
93 | 97 | |
94 | 98 | $scope.$watch('vm.ctx', function () { |
95 | - if (vm.ctx ) { | |
99 | + if (vm.ctx) { | |
100 | + vm.isStateForm = $scope.isStateForm; | |
96 | 101 | vm.settings = vm.ctx.settings; |
97 | 102 | vm.widgetConfig = vm.ctx.widgetConfig; |
98 | - initializeConfig(); | |
103 | + if (vm.ctx.datasources && vm.ctx.datasources.length) { | |
104 | + vm.deviceNameForm = vm.ctx.datasources[0].name; | |
105 | + } | |
99 | 106 | } |
107 | + initializeConfig(); | |
100 | 108 | }); |
101 | 109 | |
110 | + | |
102 | 111 | $scope.$on('gateway-form-resize', function (event, formId) { |
103 | 112 | if (vm.formId == formId) { |
104 | 113 | updateWidgetDisplaying(); |
... | ... | @@ -106,21 +115,34 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel, |
106 | 115 | }); |
107 | 116 | |
108 | 117 | function updateWidgetDisplaying() { |
109 | - vm.changeAlignment = (vm.ctx.$container[0].offsetWidth <= 425); | |
118 | + if (vm.ctx) { | |
119 | + vm.changeAlignment = (vm.ctx.$container[0].offsetWidth <= 425); | |
120 | + } | |
110 | 121 | } |
111 | 122 | |
112 | 123 | function initWidgetSettings() { |
113 | 124 | let widgetTitle; |
114 | - if (vm.settings.widgetTitle && vm.settings.widgetTitle.length) { | |
115 | - widgetTitle = utils.customTranslation(vm.settings.widgetTitle, vm.settings.widgetTitle); | |
125 | + if (vm.settings) { | |
126 | + vm.isReadOnlyForm = (vm.settings.readOnly) ? vm.settings.readOnly : false; | |
127 | + if (vm.settings.gatewayTitle && vm.settings.gatewayTitle.length) { | |
128 | + widgetTitle = utils.customTranslation(vm.settings.gatewayTitle, vm.settings.gatewayTitle); | |
129 | + } | |
116 | 130 | } else { |
131 | + vm.isReadOnlyForm = false; | |
117 | 132 | widgetTitle = $translate.instant('gateway.gateway'); |
118 | 133 | } |
119 | - vm.ctx.widgetTitle = widgetTitle; | |
134 | + if (vm.ctx) { | |
135 | + vm.ctx.widgetTitle = widgetTitle; | |
136 | + } | |
120 | 137 | |
121 | - archiveFileName = vm.settings.archiveFileName && vm.settings.archiveFileName.length ? vm.settings.archiveFileName : 'gatewayConfiguration'; | |
122 | - gatewayNameExists = utils.customTranslation(vm.settings.gatewayNameExists, vm.settings.gatewayNameExists) || $translate.instant('gateway.gateway-exists'); | |
123 | - successfulSaved = utils.customTranslation(vm.settings.successfulSave, vm.settings.successfulSave) || $translate.instant('gateway.gateway-saved'); | |
138 | + archiveFileName = vm.settings && vm.settings.archiveFileName && vm.settings.archiveFileName.length ? vm.settings.archiveFileName : 'gatewayConfiguration'; | |
139 | + if (vm.settings) { | |
140 | + gatewayNameExists = utils.customTranslation(vm.settings.deviceNameExist, vm.settings.deviceNameExist) || $translate.instant('gateway.gateway-exists'); | |
141 | + successfulSaved = utils.customTranslation(vm.settings.successfulSave, vm.settings.successfulSave) || $translate.instant('gateway.gateway-saved'); | |
142 | + } else { | |
143 | + gatewayNameExists = $translate.instant('gateway.gateway-exists'); | |
144 | + successfulSaved = $translate.instant('gateway.gateway-saved'); | |
145 | + } | |
124 | 146 | } |
125 | 147 | |
126 | 148 | function initializeConfig() { |
... | ... | @@ -129,6 +151,7 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel, |
129 | 151 | getGatewaysList(true); |
130 | 152 | } |
131 | 153 | |
154 | + | |
132 | 155 | vm.getAccessToken = (deviceId) => { |
133 | 156 | if (deviceId.id) { |
134 | 157 | getDeviceCredentials(deviceId.id); |
... | ... | @@ -152,15 +175,15 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel, |
152 | 175 | deviceService.findByName(deviceObj.name, {ignoreErrors: true}) |
153 | 176 | .then( |
154 | 177 | function () { |
155 | - toast.showError(gatewayNameExists, angular.element('.gateway-form'),'top left'); | |
178 | + toast.showError(gatewayNameExists, angular.element('.gateway-form'), 'top left'); | |
156 | 179 | }, |
157 | 180 | function () { |
158 | - if(vm.settings.gatewayType && vm.settings.gatewayType.length){ | |
181 | + if (vm.settings.gatewayType && vm.settings.gatewayType.length) { | |
159 | 182 | deviceObj.type = vm.settings.gatewayType; |
160 | 183 | } |
161 | 184 | deviceService.saveDevice(deviceObj).then( |
162 | 185 | (device) => { |
163 | - getDeviceCredentials(device.id.id).then(() =>{ | |
186 | + getDeviceCredentials(device.id.id).then(() => { | |
164 | 187 | getGatewaysList(); |
165 | 188 | }); |
166 | 189 | } |
... | ... | @@ -173,8 +196,8 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel, |
173 | 196 | saveAttribute(configurationAttribute, $window.btoa(angular.toJson(getGatewayConfigJSON())), types.attributesScope.shared.value), |
174 | 197 | saveAttribute(configurationDraftsAttribute, $window.btoa(angular.toJson(getDraftConnectorJSON())), types.attributesScope.server.value), |
175 | 198 | saveAttribute(remoteLoggingLevelAttribute, vm.configurations.remoteLoggingLevel.toUpperCase(), types.attributesScope.shared.value) |
176 | - ]).then(() =>{ | |
177 | - toast.showSuccess(successfulSaved, 2000, angular.element('.gateway-form'),'top left'); | |
199 | + ]).then(() => { | |
200 | + toast.showSuccess(successfulSaved, 2000, angular.element('.gateway-form'), 'top left'); | |
178 | 201 | }) |
179 | 202 | }; |
180 | 203 | |
... | ... | @@ -238,7 +261,7 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel, |
238 | 261 | config += ' max_records_per_file: ' + vm.configurations.maxRecordsCount + '\n'; |
239 | 262 | } |
240 | 263 | config += 'connectors:\n'; |
241 | - for(let i = 0; i < vm.configurations.connectors.length; i++){ | |
264 | + for (let i = 0; i < vm.configurations.connectors.length; i++) { | |
242 | 265 | if (vm.configurations.connectors[i].enabled) { |
243 | 266 | config += ' -\n'; |
244 | 267 | config += ' name: ' + vm.configurations.connectors[i].name + '\n'; |
... | ... | @@ -250,7 +273,7 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel, |
250 | 273 | } |
251 | 274 | |
252 | 275 | function generateConfigConnectorFiles(fileZipAdd) { |
253 | - for(let i = 0; i < vm.configurations.connectors.length; i++){ | |
276 | + for (let i = 0; i < vm.configurations.connectors.length; i++) { | |
254 | 277 | if (vm.configurations.connectors[i].enabled) { |
255 | 278 | fileZipAdd[generateFileName(vm.configurations.connectors[i].name)] = angular.toJson(vm.configurations.connectors[i].config); |
256 | 279 | } |
... | ... | @@ -276,7 +299,7 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel, |
276 | 299 | |
277 | 300 | function gatewayMainConfigJSON() { |
278 | 301 | let configuration = {}; |
279 | - | |
302 | + | |
280 | 303 | let thingsBoard = {}; |
281 | 304 | thingsBoard.host = vm.configurations.host; |
282 | 305 | thingsBoard.remoteConfiguration = vm.configurations.remoteConfiguration; |
... | ... | @@ -325,10 +348,10 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel, |
325 | 348 | } |
326 | 349 | |
327 | 350 | function gatewayConnectorConfigJSON(gatewayConfiguration) { |
328 | - for(let i = 0; i < vm.configurations.connectors.length; i++){ | |
351 | + for (let i = 0; i < vm.configurations.connectors.length; i++) { | |
329 | 352 | if (vm.configurations.connectors[i].enabled) { |
330 | 353 | let typeConnector = vm.configurations.connectors[i].configType; |
331 | - if(!angular.isArray(gatewayConfiguration[typeConnector])){ | |
354 | + if (!angular.isArray(gatewayConfiguration[typeConnector])) { | |
332 | 355 | gatewayConfiguration[typeConnector] = []; |
333 | 356 | } |
334 | 357 | |
... | ... | @@ -343,7 +366,7 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel, |
343 | 366 | |
344 | 367 | function getDraftConnectorJSON() { |
345 | 368 | let draftConnector = {}; |
346 | - for(let i = 0; i < vm.configurations.connectors.length; i++){ | |
369 | + for (let i = 0; i < vm.configurations.connectors.length; i++) { | |
347 | 370 | if (!vm.configurations.connectors[i].enabled) { |
348 | 371 | let connector = { |
349 | 372 | connector: vm.configurations.connectors[i].configType, |
... | ... | @@ -362,7 +385,10 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel, |
362 | 385 | const device = devices[i]; |
363 | 386 | if (device.additionalInfo !== null && device.additionalInfo.gateway === true) { |
364 | 387 | vm.gateways.push(device); |
365 | - if (firstInit && vm.gateways.length && device.name === vm.gateways[0].name) { | |
388 | + if (vm.deviceNameForm && firstInit && vm.gateways.length && device.name === vm.deviceNameForm) { | |
389 | + vm.configurations.gateway = device; | |
390 | + vm.getAccessToken(device.id); | |
391 | + } else if (firstInit && vm.gateways.length && device.name === vm.gateways[0].name) { | |
366 | 392 | vm.configurations.gateway = device; |
367 | 393 | vm.getAccessToken(device.id); |
368 | 394 | } |
... | ... | @@ -385,7 +411,7 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel, |
385 | 411 | for (let connectorType in keyValue) { |
386 | 412 | let name = "No name"; |
387 | 413 | if (Object.prototype.hasOwnProperty.call(keyValue[connectorType], 'name')) { |
388 | - name = keyValue[connectorType].name ; | |
414 | + name = keyValue[connectorType].name; | |
389 | 415 | } |
390 | 416 | let connector = { |
391 | 417 | enabled: true, | ... | ... |
... | ... | @@ -17,30 +17,36 @@ |
17 | 17 | --> |
18 | 18 | <md-content md-scroll-y layout="column" class="gateway-form"> |
19 | 19 | <form name="gatewayConfiguration"> |
20 | - <md-expansion-panel-group> | |
21 | - <md-expansion-panel md-component-id="thingsboardPanelId"> | |
20 | + <md-expansion-panel-group> | |
21 | + <md-expansion-panel md-component-id="{{vm.idForm}}thingsboardPanelId"> | |
22 | 22 | <md-expansion-panel-collapsed> |
23 | 23 | <div class="tb-panel-title">{{ 'gateway.thingsboard' | translate | uppercase }}</div> |
24 | 24 | <span flex></span> |
25 | 25 | <md-expansion-panel-icon></md-expansion-panel-icon> |
26 | 26 | </md-expansion-panel-collapsed> |
27 | 27 | <md-expansion-panel-expanded> |
28 | - <md-expansion-panel-header ng-click="vm.collapsePanel('thingsboardPanelId')"> | |
28 | + <md-expansion-panel-header ng-click="vm.collapsePanel(vm.idForm + 'thingsboardPanelId')"> | |
29 | 29 | <div class="tb-panel-title">{{ 'gateway.thingsboard' | translate | uppercase }}</div> |
30 | 30 | <span flex></span> |
31 | 31 | <md-expansion-panel-icon></md-expansion-panel-icon> |
32 | 32 | </md-expansion-panel-header> |
33 | 33 | <md-expansion-panel-content> |
34 | - <tb-gateway-config-select tb-required="true" | |
34 | + <tb-gateway-config-select ng-if="!vm.isStateForm" | |
35 | + tb-required="true" | |
35 | 36 | ng-model="vm.configurations.gateway" |
36 | 37 | the-form="gatewayConfiguration" |
37 | 38 | gateway-list="vm.gateways" |
38 | 39 | get_access_token="vm.getAccessToken" |
39 | 40 | create-device="vm.createDevice"> |
40 | 41 | </tb-gateway-config-select> |
42 | + <md-input-container ng-if="vm.isStateForm" | |
43 | + class="md-block"> | |
44 | + <label>{{'gateway.gateway-name' | translate }}</label> | |
45 | + <input ng-disabled="true" type="text" ng-model="vm.configurations.gateway.name" name="gatewayName"/> | |
46 | + </md-input-container> | |
41 | 47 | <md-input-container class="md-block"> |
42 | 48 | <label>{{'gateway.security-type' | translate }}</label> |
43 | - <md-select name="securityType" ng-model="vm.configurations.securityType" required> | |
49 | + <md-select ng-disabled="vm.isReadOnlyForm" name="securityType" ng-model="vm.configurations.securityType" required> | |
44 | 50 | <md-option ng-repeat="securityType in vm.securityTypes" ng-value="securityType.value"> |
45 | 51 | {{securityType.name | translate}} |
46 | 52 | </md-option> |
... | ... | @@ -50,14 +56,14 @@ |
50 | 56 | ng-class="{'gateway-config-row-vertical': vm.changeAlignment}"> |
51 | 57 | <md-input-container class="md-block" flex> |
52 | 58 | <label>{{ 'gateway.thingsboard-host' | translate }}</label> |
53 | - <input type="text" name="host" ng-model="vm.configurations.host" required> | |
59 | + <input ng-disabled="vm.isReadOnlyForm" type="text" name="host" ng-model="vm.configurations.host" required> | |
54 | 60 | <div ng-messages="gatewayConfiguration.host.$error"> |
55 | 61 | <div ng-message="required" translate>gateway.thingsboard-host-required</div> |
56 | 62 | </div> |
57 | 63 | </md-input-container> |
58 | 64 | <md-input-container class="md-block" flex> |
59 | 65 | <label>{{ 'gateway.thingsboard-port' | translate }}</label> |
60 | - <input type="number" min="1" max="65535" ng-pattern="/^-?[0-9]+$/" name="port" | |
66 | + <input ng-disabled="vm.isReadOnlyForm" type="number" min="1" max="65535" ng-pattern="/^-?[0-9]+$/" name="port" | |
61 | 67 | ng-model="vm.configurations.port" required> |
62 | 68 | <div ng-messages="gatewayConfiguration.port.$error"> |
63 | 69 | <div ng-message="required" translate>gateway.thingsboard-port-required</div> |
... | ... | @@ -70,18 +76,18 @@ |
70 | 76 | <div ng-if="vm.configurations.securityType=='tls'"> |
71 | 77 | <md-input-container class="md-block security-type"> |
72 | 78 | <label>{{'gateway.tls-path-ca-certificate' | translate }}</label> |
73 | - <input type="text" ng-model="vm.configurations.caCertPath" name="caCertPath" /> | |
79 | + <input ng-disabled="vm.isReadOnlyForm" type="text" ng-model="vm.configurations.caCertPath" name="caCertPath"/> | |
74 | 80 | </md-input-container> |
75 | 81 | <md-input-container class="md-block"> |
76 | 82 | <label>{{'gateway.tls-path-private-key' | translate }}</label> |
77 | - <input type="text" ng-model="vm.configurations.privateKeyPath" name="privateKeyPath" /> | |
83 | + <input ng-disabled="vm.isReadOnlyForm" type="text" ng-model="vm.configurations.privateKeyPath" name="privateKeyPath"/> | |
78 | 84 | </md-input-container> |
79 | 85 | <md-input-container class="md-block"> |
80 | 86 | <label>{{'gateway.tls-path-client-certificate' | translate }}</label> |
81 | - <input type="text" ng-model="vm.configurations.certPath" name="certPath" /> | |
87 | + <input ng-disabled="vm.isReadOnlyForm" type="text" ng-model="vm.configurations.certPath" name="certPath"/> | |
82 | 88 | </md-input-container> |
83 | 89 | </div> |
84 | - <md-checkbox ng-model="vm.configurations.remoteConfiguration" | |
90 | + <md-checkbox ng-show="!vm.isReadOnlyForm" ng-model="vm.configurations.remoteConfiguration" | |
85 | 91 | name="remoteConfiguration" |
86 | 92 | aria-label="{{ 'gateway.remote-remote' | translate }}"> |
87 | 93 | {{ 'gateway.remote' | translate }} |
... | ... | @@ -90,7 +96,7 @@ |
90 | 96 | ng-class="{'gateway-config-row-vertical': vm.changeAlignment}"> |
91 | 97 | <md-input-container class="md-block md-select-container" flex> |
92 | 98 | <label>{{'gateway.remote-logging-level' | translate }}</label> |
93 | - <md-select name="loggingLevel" ng-model="vm.configurations.remoteLoggingLevel"> | |
99 | + <md-select ng-disabled="vm.isReadOnlyForm" name="loggingLevel" ng-model="vm.configurations.remoteLoggingLevel"> | |
94 | 100 | <md-option ng-repeat="logLevel in vm.types.gatewayLogLevel" |
95 | 101 | ng-value="logLevel" ng-selected="$index === 5"> |
96 | 102 | {{logLevel}} |
... | ... | @@ -99,7 +105,7 @@ |
99 | 105 | </md-input-container> |
100 | 106 | <md-input-container class="md-block" flex> |
101 | 107 | <label>{{'gateway.path-logs' | translate }}</label> |
102 | - <input type="text" ng-model="vm.configurations.remoteLoggingPathToLogs" | |
108 | + <input ng-disabled="vm.isReadOnlyForm" type="text" ng-model="vm.configurations.remoteLoggingPathToLogs" | |
103 | 109 | name="remoteLoggingPathToLogs" required> |
104 | 110 | <div ng-messages="gatewayConfiguration.remoteLoggingPathToLogs.$error"> |
105 | 111 | <div ng-message="required" translate>gateway.path-logs-required</div> |
... | ... | @@ -109,14 +115,14 @@ |
109 | 115 | </md-expansion-panel-content> |
110 | 116 | </md-expansion-panel-expanded> |
111 | 117 | </md-expansion-panel> |
112 | - <md-expansion-panel md-component-id="storagePanelId"> | |
118 | + <md-expansion-panel md-component-id="{{vm.idForm}}storagePanelId"> | |
113 | 119 | <md-expansion-panel-collapsed> |
114 | 120 | <div class="tb-panel-title">{{ 'gateway.storage' | translate | uppercase }}</div> |
115 | 121 | <span flex></span> |
116 | 122 | <md-expansion-panel-icon></md-expansion-panel-icon> |
117 | 123 | </md-expansion-panel-collapsed> |
118 | 124 | <md-expansion-panel-expanded> |
119 | - <md-expansion-panel-header ng-click="vm.collapsePanel('storagePanelId')"> | |
125 | + <md-expansion-panel-header ng-click="vm.collapsePanel(vm.idForm + 'storagePanelId')"> | |
120 | 126 | <div class="tb-panel-title">{{ 'gateway.storage' | translate | uppercase }}</div> |
121 | 127 | <span flex></span> |
122 | 128 | <md-expansion-panel-icon></md-expansion-panel-icon> |
... | ... | @@ -124,18 +130,17 @@ |
124 | 130 | <md-expansion-panel-content> |
125 | 131 | <md-input-container class="md-block" flex> |
126 | 132 | <label>{{'gateway.storage-type' | translate }}</label> |
127 | - <md-select required ng-model="vm.configurations.storageType"> | |
133 | + <md-select ng-disabled="vm.isReadOnlyForm" required ng-model="vm.configurations.storageType"> | |
128 | 134 | <md-option ng-repeat="storageType in vm.storageTypes" ng-value="storageType.value"> |
129 | 135 | {{storageType.name | translate}} |
130 | 136 | </md-option> |
131 | 137 | </md-select> |
132 | 138 | </md-input-container> |
133 | - | |
134 | 139 | <div layout="row" class="gateway-form-row" |
135 | 140 | ng-class="{'gateway-config-row-vertical': vm.changeAlignment}"> |
136 | 141 | <md-input-container class="md-block" flex> |
137 | 142 | <label>{{'gateway.storage-pack-size' | translate }}</label> |
138 | - <input type="number" min="1" name="readRecordsCount" ng-pattern="/^-?[0-9]+$/" | |
143 | + <input ng-disabled="vm.isReadOnlyForm" type="number" min="1" name="readRecordsCount" ng-pattern="/^-?[0-9]+$/" | |
139 | 144 | ng-model='vm.configurations.readRecordsCount' required/> |
140 | 145 | <div ng-messages="gatewayConfiguration.readRecordsCount.$error"> |
141 | 146 | <div ng-message="required" translate>gateway.storage-pack-size-required</div> |
... | ... | @@ -143,10 +148,9 @@ |
143 | 148 | <div ng-message="pattern" translate>gateway.storage-pack-size-pattern</div> |
144 | 149 | </div> |
145 | 150 | </md-input-container> |
146 | - | |
147 | 151 | <md-input-container class="md-block" flex> |
148 | 152 | <label translate>{{ vm.configurations.storageType !== 'fileStorage' ? 'gateway.storage-max-records' : 'gateway.storage-max-file-records' }}</label> |
149 | - <input type="number" min="1" name="maxRecordsCount" ng-pattern="/^-?[0-9]+$/" | |
153 | + <input ng-disabled="vm.isReadOnlyForm" type="number" min="1" name="maxRecordsCount" ng-pattern="/^-?[0-9]+$/" | |
150 | 154 | ng-model='vm.configurations.maxRecordsCount' required/> |
151 | 155 | <div ng-messages="gatewayConfiguration.maxRecordsCount.$error"> |
152 | 156 | <div ng-message="required" translate>gateway.storage-max-records-required</div> |
... | ... | @@ -155,13 +159,12 @@ |
155 | 159 | </div> |
156 | 160 | </md-input-container> |
157 | 161 | </div> |
158 | - | |
159 | 162 | <div layout="row" class="gateway-form-row" |
160 | 163 | ng-if="vm.configurations.storageType == 'fileStorage'" |
161 | 164 | ng-class="{'gateway-config-row-vertical': vm.changeAlignment}"> |
162 | 165 | <md-input-container class="md-block" flex> |
163 | 166 | <label>{{'gateway.storage-max-files' | translate }}</label> |
164 | - <input type="number" min="1" name="maxFilesCount" ng-pattern="/^-?[0-9]+$/" | |
167 | + <input ng-disabled="vm.isReadOnlyForm" type="number" min="1" name="maxFilesCount" ng-pattern="/^-?[0-9]+$/" | |
165 | 168 | ng-model='vm.configurations.maxFilesCount' required/> |
166 | 169 | <div ng-messages="gatewayConfiguration.maxFilesCount.$error"> |
167 | 170 | <div ng-message="required" translate>gateway.storage-max-files-required</div> |
... | ... | @@ -169,10 +172,9 @@ |
169 | 172 | <div ng-message="pattern" translate>gateway.storage-max-files-pattern</div> |
170 | 173 | </div> |
171 | 174 | </md-input-container> |
172 | - | |
173 | 175 | <md-input-container class="md-block" flex> |
174 | 176 | <label>{{'gateway.storage-path' | translate }}</label> |
175 | - <input type="text" name="dataFolderPath" ng-model='vm.configurations.dataFolderPath' | |
177 | + <input ng-disabled="vm.isReadOnlyForm" type="text" name="dataFolderPath" ng-model='vm.configurations.dataFolderPath' | |
176 | 178 | required/> |
177 | 179 | <div ng-messages="gatewayConfiguration.dataFolderPath.$error"> |
178 | 180 | <div ng-message="required" translate>gateway.storage-path-required</div> |
... | ... | @@ -182,14 +184,14 @@ |
182 | 184 | </md-expansion-panel-content> |
183 | 185 | </md-expansion-panel-expanded> |
184 | 186 | </md-expansion-panel> |
185 | - <md-expansion-panel md-component-id="connectorsPanelId"> | |
187 | + <md-expansion-panel md-component-id="{{vm.idForm}}connectorsPanelId"> | |
186 | 188 | <md-expansion-panel-collapsed> |
187 | 189 | <div class="tb-panel-title">{{ 'gateway.connectors' | translate | uppercase }}</div> |
188 | 190 | <span flex></span> |
189 | 191 | <md-expansion-panel-icon></md-expansion-panel-icon> |
190 | 192 | </md-expansion-panel-collapsed> |
191 | 193 | <md-expansion-panel-expanded> |
192 | - <md-expansion-panel-header ng-click="vm.collapsePanel('connectorsPanelId')"> | |
194 | + <md-expansion-panel-header ng-click="vm.collapsePanel(vm.idForm + 'connectorsPanelId')"> | |
193 | 195 | <div class="tb-panel-title">{{ 'gateway.connectors' | translate | uppercase }}</div> |
194 | 196 | <span flex></span> |
195 | 197 | <md-expansion-panel-icon></md-expansion-panel-icon> |
... | ... | @@ -198,13 +200,14 @@ |
198 | 200 | <tb-gateway-config |
199 | 201 | gateway-config="vm.configurations.connectors" |
200 | 202 | the-form="gatewayConfiguration" |
201 | - change-alignment="vm.changeAlignment"> | |
203 | + change-alignment="vm.changeAlignment" | |
204 | + is-read-only="vm.isReadOnlyForm"> | |
202 | 205 | </tb-gateway-config> |
203 | 206 | </md-expansion-panel-content> |
204 | 207 | </md-expansion-panel-expanded> |
205 | 208 | </md-expansion-panel> |
206 | 209 | </md-expansion-panel-group> |
207 | - <section layout="row" layout-align="end center" class="form-action-buttons"> | |
210 | + <section ng-show="!vm.isReadOnlyForm" layout="row" layout-align="end center" class="form-action-buttons"> | |
208 | 211 | <md-button class="md-primary md-raised" |
209 | 212 | ng-click="vm.exportConfig()" |
210 | 213 | ng-if="!vm.configurations.remoteConfiguration" |
... | ... | @@ -213,14 +216,14 @@ |
213 | 216 | {{'action.download' | translate }} |
214 | 217 | <md-tooltip>{{'gateway.download-tip' | translate }}</md-tooltip> |
215 | 218 | </md-button> |
216 | - | |
217 | 219 | <md-button class="md-primary md-raised" |
218 | 220 | ng-click="vm.saveAttributeConfig()" |
219 | 221 | ng-if="vm.configurations.remoteConfiguration" |
220 | 222 | ng-disabled="gatewayConfiguration.$invalid || !gatewayConfiguration.$dirty" |
221 | 223 | aria-label="{{ 'gateway.save-tip' | translate }}"> |
222 | 224 | {{'action.save' | translate }} |
223 | - <md-tooltip ng-if="vm.configurations.remoteConfiguration">{{'gateway.save-tip' | translate }}</md-tooltip> | |
225 | + <md-tooltip ng-if="vm.configurations.remoteConfiguration">{{'gateway.save-tip' | translate }} | |
226 | + </md-tooltip> | |
224 | 227 | </md-button> |
225 | 228 | </section> |
226 | 229 | </form> | ... | ... |
... | ... | @@ -1201,7 +1201,12 @@ |
1201 | 1201 | "tls-path-private-key": "Path to private key on gateway", |
1202 | 1202 | "toggle-fullscreen": "Toggle fullscreen", |
1203 | 1203 | "transformer-json-config": "Configuration JSON*", |
1204 | - "update-config": "Add/update configuration JSON" | |
1204 | + "update-config": "Add/update configuration JSON", | |
1205 | + "state-title": "Gateway state", | |
1206 | + "show-config-tip": "Show gateway configuration", | |
1207 | + "title-show-config": "Show gateway configuration", | |
1208 | + "read-only": "Read only", | |
1209 | + "read-write": "" | |
1205 | 1210 | }, |
1206 | 1211 | "grid": { |
1207 | 1212 | "delete-item-title": "Are you sure you want to delete this item?", | ... | ... |