Browse Source

new widget for gateway with the last telemetry type

pull/2627/head
nick 7 years ago
parent
commit
6c15874dde
  1. 1
      ui/src/app/components/gateway/gateway-config-select.directive.js
  2. 3
      ui/src/app/components/gateway/gateway-config.directive.js
  3. 12
      ui/src/app/components/gateway/gateway-config.tpl.html
  4. 79
      ui/src/app/components/gateway/gateway-form.directive.js
  5. 63
      ui/src/app/components/gateway/gateway-form.tpl.html
  6. 18
      ui/src/app/components/gateway/state-gateway-dialog.scss
  7. 52
      ui/src/app/components/gateway/state-gateway-dialog.tpl.html
  8. 149
      ui/src/app/components/gateway/state-gateway-form.directive.js
  9. 18
      ui/src/app/components/gateway/state-gateway-form.scss
  10. 28
      ui/src/app/components/gateway/state-gateway-form.tpl.html
  11. 2
      ui/src/app/layout/index.js
  12. 7
      ui/src/app/locale/locale.constant-en_US.json

1
ui/src/app/components/gateway/gateway-config-select.directive.js

@ -48,6 +48,7 @@ function GatewayConfigSelect($compile, $templateCache, $mdConstant, $translate,
function startWatchers() {
scope.$watch('gateway', function (newVal, prevVal) {
if (!angular.equals(newVal, prevVal) && newVal !== null) {
console.log("select startWatchers", "newVal", newVal, "prevVal", prevVal); //eslint-disable-line
scope.updateView();
}
});

3
ui/src/app/components/gateway/gateway-config.directive.js

@ -37,7 +37,8 @@ function GatewayConfig() {
disabled: '=ngDisabled',
gatewayConfig: '=',
changeAlignment: '=',
theForm: '='
theForm: '=',
isReadOnly: '='
},
controller: GatewayConfigController,
controllerAs: 'vm',

12
ui/src/app/components/gateway/gateway-config.tpl.html

@ -18,7 +18,7 @@
<section name="gatewayConfig" layout="column" class="gateway-config">
<section layout="row" ng-form="gatewayConfig_{{$index}}" ng-repeat="connector in vm.gatewayConfig track by $index">
<div layout="column" layout-align="center start" class="gateway-config-row">
<md-switch ng-model="connector.enabled" ng-disabled="gatewayConfig_{{$index}}.$invalid || vm.validateJSON(connector.config)"
<md-switch ng-disabled="vm.isReadOnly" ng-model="connector.enabled" ng-disabled="gatewayConfig_{{$index}}.$invalid || vm.validateJSON(connector.config)"
aria-label="{{ 'gateway.connector-enabled' | translate }}">
</md-switch>
</div>
@ -26,7 +26,7 @@
ng-class="{'gateway-config-row-vertical': vm.changeAlignment}">
<md-input-container class="md-block" flex>
<label>{{'gateway.connector-type' | translate }}</label>
<md-select name="connectorType"
<md-select ng-disabled="vm.isReadOnly" name="connectorType"
ng-change="vm.changeConnectorType(connector)"
aria-label="{{ 'gateway.gateway.connector-type' | translate }}"
ng-model="connector.configType" required>
@ -39,7 +39,7 @@
</div>
</md-input-container>
<md-input-container class="md-block" flex>
<input placeholder="{{'gateway.connector-name' | translate }}"
<input ng-disabled="vm.isReadOnly" placeholder="{{'gateway.connector-name' | translate }}"
ng-model-options="{ updateOn: 'blur' }"
ng-change="vm.changeConnectorName(connector, $index)" name="connectorName" ng-model="connector.name" required/>
<div ng-messages="vm.theForm.connectorName.$error">
@ -49,7 +49,7 @@
</div>
<div layout="row" layout-align="end center" class="action-buttons"
ng-class="{'gateway-config-row-vertical': vm.changeAlignment}">
<md-button class="md-icon-button md-mini" ng-click="vm.openConfigDialog($event, $index, connector.config, connector.name)"
<md-button ng-disabled="vm.isReadOnly" class="md-icon-button md-mini" ng-click="vm.openConfigDialog($event, $index, connector.config, connector.name)"
aria-label="{{ 'gateway.update-config' | translate }}"
ng-class="{'md-warn': vm.validateJSON(connector.config)}">
<md-icon class="material-icons">more_horiz</md-icon>
@ -57,7 +57,7 @@
{{ 'gateway.update-config' | translate }}
</md-tooltip>
</md-button>
<md-button class="md-icon-button md-mini" ng-click="vm.removeConnector($index)"
<md-button ng-disabled="vm.isReadOnly" class="md-icon-button md-mini" ng-click="vm.removeConnector($index)"
aria-label="{{ 'gateway.delete' | translate }}">
<md-icon class="material-icons">close</md-icon>
<md-tooltip md-direction="top">
@ -70,7 +70,7 @@
layout-align="center center" ng-class="{'disabled': vm.disabled}"
class="no-data-found" translate>{{'gateway.no-connectors'}}</span>
<div>
<md-button class="md-raised" ng-click="vm.addNewConnector()"
<md-button ng-show="!vm.isReadOnly" class="md-raised" ng-click="vm.addNewConnector()"
aria-label="{{ 'gateway.connector-add' | translate }}">
<md-tooltip md-direction="top">
{{ 'gateway.connector-add' | translate }}

79
ui/src/app/components/gateway/gateway-form.directive.js

@ -31,11 +31,14 @@ function GatewayForm() {
scope: true,
bindToController: {
formId: '=',
ctx: '='
ctx: '=',
deviceName: '=',
isReadOnly: '=',
isState: '='
},
controller: GatewayFormController,
controllerAs: 'vm',
templateUrl: gatewayFormTemplate
templateUrl: gatewayFormTemplate,
};
}
@ -50,7 +53,11 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel,
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"';
vm.types = types;
vm.deviceNameForm = (vm.deviceName) ? vm.deviceName : null;
// vm.isReadOnlyForm = (vm.isReadOnly) ? vm.isReadOnly : false;
// vm.isStateForm = (vm.isState) ? vm.isState : false;
vm.isStateForm = true;
vm.idForm = Math.random().toString(36).replace(/^0\.[0-9]*/, '');
vm.configurations = {
gateway: '',
host: $document[0].domain,
@ -92,13 +99,17 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel,
}];
$scope.$watch('vm.ctx', function () {
if (vm.ctx ) {
if (vm.ctx) {
vm.settings = vm.ctx.settings;
vm.widgetConfig = vm.ctx.widgetConfig;
initializeConfig();
if (vm.ctx.datasources && vm.ctx.datasources.length) {
vm.deviceNameForm = vm.ctx.datasources[0].name;
}
}
initializeConfig();
});
$scope.$on('gateway-form-resize', function (event, formId) {
if (vm.formId == formId) {
updateWidgetDisplaying();
@ -106,21 +117,34 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel,
});
function updateWidgetDisplaying() {
vm.changeAlignment = (vm.ctx.$container[0].offsetWidth <= 425);
if (vm.ctx) {
vm.changeAlignment = (vm.ctx.$container[0].offsetWidth <= 425);
}
}
function initWidgetSettings() {
let widgetTitle;
if (vm.settings.widgetTitle && vm.settings.widgetTitle.length) {
widgetTitle = utils.customTranslation(vm.settings.widgetTitle, vm.settings.widgetTitle);
if (vm.settings) {
vm.isReadOnlyForm = (vm.settings.readOnly) ? vm.settings.readOnly : false;
if (vm.settings.gatewayTitle && vm.settings.gatewayTitle.length) {
widgetTitle = utils.customTranslation(vm.settings.gatewayTitle, vm.settings.gatewayTitle);
}
} else {
vm.isReadOnlyForm = false;
widgetTitle = $translate.instant('gateway.gateway');
}
vm.ctx.widgetTitle = widgetTitle;
if (vm.ctx) {
vm.ctx.widgetTitle = widgetTitle;
}
archiveFileName = vm.settings.archiveFileName && vm.settings.archiveFileName.length ? vm.settings.archiveFileName : 'gatewayConfiguration';
gatewayNameExists = utils.customTranslation(vm.settings.deviceNameExist, vm.settings.deviceNameExist) || $translate.instant('gateway.gateway-exists');
successfulSaved = utils.customTranslation(vm.settings.successfulSave, vm.settings.successfulSave) || $translate.instant('gateway.gateway-saved');
archiveFileName = vm.settings && vm.settings.archiveFileName && vm.settings.archiveFileName.length ? vm.settings.archiveFileName : 'gatewayConfiguration';
if (vm.settings) {
gatewayNameExists = utils.customTranslation(vm.settings.deviceNameExist, vm.settings.deviceNameExist) || $translate.instant('gateway.gateway-exists');
successfulSaved = utils.customTranslation(vm.settings.successfulSave, vm.settings.successfulSave) || $translate.instant('gateway.gateway-saved');
} else {
gatewayNameExists = $translate.instant('gateway.gateway-exists');
successfulSaved = $translate.instant('gateway.gateway-saved');
}
}
function initializeConfig() {
@ -129,6 +153,7 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel,
getGatewaysList(true);
}
vm.getAccessToken = (deviceId) => {
if (deviceId.id) {
getDeviceCredentials(deviceId.id);
@ -149,18 +174,19 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel,
}
vm.createDevice = (deviceObj) => {
// console.log("vm.createDevice deviceObj", deviceObj); //eslint-disable-line
deviceService.findByName(deviceObj.name, {ignoreErrors: true})
.then(
function () {
toast.showError(gatewayNameExists, angular.element('.gateway-form'),'top left');
toast.showError(gatewayNameExists, angular.element('.gateway-form'), 'top left');
},
function () {
if(vm.settings.gatewayType && vm.settings.gatewayType.length){
if (vm.settings.gatewayType && vm.settings.gatewayType.length) {
deviceObj.type = vm.settings.gatewayType;
}
deviceService.saveDevice(deviceObj).then(
(device) => {
getDeviceCredentials(device.id.id).then(() =>{
getDeviceCredentials(device.id.id).then(() => {
getGatewaysList();
});
}
@ -173,8 +199,8 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel,
saveAttribute(configurationAttribute, $window.btoa(angular.toJson(getGatewayConfigJSON())), types.attributesScope.shared.value),
saveAttribute(configurationDraftsAttribute, $window.btoa(angular.toJson(getDraftConnectorJSON())), types.attributesScope.server.value),
saveAttribute(remoteLoggingLevelAttribute, vm.configurations.remoteLoggingLevel.toUpperCase(), types.attributesScope.shared.value)
]).then(() =>{
toast.showSuccess(successfulSaved, 2000, angular.element('.gateway-form'),'top left');
]).then(() => {
toast.showSuccess(successfulSaved, 2000, angular.element('.gateway-form'), 'top left');
})
};
@ -238,7 +264,7 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel,
config += ' max_records_per_file: ' + vm.configurations.maxRecordsCount + '\n';
}
config += 'connectors:\n';
for(let i = 0; i < vm.configurations.connectors.length; i++){
for (let i = 0; i < vm.configurations.connectors.length; i++) {
if (vm.configurations.connectors[i].enabled) {
config += ' -\n';
config += ' name: ' + vm.configurations.connectors[i].name + '\n';
@ -250,7 +276,7 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel,
}
function generateConfigConnectorFiles(fileZipAdd) {
for(let i = 0; i < vm.configurations.connectors.length; i++){
for (let i = 0; i < vm.configurations.connectors.length; i++) {
if (vm.configurations.connectors[i].enabled) {
fileZipAdd[generateFileName(vm.configurations.connectors[i].name)] = angular.toJson(vm.configurations.connectors[i].config);
}
@ -276,7 +302,7 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel,
function gatewayMainConfigJSON() {
let configuration = {};
let thingsBoard = {};
thingsBoard.host = vm.configurations.host;
thingsBoard.remoteConfiguration = vm.configurations.remoteConfiguration;
@ -325,10 +351,10 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel,
}
function gatewayConnectorConfigJSON(gatewayConfiguration) {
for(let i = 0; i < vm.configurations.connectors.length; i++){
for (let i = 0; i < vm.configurations.connectors.length; i++) {
if (vm.configurations.connectors[i].enabled) {
let typeConnector = vm.configurations.connectors[i].configType;
if(!angular.isArray(gatewayConfiguration[typeConnector])){
if (!angular.isArray(gatewayConfiguration[typeConnector])) {
gatewayConfiguration[typeConnector] = [];
}
@ -343,7 +369,7 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel,
function getDraftConnectorJSON() {
let draftConnector = {};
for(let i = 0; i < vm.configurations.connectors.length; i++){
for (let i = 0; i < vm.configurations.connectors.length; i++) {
if (!vm.configurations.connectors[i].enabled) {
let connector = {
connector: vm.configurations.connectors[i].configType,
@ -362,7 +388,10 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel,
const device = devices[i];
if (device.additionalInfo !== null && device.additionalInfo.gateway === true) {
vm.gateways.push(device);
if (firstInit && vm.gateways.length && device.name === vm.gateways[0].name) {
if (vm.deviceNameForm && firstInit && vm.gateways.length && device.name === vm.deviceNameForm) {
vm.configurations.gateway = device;
vm.getAccessToken(device.id);
} else if (firstInit && vm.gateways.length && device.name === vm.gateways[0].name) {
vm.configurations.gateway = device;
vm.getAccessToken(device.id);
}
@ -385,7 +414,7 @@ function GatewayFormController($scope, $injector, $document, $mdExpansionPanel,
for (let connectorType in keyValue) {
let name = "No name";
if (Object.prototype.hasOwnProperty.call(keyValue[connectorType], 'name')) {
name = keyValue[connectorType].name ;
name = keyValue[connectorType].name;
}
let connector = {
enabled: true,

63
ui/src/app/components/gateway/gateway-form.tpl.html

@ -17,30 +17,36 @@
-->
<md-content md-scroll-y layout="column" class="gateway-form">
<form name="gatewayConfiguration">
<md-expansion-panel-group>
<md-expansion-panel md-component-id="thingsboardPanelId">
<md-expansion-panel-group>
<md-expansion-panel md-component-id="{{vm.idForm}}thingsboardPanelId">
<md-expansion-panel-collapsed>
<div class="tb-panel-title">{{ 'gateway.thingsboard' | translate | uppercase }}</div>
<span flex></span>
<md-expansion-panel-icon></md-expansion-panel-icon>
</md-expansion-panel-collapsed>
<md-expansion-panel-expanded>
<md-expansion-panel-header ng-click="vm.collapsePanel('thingsboardPanelId')">
<md-expansion-panel-header ng-click="vm.collapsePanel(vm.idForm + 'thingsboardPanelId')">
<div class="tb-panel-title">{{ 'gateway.thingsboard' | translate | uppercase }}</div>
<span flex></span>
<md-expansion-panel-icon></md-expansion-panel-icon>
</md-expansion-panel-header>
<md-expansion-panel-content>
<tb-gateway-config-select tb-required="true"
<tb-gateway-config-select ng-if="!vm.isStateForm"
tb-required="true"
ng-model="vm.configurations.gateway"
the-form="gatewayConfiguration"
gateway-list="vm.gateways"
get_access_token="vm.getAccessToken"
create-device="vm.createDevice">
</tb-gateway-config-select>
<md-input-container ng-if="vm.isStateForm"
class="md-block">
<label>{{'gateway.gateway-name' | translate }}</label>
<input ng-disabled="true" type="text" ng-model="vm.configurations.gateway.name" name="gatewayName"/>
</md-input-container>
<md-input-container class="md-block">
<label>{{'gateway.security-type' | translate }}</label>
<md-select name="securityType" ng-model="vm.configurations.securityType" required>
<md-select ng-disabled="vm.isReadOnlyForm" name="securityType" ng-model="vm.configurations.securityType" required>
<md-option ng-repeat="securityType in vm.securityTypes" ng-value="securityType.value">
{{securityType.name | translate}}
</md-option>
@ -50,14 +56,14 @@
ng-class="{'gateway-config-row-vertical': vm.changeAlignment}">
<md-input-container class="md-block" flex>
<label>{{ 'gateway.thingsboard-host' | translate }}</label>
<input type="text" name="host" ng-model="vm.configurations.host" required>
<input ng-disabled="vm.isReadOnlyForm" type="text" name="host" ng-model="vm.configurations.host" required>
<div ng-messages="gatewayConfiguration.host.$error">
<div ng-message="required" translate>gateway.thingsboard-host-required</div>
</div>
</md-input-container>
<md-input-container class="md-block" flex>
<label>{{ 'gateway.thingsboard-port' | translate }}</label>
<input type="number" min="1" max="65535" ng-pattern="/^-?[0-9]+$/" name="port"
<input ng-disabled="vm.isReadOnlyForm" type="number" min="1" max="65535" ng-pattern="/^-?[0-9]+$/" name="port"
ng-model="vm.configurations.port" required>
<div ng-messages="gatewayConfiguration.port.$error">
<div ng-message="required" translate>gateway.thingsboard-port-required</div>
@ -70,18 +76,18 @@
<div ng-if="vm.configurations.securityType=='tls'">
<md-input-container class="md-block security-type">
<label>{{'gateway.tls-path-ca-certificate' | translate }}</label>
<input type="text" ng-model="vm.configurations.caCertPath" name="caCertPath" />
<input ng-disabled="vm.isReadOnlyForm" type="text" ng-model="vm.configurations.caCertPath" name="caCertPath"/>
</md-input-container>
<md-input-container class="md-block">
<label>{{'gateway.tls-path-private-key' | translate }}</label>
<input type="text" ng-model="vm.configurations.privateKeyPath" name="privateKeyPath" />
<input ng-disabled="vm.isReadOnlyForm" type="text" ng-model="vm.configurations.privateKeyPath" name="privateKeyPath"/>
</md-input-container>
<md-input-container class="md-block">
<label>{{'gateway.tls-path-client-certificate' | translate }}</label>
<input type="text" ng-model="vm.configurations.certPath" name="certPath" />
<input ng-disabled="vm.isReadOnlyForm" type="text" ng-model="vm.configurations.certPath" name="certPath"/>
</md-input-container>
</div>
<md-checkbox ng-model="vm.configurations.remoteConfiguration"
<md-checkbox ng-show="!vm.isReadOnlyForm" ng-model="vm.configurations.remoteConfiguration"
name="remoteConfiguration"
aria-label="{{ 'gateway.remote-remote' | translate }}">
{{ 'gateway.remote' | translate }}
@ -90,7 +96,7 @@
ng-class="{'gateway-config-row-vertical': vm.changeAlignment}">
<md-input-container class="md-block md-select-container" flex>
<label>{{'gateway.remote-logging-level' | translate }}</label>
<md-select name="loggingLevel" ng-model="vm.configurations.remoteLoggingLevel">
<md-select ng-disabled="vm.isReadOnlyForm" name="loggingLevel" ng-model="vm.configurations.remoteLoggingLevel">
<md-option ng-repeat="logLevel in vm.types.gatewayLogLevel"
ng-value="logLevel" ng-selected="$index === 5">
{{logLevel}}
@ -99,7 +105,7 @@
</md-input-container>
<md-input-container class="md-block" flex>
<label>{{'gateway.path-logs' | translate }}</label>
<input type="text" ng-model="vm.configurations.remoteLoggingPathToLogs"
<input ng-disabled="vm.isReadOnlyForm" type="text" ng-model="vm.configurations.remoteLoggingPathToLogs"
name="remoteLoggingPathToLogs" required>
<div ng-messages="gatewayConfiguration.remoteLoggingPathToLogs.$error">
<div ng-message="required" translate>gateway.path-logs-required</div>
@ -109,14 +115,14 @@
</md-expansion-panel-content>
</md-expansion-panel-expanded>
</md-expansion-panel>
<md-expansion-panel md-component-id="storagePanelId">
<md-expansion-panel md-component-id="{{vm.idForm}}storagePanelId">
<md-expansion-panel-collapsed>
<div class="tb-panel-title">{{ 'gateway.storage' | translate | uppercase }}</div>
<span flex></span>
<md-expansion-panel-icon></md-expansion-panel-icon>
</md-expansion-panel-collapsed>
<md-expansion-panel-expanded>
<md-expansion-panel-header ng-click="vm.collapsePanel('storagePanelId')">
<md-expansion-panel-header ng-click="vm.collapsePanel(vm.idForm + 'storagePanelId')">
<div class="tb-panel-title">{{ 'gateway.storage' | translate | uppercase }}</div>
<span flex></span>
<md-expansion-panel-icon></md-expansion-panel-icon>
@ -124,18 +130,17 @@
<md-expansion-panel-content>
<md-input-container class="md-block" flex>
<label>{{'gateway.storage-type' | translate }}</label>
<md-select required ng-model="vm.configurations.storageType">
<md-select ng-disabled="vm.isReadOnlyForm" required ng-model="vm.configurations.storageType">
<md-option ng-repeat="storageType in vm.storageTypes" ng-value="storageType.value">
{{storageType.name | translate}}
</md-option>
</md-select>
</md-input-container>
<div layout="row" class="gateway-form-row"
ng-class="{'gateway-config-row-vertical': vm.changeAlignment}">
<md-input-container class="md-block" flex>
<label>{{'gateway.storage-pack-size' | translate }}</label>
<input type="number" min="1" name="readRecordsCount" ng-pattern="/^-?[0-9]+$/"
<input ng-disabled="vm.isReadOnlyForm" type="number" min="1" name="readRecordsCount" ng-pattern="/^-?[0-9]+$/"
ng-model='vm.configurations.readRecordsCount' required/>
<div ng-messages="gatewayConfiguration.readRecordsCount.$error">
<div ng-message="required" translate>gateway.storage-pack-size-required</div>
@ -143,10 +148,9 @@
<div ng-message="pattern" translate>gateway.storage-pack-size-pattern</div>
</div>
</md-input-container>
<md-input-container class="md-block" flex>
<label translate>{{ vm.configurations.storageType !== 'fileStorage' ? 'gateway.storage-max-records' : 'gateway.storage-max-file-records' }}</label>
<input type="number" min="1" name="maxRecordsCount" ng-pattern="/^-?[0-9]+$/"
<input ng-disabled="vm.isReadOnlyForm" type="number" min="1" name="maxRecordsCount" ng-pattern="/^-?[0-9]+$/"
ng-model='vm.configurations.maxRecordsCount' required/>
<div ng-messages="gatewayConfiguration.maxRecordsCount.$error">
<div ng-message="required" translate>gateway.storage-max-records-required</div>
@ -155,13 +159,12 @@
</div>
</md-input-container>
</div>
<div layout="row" class="gateway-form-row"
ng-if="vm.configurations.storageType == 'fileStorage'"
ng-class="{'gateway-config-row-vertical': vm.changeAlignment}">
<md-input-container class="md-block" flex>
<label>{{'gateway.storage-max-files' | translate }}</label>
<input type="number" min="1" name="maxFilesCount" ng-pattern="/^-?[0-9]+$/"
<input ng-disabled="vm.isReadOnlyForm" type="number" min="1" name="maxFilesCount" ng-pattern="/^-?[0-9]+$/"
ng-model='vm.configurations.maxFilesCount' required/>
<div ng-messages="gatewayConfiguration.maxFilesCount.$error">
<div ng-message="required" translate>gateway.storage-max-files-required</div>
@ -169,10 +172,9 @@
<div ng-message="pattern" translate>gateway.storage-max-files-pattern</div>
</div>
</md-input-container>
<md-input-container class="md-block" flex>
<label>{{'gateway.storage-path' | translate }}</label>
<input type="text" name="dataFolderPath" ng-model='vm.configurations.dataFolderPath'
<input ng-disabled="vm.isReadOnlyForm" type="text" name="dataFolderPath" ng-model='vm.configurations.dataFolderPath'
required/>
<div ng-messages="gatewayConfiguration.dataFolderPath.$error">
<div ng-message="required" translate>gateway.storage-path-required</div>
@ -182,14 +184,14 @@
</md-expansion-panel-content>
</md-expansion-panel-expanded>
</md-expansion-panel>
<md-expansion-panel md-component-id="connectorsPanelId">
<md-expansion-panel md-component-id="{{vm.idForm}}connectorsPanelId">
<md-expansion-panel-collapsed>
<div class="tb-panel-title">{{ 'gateway.connectors' | translate | uppercase }}</div>
<span flex></span>
<md-expansion-panel-icon></md-expansion-panel-icon>
</md-expansion-panel-collapsed>
<md-expansion-panel-expanded>
<md-expansion-panel-header ng-click="vm.collapsePanel('connectorsPanelId')">
<md-expansion-panel-header ng-click="vm.collapsePanel(vm.idForm + 'connectorsPanelId')">
<div class="tb-panel-title">{{ 'gateway.connectors' | translate | uppercase }}</div>
<span flex></span>
<md-expansion-panel-icon></md-expansion-panel-icon>
@ -198,13 +200,14 @@
<tb-gateway-config
gateway-config="vm.configurations.connectors"
the-form="gatewayConfiguration"
change-alignment="vm.changeAlignment">
change-alignment="vm.changeAlignment"
is-read-only="vm.isReadOnlyForm">
</tb-gateway-config>
</md-expansion-panel-content>
</md-expansion-panel-expanded>
</md-expansion-panel>
</md-expansion-panel-group>
<section layout="row" layout-align="end center" class="form-action-buttons">
<section ng-show="!vm.isReadOnlyForm" layout="row" layout-align="end center" class="form-action-buttons">
<md-button class="md-primary md-raised"
ng-click="vm.exportConfig()"
ng-if="!vm.configurations.remoteConfiguration"
@ -213,14 +216,14 @@
{{'action.download' | translate }}
<md-tooltip>{{'gateway.download-tip' | translate }}</md-tooltip>
</md-button>
<md-button class="md-primary md-raised"
ng-click="vm.saveAttributeConfig()"
ng-if="vm.configurations.remoteConfiguration"
ng-disabled="gatewayConfiguration.$invalid || !gatewayConfiguration.$dirty"
aria-label="{{ 'gateway.save-tip' | translate }}">
{{'action.save' | translate }}
<md-tooltip ng-if="vm.configurations.remoteConfiguration">{{'gateway.save-tip' | translate }}</md-tooltip>
<md-tooltip ng-if="vm.configurations.remoteConfiguration">{{'gateway.save-tip' | translate }}
</md-tooltip>
</md-button>
</section>
</form>

18
ui/src/app/components/gateway/state-gateway-dialog.scss

@ -0,0 +1,18 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.state-gateway-config-dialog {
width: 600px;
}

52
ui/src/app/components/gateway/state-gateway-dialog.tpl.html

@ -0,0 +1,52 @@
<!--
Copyright © 2016-2020 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<md-dialog class="state-gateway-config-dialog">
<md-toolbar>
<div class="md-toolbar-tools">
<h2 translate translate-values='{ typeName: "{{vm.typeName | translate}}" }'>
gateway.title-show-config
</h2>
<span flex></span>
<md-button class="md-icon-button"
ng-click="vm.cancel()"
aria-label="{{'action.close'|translate}}">
<ng-md-icon icon="close" aria-label="Close"></ng-md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content>
<div class="md-dialog-content">
<div tb-expand-fullscreen fullscreen-zindex="100" expand-button-id="expand-button" layout="column">
<div layout="row" layout-align="start center" class="tb-json-toolbar">
<label ng-if="vm.isReadOnly" class="tb-title no-padding" translate>gateway.read-only</label>
<label ng-if="!vm.isReadOnly" class="tb-title no-padding" translate>gateway.read-write</label>
<span flex></span>
<md-button id="expand-button" aria-label="Fullscreen"
class="md-icon-button tb-md-32 tb-fullscreen-button-style"></md-button>
</div>
<tb-gateway-form device-name = "vm.deviceName"
is-read-only="vm.isReadOnly"
is-state="vm.isState">
</tb-gateway-form>
</div>
</div>
</md-dialog-content>
</md-dialog>

149
ui/src/app/components/gateway/state-gateway-form.directive.js

@ -0,0 +1,149 @@
/*
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import './state-gateway-form.scss';
import './state-gateway-dialog.scss';
/* eslint-disable import/no-unresolved, import/default */
import stateGatewayFormTemplate from './state-gateway-form.tpl.html';
import stateGatewayDialogTemplate from "./state-gateway-dialog.tpl.html";
/* eslint-enable import/no-unresolved, import/default */
export default angular.module('thingsboard.directives.stateGatewayForm', [])
.directive('tbStateGatewayForm', StateGatewayForm)
.name;
/*@ngInject*/
function StateGatewayForm() {
return {
restrict: "E",
scope: true,
bindToController: {
disabled: '=ngDisabled',
keyPlaceholderText: '@?',
valuePlaceholderText: '@?',
noDataText: '@?',
formId: '=',
ctx: '=',
theForm: '='
},
controller: StateGatewayFormController,
controllerAs: 'vm',
templateUrl: stateGatewayFormTemplate
};
}
/*@ngInject*/
function StateGatewayFormController($scope, $mdDialog, $injector, $document, $mdExpansionPanel, $translate, types, entityService, utils) {
$scope.$mdExpansionPanel = $mdExpansionPanel;
let vm = this;
vm.isReadOnly = false;
vm.isState = true;
vm.isDashboard = false;
$scope.$watch('vm.ctx', function() {
if (vm.ctx && vm.ctx.defaultSubscription) {
vm.settings = vm.ctx.settings;
if (vm.ctx.datasources && vm.ctx.datasources.length) {
vm.deviceName = vm.ctx.datasources[0].name;
vm.isDashboard = vm.deviceName ? true : false;
if (vm.ctx.settings) {
vm.isReadOnly = vm.ctx.settings.readOnly;
}
initializeConfig();
}
}
});
function updateWidgetDisplaying() {
if (vm.ctx && vm.ctx.$container) {
vm.changeAlignment = (vm.ctx.$container[0].offsetWidth <= 425);
}
}
function initWidgetSettings() {
if (vm.settings.stateGatewayTitle && vm.settings.stateGatewayTitle.length) {
vm.stateGatewayTitle = utils.customTranslation(vm.settings.stateGatewayTitle, vm.settings.stateGatewayTitle);
} else {
vm.stateGatewayTitle = $translate.instant('gateway.state-title');
}
vm.ctx.widgetActions = [vm.showConfig];
vm.ctx.widgetTitle = vm.stateGatewayTitle;
}
function initializeConfig() {
updateWidgetDisplaying();
initWidgetSettings();
}
$scope.$on('state-gateway-form-resize', function (event, formId) {
if (vm.formId == formId) {
updateWidgetDisplaying();
}
});
updateWidgetDisplaying();
vm.showConfig = {
name: "gateway.show-config-tip",
show: true,
onAction: function($event) {
vm.openShowConfigDialog($event)
},
icon: "visibility"
};
vm.openShowConfigDialog =($event) => {
if ($event) {
$event.stopPropagation();
}
$mdDialog.show({
controller: StateGatewayDialogController,
controllerAs: 'vm',
templateUrl: stateGatewayDialogTemplate,
parent: angular.element($document[0].body),
locals: {
deviceName: vm.deviceName,
isReadOnly: vm.isReadOnly,
isState: vm.isState
},
bindToController: true,
targetEvent: $event,
fullscreen: true,
multiple: true
}).then(function() {
}, function () {
});
}
}
/*@ngInject*/
function StateGatewayDialogController($scope, $mdDialog, deviceName, isReadOnly, isState) {
let vm = this;
vm.deviceName = deviceName;
vm.isReadOnly = isReadOnly;
vm.isState = isState;
vm.cancel = () => {
$mdDialog.hide();
};
}

18
ui/src/app/components/gateway/state-gateway-form.scss

@ -0,0 +1,18 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.state-gateway-form {
padding: 5px 5px 0;
}

28
ui/src/app/components/gateway/state-gateway-form.tpl.html

@ -0,0 +1,28 @@
<!--
Copyright © 2016-2020 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<form name="stateGatewayConfiguration" class="state-gateway-form">
<md-input-container class="md-block">
<label>{{'gateway.gateway-name' | translate }}</label>
<input ng-if="vm.isDashboard" ng-disabled="true" type="text" ng-model="vm.deviceName" name="gatewayName"/>
</md-input-container>
<!-- <md-switch ng-model="vm.isReadOnly"-->
<!-- aria-label="{{ 'gateway.read-only' | translate }}">-->
<!-- {{'gateway.read-only' | translate }}-->
<!-- </md-switch>-->
</form>

2
ui/src/app/layout/index.js

@ -30,6 +30,7 @@ import thingsboardSideMenu from '../components/side-menu.directive';
import thingsboardNavTree from '../components/nav-tree.directive';
import thingsboardDashboardAutocomplete from '../components/dashboard-autocomplete.directive';
import thingsboardKvMap from '../components/kv-map.directive';
import thingsboardStateGatewayForm from '../components/gateway/state-gateway-form.directive';
import thingsboardGatewayConfig from '../components/gateway/gateway-config.directive';
import thingsboardGatewayConfigSelect from '../components/gateway/gateway-config-select.directive';
import thingsboardGatewayForm from '../components/gateway/gateway-form.directive';
@ -96,6 +97,7 @@ export default angular.module('thingsboard.home', [
thingsboardNavTree,
thingsboardDashboardAutocomplete,
thingsboardKvMap,
thingsboardStateGatewayForm,
thingsboardGatewayConfig,
thingsboardGatewayConfigSelect,
thingsboardGatewayForm,

7
ui/src/app/locale/locale.constant-en_US.json

@ -1197,7 +1197,12 @@
"tls-path-private-key": "Path to private key on gateway",
"toggle-fullscreen": "Toggle fullscreen",
"transformer-json-config": "Configuration JSON*",
"update-config": "Add/update configuration JSON"
"update-config": "Add/update configuration JSON",
"state-title": "Gateway state",
"show-config-tip": "Show gateway configuration",
"title-show-config": "Show gateway configuration",
"read-only": "Read only",
"read-write": ""
},
"grid": {
"delete-item-title": "Are you sure you want to delete this item?",

Loading…
Cancel
Save