,
protected router: Router,
@Inject(MAT_DIALOG_DATA) public data: JsonObjectEditDialogData,
diff --git a/ui-ngx/src/app/shared/components/directives/tb-json-to-string.directive.ts b/ui-ngx/src/app/shared/components/directives/tb-json-to-string.directive.ts
index 8da5fb1396..c70de1ab48 100644
--- a/ui-ngx/src/app/shared/components/directives/tb-json-to-string.directive.ts
+++ b/ui-ngx/src/app/shared/components/directives/tb-json-to-string.directive.ts
@@ -17,19 +17,23 @@
import { Directive, ElementRef, forwardRef, HostListener, Renderer2, SkipSelf } from '@angular/core';
import {
ControlValueAccessor,
- UntypedFormControl,
FormGroupDirective,
NG_VALIDATORS,
NG_VALUE_ACCESSOR,
NgForm,
+ UntypedFormControl,
ValidationErrors,
Validator
} from '@angular/forms';
import { ErrorStateMatcher } from '@angular/material/core';
-import { isObject } from "@core/utils";
+import { isObject } from '@core/utils';
@Directive({
selector: '[tb-json-to-string]',
+ // eslint-disable-next-line @angular-eslint/no-host-metadata-property
+ host: {
+ '(blur)': 'onTouched()'
+ },
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => TbJsonToStringDirective),
@@ -48,18 +52,26 @@ import { isObject } from "@core/utils";
export class TbJsonToStringDirective implements ControlValueAccessor, Validator, ErrorStateMatcher {
private propagateChange = null;
+ public onTouched = () => {};
private parseError: boolean;
private data: any;
@HostListener('input', ['$event.target.value']) input(newValue: any): void {
try {
- this.data = JSON.parse(newValue);
- if (isObject(this.data)) {
- this.parseError = false;
+ if (newValue) {
+ this.data = JSON.parse(newValue);
+ if (isObject(this.data)) {
+ this.parseError = false;
+ } else {
+ this.data = null;
+ this.parseError = true;
+ }
} else {
- this.parseError = true;
+ this.data = null;
+ this.parseError = false;
}
} catch (e) {
+ this.data = null;
this.parseError = true;
}
@@ -73,9 +85,7 @@ export class TbJsonToStringDirective implements ControlValueAccessor, Validator,
}
isErrorState(control: UntypedFormControl | null, form: FormGroupDirective | NgForm | null): boolean {
- const originalErrorState = this.errorStateMatcher.isErrorState(control, form);
- const customErrorState = !!(control && control.invalid && this.parseError);
- return originalErrorState || customErrorState;
+ return !!(control && control.invalid && !Array.isArray(control.value) && control.touched);
}
validate(c: UntypedFormControl): ValidationErrors {
@@ -87,11 +97,9 @@ export class TbJsonToStringDirective implements ControlValueAccessor, Validator,
}
writeValue(obj: any): void {
- if (obj) {
- this.data = obj;
- this.parseError = false;
- this.render.setProperty(this.element.nativeElement, 'value', JSON.stringify(obj));
- }
+ this.data = obj;
+ this.parseError = false;
+ this.render.setProperty(this.element.nativeElement, 'value', obj ? JSON.stringify(obj) : '');
}
registerOnChange(fn: any): void {
@@ -99,5 +107,6 @@ export class TbJsonToStringDirective implements ControlValueAccessor, Validator,
}
registerOnTouched(fn: any): void {
+ this.onTouched = fn;
}
}
diff --git a/ui-ngx/src/app/shared/components/file-input.component.html b/ui-ngx/src/app/shared/components/file-input.component.html
index 57e1ad1465..308e9e59f7 100644
--- a/ui-ngx/src/app/shared/components/file-input.component.html
+++ b/ui-ngx/src/app/shared/components/file-input.component.html
@@ -16,7 +16,12 @@
-->
diff --git a/ui-ngx/src/app/shared/components/file-input.component.scss b/ui-ngx/src/app/shared/components/file-input.component.scss
index 02924111b4..a229a01bfb 100644
--- a/ui-ngx/src/app/shared/components/file-input.component.scss
+++ b/ui-ngx/src/app/shared/components/file-input.component.scss
@@ -93,4 +93,8 @@ $previewSize: 100px !default;
padding: 0 16px;
}
}
+
+ .pointer-event {
+ pointer-events: auto;
+ }
}
diff --git a/ui-ngx/src/app/shared/components/file-input.component.ts b/ui-ngx/src/app/shared/components/file-input.component.ts
index 51933d749c..8e70ca88ba 100644
--- a/ui-ngx/src/app/shared/components/file-input.component.ts
+++ b/ui-ngx/src/app/shared/components/file-input.component.ts
@@ -54,6 +54,9 @@ export class FileInputComponent extends PageComponent implements AfterViewInit,
@Input()
label: string;
+ @Input()
+ hint: string;
+
@Input()
accept = '*/*';
diff --git a/ui-ngx/src/app/shared/components/json-object-edit.component.html b/ui-ngx/src/app/shared/components/json-object-edit.component.html
index c0024da9dd..3ed828e6cf 100644
--- a/ui-ngx/src/app/shared/components/json-object-edit.component.html
+++ b/ui-ngx/src/app/shared/components/json-object-edit.component.html
@@ -20,7 +20,7 @@
[fullscreen]="fullscreen" (fullscreenChanged)="onFullscreen()" fxLayout="column">
diff --git a/ui-ngx/src/app/shared/components/json-object-edit.component.ts b/ui-ngx/src/app/shared/components/json-object-edit.component.ts
index f7e3116b0f..f89430f98b 100644
--- a/ui-ngx/src/app/shared/components/json-object-edit.component.ts
+++ b/ui-ngx/src/app/shared/components/json-object-edit.component.ts
@@ -24,7 +24,14 @@ import {
OnInit,
ViewChild
} from '@angular/core';
-import { ControlValueAccessor, UntypedFormControl, NG_VALIDATORS, NG_VALUE_ACCESSOR, Validator } from '@angular/forms';
+import {
+ ControlValueAccessor,
+ UntypedFormControl,
+ NG_VALIDATORS,
+ NG_VALUE_ACCESSOR,
+ Validator,
+ AbstractControl, ValidationErrors
+} from '@angular/forms';
import { Ace } from 'ace-builds';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { ActionNotificationHide, ActionNotificationShow } from '@core/notification/notification.actions';
@@ -34,6 +41,9 @@ import { CancelAnimationFrame, RafService } from '@core/services/raf.service';
import { guid, isDefinedAndNotNull, isObject, isUndefined } from '@core/utils';
import { ResizeObserver } from '@juggle/resize-observer';
import { getAce } from '@shared/models/ace/ace.models';
+import { coerceBoolean } from '@shared/decorators/coercion';
+
+export const jsonRequired = (control: AbstractControl): ValidationErrors | null => !control.value ? {required: true} : null;
@Component({
selector: 'tb-json-object-edit',
@@ -73,27 +83,13 @@ export class JsonObjectEditComponent implements OnInit, ControlValueAccessor, Va
@Input() sort: (key: string, value: any) => any;
- private requiredValue: boolean;
-
- get required(): boolean {
- return this.requiredValue;
- }
-
+ @coerceBoolean()
@Input()
- set required(value: boolean) {
- this.requiredValue = coerceBooleanProperty(value);
- }
-
- private readonlyValue: boolean;
-
- get readonly(): boolean {
- return this.readonlyValue;
- }
+ jsonRequired: boolean;
+ @coerceBoolean()
@Input()
- set readonly(value: boolean) {
- this.readonlyValue = coerceBooleanProperty(value);
- }
+ readonly: boolean;
fullscreen = false;
@@ -245,12 +241,10 @@ export class JsonObjectEditComponent implements OnInit, ControlValueAccessor, Va
try {
if (isDefinedAndNotNull(this.modelValue)) {
this.contentValue = JSON.stringify(this.modelValue, isUndefined(this.sort) ? undefined :
- (key, objectValue) => {
- return this.sort(key, objectValue);
- }, 2);
+ (key, objectValue) => this.sort(key, objectValue), 2);
this.objectValid = true;
} else {
- this.objectValid = !this.required;
+ this.objectValid = !this.jsonRequired;
this.validationError = 'Json object is required.';
}
} catch (e) {
@@ -288,8 +282,8 @@ export class JsonObjectEditComponent implements OnInit, ControlValueAccessor, Va
this.validationError = errorInfo;
}
} else {
- this.objectValid = !this.required;
- this.validationError = this.required ? 'Json object is required.' : '';
+ this.objectValid = !this.jsonRequired;
+ this.validationError = this.jsonRequired ? 'Json object is required.' : '';
}
this.modelValue = data;
this.propagateChange(data);
diff --git a/ui-ngx/src/app/shared/components/value-input.component.html b/ui-ngx/src/app/shared/components/value-input.component.html
index 57d6954699..9f7f9d0ffc 100644
--- a/ui-ngx/src/app/shared/components/value-input.component.html
+++ b/ui-ngx/src/app/shared/components/value-input.component.html
@@ -67,7 +67,7 @@
-
+
{{ (requiredText ? requiredText : 'value.json-value-required') | translate }}
diff --git a/ui-ngx/src/app/shared/components/value-input.component.ts b/ui-ngx/src/app/shared/components/value-input.component.ts
index 4ba7abf157..6d57b1ddd2 100644
--- a/ui-ngx/src/app/shared/components/value-input.component.ts
+++ b/ui-ngx/src/app/shared/components/value-input.component.ts
@@ -73,7 +73,8 @@ export class ValueInputComponent implements OnInit, ControlValueAccessor {
disableClose: true,
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
data: {
- jsonValue: this.modelValue
+ jsonValue: this.modelValue,
+ required: true
}
}).afterClosed().subscribe(
(res) => {
@@ -115,7 +116,8 @@ export class ValueInputComponent implements OnInit, ControlValueAccessor {
}
updateView() {
- if (this.inputForm.valid || this.valueType === ValueType.BOOLEAN) {
+ if (this.inputForm.valid || this.valueType === ValueType.BOOLEAN ||
+ (this.valueType === ValueType.JSON && Array.isArray(this.modelValue))) {
this.propagateChange(this.modelValue);
} else {
this.propagateChange(null);
diff --git a/ui-ngx/src/app/shared/models/device.models.ts b/ui-ngx/src/app/shared/models/device.models.ts
index 345dd92b1e..260fbee33a 100644
--- a/ui-ngx/src/app/shared/models/device.models.ts
+++ b/ui-ngx/src/app/shared/models/device.models.ts
@@ -865,6 +865,13 @@ export interface PublishTelemetryCommand {
snmp?: string;
}
+export interface PublishLaunchCommand {
+ mqtt: {
+ linux: string;
+ windows: string;
+ };
+}
+
export const dayOfWeekTranslations = new Array(
'device-profile.schedule-day.monday',
'device-profile.schedule-day.tuesday',
diff --git a/ui-ngx/src/app/shared/models/edge.models.ts b/ui-ngx/src/app/shared/models/edge.models.ts
index 372a910402..1acfa2ca28 100644
--- a/ui-ngx/src/app/shared/models/edge.models.ts
+++ b/ui-ngx/src/app/shared/models/edge.models.ts
@@ -59,9 +59,12 @@ export enum EdgeEventType {
CUSTOMER = 'CUSTOMER',
RELATION = 'RELATION',
TENANT = 'TENANT',
+ TENANT_PROFILE = 'TENANT_PROFILE',
WIDGETS_BUNDLE = 'WIDGETS_BUNDLE',
WIDGET_TYPE = 'WIDGET_TYPE',
- ADMIN_SETTINGS = 'ADMIN_SETTINGS'
+ ADMIN_SETTINGS = 'ADMIN_SETTINGS',
+ OTA_PACKAGE = 'OTA_PACKAGE',
+ QUEUE = 'QUEUE'
}
export enum EdgeEventActionType {
@@ -80,6 +83,8 @@ export enum EdgeEventActionType {
RPC_CALL = 'RPC_CALL',
ALARM_ACK = 'ALARM_ACK',
ALARM_CLEAR = 'ALARM_CLEAR',
+ ALARM_ASSIGNED = 'ALARM_ASSIGNED',
+ ALARM_UNASSIGNED = 'ALARM_UNASSIGNED',
ASSIGNED_TO_EDGE = 'ASSIGNED_TO_EDGE',
UNASSIGNED_FROM_EDGE = 'UNASSIGNED_FROM_EDGE',
CREDENTIALS_REQUEST = 'CREDENTIALS_REQUEST',
@@ -107,9 +112,12 @@ export const edgeEventTypeTranslations = new Map(
[EdgeEventType.CUSTOMER, 'edge-event.type-customer'],
[EdgeEventType.RELATION, 'edge-event.type-relation'],
[EdgeEventType.TENANT, 'edge-event.type-tenant'],
+ [EdgeEventType.TENANT_PROFILE, 'edge-event.type-tenant-profile'],
[EdgeEventType.WIDGETS_BUNDLE, 'edge-event.type-widgets-bundle'],
[EdgeEventType.WIDGET_TYPE, 'edge-event.type-widgets-type'],
- [EdgeEventType.ADMIN_SETTINGS, 'edge-event.type-admin-settings']
+ [EdgeEventType.ADMIN_SETTINGS, 'edge-event.type-admin-settings'],
+ [EdgeEventType.OTA_PACKAGE, 'edge-event.type-ota-package'],
+ [EdgeEventType.QUEUE, 'edge-event.type-queue']
]
);
@@ -130,6 +138,8 @@ export const edgeEventActionTypeTranslations = new MapThingsBoard device) with credentials of the current device you can use the following commands.",
+ "telemetry-command-setup-step": "1. Setup:",
+ "telemetry-command-send-step": "2. Send command:",
+ "telemetry-command-send-step-coap": "2. Send command: (based on CoAP cli)",
"idCopiedMessage": "Device Id has been copied to clipboard",
"accessTokenCopiedMessage": "Device access token has been copied to clipboard",
"mqtt-authentication-copied-message": "Device MQTT authentication has been copied to clipboard",
@@ -2007,11 +2015,15 @@
"type-rule-chain-metadata": "Rule Chain Metadata",
"type-edge": "Edge",
"type-user": "User",
+ "type-tenant": "Tenant",
+ "type-tenant-profile": "Tenant Profile",
"type-customer": "Customer",
"type-relation": "Relation",
"type-widgets-bundle": "Widgets Bundle",
"type-widgets-type": "Widgets Type",
"type-admin-settings": "Admin Settings",
+ "type-ota-package": "Ota Package",
+ "type-queue": "Queue",
"action-type-added": "Added",
"action-type-deleted": "Deleted",
"action-type-updated": "Updated",
@@ -2027,6 +2039,8 @@
"action-type-rpc-call": "RPC Call",
"action-type-alarm-ack": "Alarm Ack",
"action-type-alarm-clear": "Alarm Clear",
+ "action-type-alarm-assigned": "Alarm Assigned",
+ "action-type-alarm-unassigned": "Alarm Unassigned",
"action-type-assigned-to-edge": "Assigned to Edge",
"action-type-unassigned-from-edge": "Unassigned from Edge",
"action-type-credentials-request": "Credentials Request",
@@ -2628,38 +2642,181 @@
},
"gateway": {
"add-entry": "Add configuration",
+ "advanced": "Advanced",
+ "checking-device-activity": "Checking Device Activity:",
+ "command": "Docker commands",
+ "command-copied-message": "Docker command has been copied to clipboard",
+ "configuration": "Configuration",
+ "connector-json": "Connector JSON",
"connector-add": "Add new connector",
"connector-enabled": "Enable connector",
"connector-name": "Connector name",
"connector-name-required": "Connector name is required.",
+ "connector-key": "Connector key",
+ "connector-key-required": "Connector key is required.",
+ "connector-configuration": "Configuration file name",
+ "connector-configuration-required": "Configuration file name is required.",
"connector-type": "Connector type",
"connector-type-required": "Connector type is required.",
- "connectors": "Connectors configuration",
+ "connector-types": {
+ "mqtt": "MQTT Broker Connector",
+ "modbus": "Modbus Connector",
+ "modbus_serial": "Modbus Connector (serial)",
+ "opcua": "OPC-UA Connector",
+ "opcua_asyncio": "OPC-UA Connector (asyncio)",
+ "ble": "BLE Connector",
+ "request": "REQUEST Connector",
+ "can": "CAN Connector",
+ "bacnet": "BACnet Connector",
+ "odbc": "ODBC Connector",
+ "rest": "REST Connector",
+ "snmp": "SNMP Connector",
+ "ftp": "FTP Connector",
+ "socket": "Socket TCP/UDP Connector",
+ "xmpp": "XMPP Connector",
+ "ocpp": "OCPP Connector"
+ },
+ "connectors": "Connectors",
+ "connectors-config": "Connectors configuration",
+ "connectors-active": "Connector active",
+ "connectors-inactive": "Connector inactive",
+ "connectors-table-enabled": "Enabled",
+ "connectors-table-name": "Name",
+ "connectors-table-type": "Type",
+ "connectors-table-status": "Status",
+ "connectors-table-actions": "Actions",
+ "connectors-table-key": "Key",
+ "connectors-table-class": "Class",
+ "rpc-command-send": "Send",
+ "rpc-command-result": "Result",
+ "rpc-command-edit-params": "Edit parameters",
+ "select-connector": "Select connector",
+ "gateway-configuration": "Gateway Configuration",
+ "docker-label": "In order to run ThingsBoard IoT gateway in docker with credentials for this device you can use the following commands.",
+ "copy-command": "Copy docker command",
"create-new-gateway": "Create a new gateway",
"create-new-gateway-text": "Are you sure you want create a new gateway with name: '{{gatewayName}}'?",
+ "created-time": "Created time",
+ "configuration-delete-dialog-header": "Configurations will be deleted",
+ "configuration-delete-dialog-body": "Turning off Remote Configuration is possible only if there is physical access to the Gateway. All previous configurations will be deleted.
\nTo turn off configuration, enter gateway name below",
+ "configuration-delete-dialog-input": "Gateway name",
+ "configuration-delete-dialog-input-required": "Gateway name is mandatory",
+ "configuration-delete-dialog-confirm": "Turn Off",
"delete": "Delete configuration",
"download-tip": "Download configuration file",
+ "drop-file": "Drop file here or",
"gateway": "Gateway",
"gateway-exists": "Device with same name is already exists.",
"gateway-name": "Gateway name",
"gateway-name-required": "Gateway name is required.",
"gateway-saved": "Gateway configuration successfully saved.",
+ "gateway-search": "Gateway search",
+ "grpc": "GRPC",
+ "grpc-keep-alive-timeout": "Keep alive timeout (in ms)",
+ "grpc-keep-alive-timeout-required": "Keep alive timeout is required",
+ "grpc-keep-alive-timeout-min": "Keep alive timeout can not be less then 1",
+ "grpc-keep-alive-timeout-pattern": "Keep alive timeout is not valid",
+ "grpc-keep-alive": "Keep alive (in ms)",
+ "grpc-keep-alive-required": "Keep alive is required",
+ "grpc-keep-alive-min": "Keep alive can not be less then 1",
+ "grpc-keep-alive-pattern": "Keep alive is not valid",
+ "grpc-min-time-between-pings": "Min time between pings (in ms)",
+ "grpc-min-time-between-pings-required": "Min time between pings is required",
+ "grpc-min-time-between-pings-min": "Min time between pings can not be less then 1",
+ "grpc-min-time-between-pings-pattern": "Min time between pings is not valid",
+ "grpc-min-ping-interval-without-data": "Min ping interval without data (in ms)",
+ "grpc-min-ping-interval-without-data-required": "Min ping interval without data is required",
+ "grpc-min-ping-interval-without-data-min": "Min ping interval without data can not be less then 1",
+ "grpc-min-ping-interval-without-data-pattern": "Min ping interval without data is not valid",
+ "grpc-max-pings-without-data": "Max pings without data",
+ "grpc-max-pings-without-data-required": "Max pings without data is required",
+ "grpc-max-pings-without-data-min": "Max pings without data can not be less then 1",
+ "grpc-max-pings-without-data-pattern": "Max pings without data is not valid",
+ "handle-device-renaming": "Handle device renaming",
+ "inactivity-check-period-seconds": "Inactivity check period (in sec)",
+ "inactivity-check-period-seconds-required": "Inactivity check period is required",
+ "inactivity-check-period-seconds-min": "Inactivity check period can not be less then 1",
+ "inactivity-timeout-seconds": "Inactivity timeout (in sec)",
+ "inactivity-timeout-seconds-required": "Inactivity timeout is required",
+ "inactivity-timeout-seconds-min": "Inactivity timeout can not be less then 1",
"json-parse": "Not valid JSON.",
"json-required": "Field cannot be empty.",
+ "linux-macos": "Linux/MacOS",
+ "logs": {
+ "logs": "Logs",
+ "days": "days",
+ "hours": "hours",
+ "minutes": "minutes",
+ "seconds": "seconds",
+ "date-format": "Date format",
+ "date-format-required": "Date format required",
+ "log-format": "Log format",
+ "log-type": "Log type",
+ "log-format-required": "Log format required",
+ "remote": "Remote logging",
+ "remote-logs": "Remote logs",
+ "local": "Local logging",
+ "level": "Log level",
+ "file-path": "File path",
+ "file-path-required": "File path required",
+ "saving-period": "Log saving period",
+ "saving-period-min": "Log saving period can not be less then 1",
+ "saving-period-required": "Log saving period required",
+ "backup-count": "Backup count",
+ "backup-count-min": "Backup count can not be less then 1",
+ "backup-count-required": "Backup count required"
+ },
+ "min-pack-send-delay": "Min pack send delay (in ms)",
+ "min-pack-send-delay-required": "Min pack send delay is required",
+ "min-pack-send-delay-min": "Min pack send delay can not be less then 0",
"no-connectors": "No connectors",
"no-data": "No configurations",
"no-gateway-found": "No gateway found.",
"no-gateway-matching": " '{{item}}' not found.",
"path-logs": "Path to log files",
"path-logs-required": "Path is required.",
+ "permit-without-calls": "Keep alive permit without calls",
"remote": "Remote configuration",
"remote-logging-level": "Logging level",
"remove-entry": "Remove configuration",
+ "remote-shell": "Remote shell",
+ "remote-configuration": "Remote Configuration",
+ "other": "Other",
"save-tip": "Save configuration file",
"security-type": "Security type",
"security-types": {
"access-token": "Access Token",
- "tls": "TLS"
+ "username-password": "Username and Password",
+ "tls": "TLS",
+ "tls-access-token": "TLS + Access Token",
+ "tls-private-key": "TLS + Private Key"
+ },
+ "server-port": "Server port",
+ "stats-send-period-in-sec": "Stats send period in seconds",
+ "statistics": {
+ "statistic": "Statistic",
+ "statistics": "Statistics",
+ "statistic-commands-empty": "No statistics available",
+ "commands": "Commands",
+ "send-period": "Statistic send period (in sec)",
+ "send-period-required": "Statistic send period is required",
+ "send-period-min": "Statistic send period can not be less then 60",
+ "send-period-pattern": "Statistic send period is not valid",
+ "check-connectors-configuration": "Check connectors configuration (in sec)",
+ "check-connectors-configuration-required": "Check connectors configuration is required",
+ "check-connectors-configuration-min": "Check connectors configuration can not be less then 1",
+ "check-connectors-configuration-pattern": "Check connectors configuration is not valid",
+ "add": "Add command",
+ "timeout": "Timeout",
+ "timeout-ms": "Timeout (in ms)",
+ "timeout-required": "Timeout is required",
+ "timeout-min": "Timeout can not be less then 1",
+ "timeout-pattern": "Timeout is not valid",
+ "attribute-name": "Attribute name",
+ "attribute-name-required": "Attribute name is required",
+ "command": "Command",
+ "command-required": "Command is required",
+ "remove": "Remove command"
},
"storage": "Storage",
"storage-max-file-records": "Maximum records in file",
@@ -2671,6 +2828,16 @@
"storage-max-records-min": "Minimum number of records is 1.",
"storage-max-records-pattern": "Number is not valid.",
"storage-max-records-required": "Maximum records is required.",
+ "storage-read-record-count": "Read record count in storage",
+ "storage-read-record-count-min": "Minimum number of records is 1.",
+ "storage-read-record-count-pattern": "Number is not valid.",
+ "storage-read-record-count-required": "Read record count is required.",
+ "storage-max-read-record-count": "Max read record count in storage",
+ "storage-max-read-record-count-min": "Minimum number of records is 1.",
+ "storage-max-read-record-count-pattern": "Number is not valid.",
+ "storage-max-read-record-count-required": "Max Read record count is required.",
+ "storage-data-folder-path": "Data folder path",
+ "storage-data-folder-path-required": "Data folder path is required.",
"storage-pack-size": "Maximum event pack size",
"storage-pack-size-min": "Minimum number is 1.",
"storage-pack-size-pattern": "Number is not valid.",
@@ -2680,9 +2847,11 @@
"storage-type": "Storage type",
"storage-types": {
"file-storage": "File storage",
- "memory-storage": "Memory storage"
+ "memory-storage": "Memory storage",
+ "sqlite": "SQLITE"
},
"thingsboard": "ThingsBoard",
+ "thingsboard-general": "General",
"thingsboard-host": "ThingsBoard host",
"thingsboard-host-required": "Host is required.",
"thingsboard-port": "ThingsBoard port",
@@ -2695,10 +2864,67 @@
"title-connectors-json": "Connector {{typeName}} configuration",
"tls-path-ca-certificate": "Path to CA certificate on gateway",
"tls-path-client-certificate": "Path to client certificate on gateway",
+ "messages-ttl-check-in-hours": "Messages TTL check in hours",
+ "messages-ttl-check-in-hours-required": "Messages TTL check in hours is required.",
+ "messages-ttl-check-in-hours-min": "Min number is 1.",
+ "messages-ttl-check-in-hours-pattern": "Number is not valid.",
+ "messages-ttl-in-days": "Messages TTL in days",
+ "messages-ttl-in-days-required": "Messages TTL in days is required.",
+ "messages-ttl-in-days-min": "Min number is 1.",
+ "messages-ttl-in-days-pattern": "Number is not valid.",
+ "mqtt-qos": "QoS",
+ "mqtt-qos-required": "QoS is required",
+ "mqtt-qos-range": "QoS values range is from 0 to 1",
"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",
+ "windows": "Windows",
+ "hints": {
+ "remote-configuration": "Enables remote configuration and management of the gateway",
+ "remote-shell": "Enables remote control of the operating system with the gateway from the Remote Shell widget",
+ "host": "Hostname or IP address of ThingsBoard server",
+ "port": "Port of MQTT service on ThingsBoard server",
+ "token": "Access token for the gateway from ThingsBoard server",
+ "client-id": "MQTT client id for the gateway form ThingsBoard server",
+ "username": "MQTT username for the gateway form ThingsBoard server",
+ "password": "MQTT password for the gateway form ThingsBoard server",
+ "ca-cert": "Path to CA certificate file",
+ "cert": "Path to certificate file",
+ "private-key": "Path to private key file",
+ "date-form": "Date format in log message",
+ "log-format": "Log message format",
+ "remote-log": "Enables remote logging and logs reading from the gateway",
+ "backup-count": "If backup count is > 0, when a rollover is done, no more than backup count files are kept - the oldest ones are deleted",
+ "storage": "Provides configuration for saving incoming data before it is sent to the ThingsBoard platform",
+ "file": "Received data saving to the hard drive",
+ "memory": "Received data saving to the RAM memory",
+ "sqlite": "Received data saving to the .db file",
+ "data-folder": "Path to folder, that will contains data (Relative or Absolute)",
+ "max-file-count": "Maximum count of file that will be created",
+ "max-read-count": "Count of messages to get from storage and send to ThingsBoard",
+ "max-records": "Maximum count of records that will be stored in one file",
+ "read-record-count": "Count of messages to get from storage and send to ThingsBoard",
+ "max-records-count": "Maximum count of data in storage before send to ThingsBoard",
+ "ttl-check-hour": "How often will Gateway check data for obsolescence",
+ "ttl-messages-day": "Maximum days that storage will save data",
+ "commands": "Commands for collecting additional statistic",
+ "attribute": "Statistic telemetry key",
+ "timeout": "Timeout for command executing",
+ "command": "The result of the command execution, will be used as the value for telemetry",
+ "check-device-activity": "Enables monitor the activity of each connected device",
+ "inactivity-timeout": "Time after whose the gateway will disconnect device",
+ "inactivity-period": "Periodicity of device activity check",
+ "minimal-pack-delay": "Delay between sending packs of messages (Decreasing this setting results in increased CPU usage)",
+ "qos": "Quality of Service in MQTT messaging (0 - at most once, 1 - at least once)",
+ "server-port": "Network port on which GRPC server will listen for incoming connections.",
+ "grpc-keep-alive-timeout": "Maximum time the server should wait for a keepalive ping response before considering the connection dead.",
+ "grpc-keep-alive": "Duration between two successive keepalive ping messages when there is no active RPC call.",
+ "grpc-min-time-between-pings": "Minimum amount of time the server should wait between sending keepalive ping messages",
+ "grpc-max-pings-without-data": "Maximum number of keepalive ping messages that the server can send without receiving any data before it considers the connection dead.",
+ "grpc-min-ping-interval-without-data": "Minimum amount of time the server should wait between sending keepalive ping messages when there is no data being sent or received.",
+ "permit-without-calls": "Allow server to keep the GRPC connection alive even when there are no active RPC calls."
+ }
},
"grid": {
"delete-item-title": "Are you sure you want to delete this item?",
@@ -3273,6 +3499,20 @@
"security": {
"security": "Security",
"general-settings": "General security settings",
+ "access-token": "Access token",
+ "access-token-required": "Access token is required",
+ "clientId": "Client ID",
+ "clientId-required": "Client ID is required",
+ "username": "Username",
+ "username-required": "Username is required",
+ "password": "Password",
+ "password-required": "Password is required",
+ "ca-cert": "CA certificate",
+ "ca-cert-required": "CA certificate is required",
+ "cert": "Certificate",
+ "cert-required": "Certificate is required",
+ "private-key": "Private Key",
+ "private-key-required": "Private Key is required",
"2fa": {
"2fa": "Two-factor authentication",
"2fa-description": "Two-factor authentication protects your account from unauthorized access. All you have to do is enter a security code when you log in.",
@@ -5102,7 +5342,9 @@
"read-only": "Read only",
"events-title": "Gateway events form title",
"events-filter": "Events filter",
- "event-key-contains": "Event key contains..."
+ "event-key-contains": "Event key contains...",
+ "is-connector": "Is Connector",
+ "state-param-name": "State parameter connector name"
},
"gauge": {
"default-color": "Default color",
@@ -6160,7 +6402,8 @@
"node-selected": "On node selected",
"element-click": "On HTML element click",
"pie-slice-click": "On slice click",
- "row-double-click": "On row double click"
+ "row-double-click": "On row double click",
+ "action-button-click": "Action button click"
}
},
"paginator" : {