corrections-after-review

This commit is contained in:
Dmitriymush 2022-07-15 18:23:10 +03:00
parent 97657284a8
commit 97a70366fa
5 changed files with 358 additions and 121 deletions

View File

@ -17,13 +17,13 @@
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component, ElementRef, HostBinding,
Component, ElementRef, EventEmitter, HostBinding,
Inject,
Injector,
Input,
NgZone,
OnDestroy,
OnInit, Optional,
OnInit, Optional, Renderer2,
StaticProvider,
ViewChild,
ViewContainerRef,
@ -136,7 +136,11 @@ import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
import cssjs from '@core/css/css';
import { DOCUMENT } from '@angular/common';
import { IAliasController } from '@core/api/widget-api.models';
import { LayoutType, LayoutWidthType } from "@home/components/dashboard-page/layout/layout.models";
import { MatButton } from '@angular/material/button';
import { VersionControlComponent } from '@home/components/vc/version-control.component';
import { TbPopoverService } from '@shared/components/popover.service';
import { tap } from 'rxjs/operators';
import { LayoutWidthType } from "@home/components/dashboard-page/layout/layout.models";
// @dynamic
@Component({
@ -292,6 +296,8 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
]
};
updateBreadcrumbs = new EventEmitter();
private rxSubscriptions = new Array<Subscription>();
get toolbarOpened(): boolean {
@ -331,6 +337,8 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
private fb: FormBuilder,
private dialog: MatDialog,
private translate: TranslateService,
private popoverService: TbPopoverService,
private renderer: Renderer2,
private ngZone: NgZone,
@Optional() @Inject('embeddedValue') private embeddedValue,
private overlay: Overlay,
@ -653,15 +661,15 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
}
public mainLayoutWidth(): string {
if (this.isEditingWidget && this.editingLayoutCtx.id === LayoutType.MAIN) {
if (this.isEditingWidget && this.editingLayoutCtx.id === 'main') {
return '100%';
} else {
return this.layouts.right.show && !this.isMobile ? this.calculateWidth(LayoutType.MAIN) : '100%';
return this.layouts.right.show && !this.isMobile ? this.calculateWidth('main') : '100%';
}
}
public mainLayoutHeight(): string {
if (!this.isEditingWidget || this.editingLayoutCtx.id === LayoutType.MAIN) {
if (!this.isEditingWidget || this.editingLayoutCtx.id === 'main') {
return '100%';
} else {
return '0px';
@ -669,10 +677,10 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
}
public rightLayoutWidth(): string {
if (this.isEditingWidget && this.editingLayoutCtx.id === LayoutType.RIGHT) {
if (this.isEditingWidget && this.editingLayoutCtx.id === 'right') {
return '100%';
} else {
return this.isMobile ? '100%' : this.calculateWidth(LayoutType.RIGHT);
return this.isMobile ? '100%' : this.calculateWidth('right');
}
}
@ -689,7 +697,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
}
if (layoutDimension) {
if (layoutDimension.type === LayoutWidthType.PERCENTAGE) {
if (layout === LayoutType.RIGHT) {
if (layout === 'right') {
return (100 - layoutDimension.leftWidthPercentage) + '%';
} else {
return layoutDimension.leftWidthPercentage + '%';
@ -1432,4 +1440,52 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
}
});
}
toggleVersionControl($event: Event, versionControlButton: MatButton) {
if ($event) {
$event.stopPropagation();
}
const trigger = versionControlButton._elementRef.nativeElement;
if (this.popoverService.hasPopover(trigger)) {
this.popoverService.hidePopover(trigger);
} else {
const versionControlPopover = this.popoverService.displayPopover(trigger, this.renderer,
this.viewContainerRef, VersionControlComponent, 'leftTop', true, null,
{
detailsMode: true,
active: true,
singleEntityMode: true,
externalEntityId: this.dashboard.externalId || this.dashboard.id,
entityId: this.dashboard.id,
entityName: this.dashboard.name,
onBeforeCreateVersion: () => {
return this.dashboardService.saveDashboard(this.dashboard).pipe(
tap((dashboard) => {
this.dashboard = this.dashboardUtils.validateAndUpdateDashboard(dashboard);
this.prevDashboard = deepClone(this.dashboard);
})
);
}
}, {}, {}, {}, true);
versionControlPopover.tbComponentRef.instance.popoverComponent = versionControlPopover;
versionControlPopover.tbComponentRef.instance.versionRestored.subscribe(() => {
this.dashboardService.getDashboard(this.currentDashboardId).subscribe((dashboard) => {
dashboard = this.dashboardUtils.validateAndUpdateDashboard(dashboard);
const data = {
dashboard,
widgetEditMode: false,
currentDashboardId: this.currentDashboardId
} as any;
this.init(data);
this.dashboardCtx.stateController.cleanupPreservedStates();
this.dashboardCtx.stateController.resetState();
this.setEditMode(true, false);
this.updateBreadcrumbs.emit();
this.ngZone.run(() => {
this.cd.detectChanges();
});
});
});
}
}
}

View File

@ -28,8 +28,3 @@ export enum LayoutWidthType {
FIXED = "fixed"
}
export enum LayoutType {
MAIN = "main",
RIGHT = "right",
LEFT = "left"
}

View File

@ -38,30 +38,31 @@
</mat-checkbox>
</div>
<div fxLayout="column" fxLayoutAlign="start center" fxLayoutGap="8px">
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px" style="width: 100%;">
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="2%" style="width: 100%;">
<button fxFlex="{{buttonFlexValue()}}"
type="button"
mat-raised-button
color="primary"
class="tb-layout-button"
(click)="openLayoutSettings(LayoutType.MAIN)"
(click)="openLayoutSettings('main')"
>
<span >{{ (layoutsFormGroup.value.right ? 'layout.left' : 'layout.main') | translate }}</span>
</button>
<button fxFlex
[fxShow]="layoutsFormGroup.get(LayoutType.RIGHT).value"
[fxShow]="layoutsFormGroup.get('right').value"
type="button"
mat-raised-button
color="primary"
class="tb-layout-button"
(click)="openLayoutSettings(LayoutType.RIGHT)">
(click)="openLayoutSettings('right')">
<span >{{ 'layout.right' | translate }}</span>
</button>
</div>
<div fxLayout="column"
fxLayoutAlign="start center"
fxLayoutGap="8px"
[fxShow]="layoutsFormGroup.get(LayoutType.RIGHT).value">
style="width: 100%;"
[fxShow]="layoutsFormGroup.get('right').value">
<mat-button-toggle-group aria-label="Select width value type"
formControlName="type"
style="width: 100%;">
@ -72,9 +73,8 @@
{{ 'layout.fixed-width' | translate }}
</mat-button-toggle>
</mat-button-toggle-group>
<div [fxShow]="layoutsFormGroup.get('type').value === LayoutWidthType.PERCENTAGE">
<div
fxLayoutAlign="start center"
<div [fxShow]="layoutsFormGroup.get('type').value === LayoutWidthType.PERCENTAGE" style="width: 100%;">
<div fxLayoutAlign="start center"
fxLayoutGap="8px"
style="width: 100%;">
<mat-slider min="10"
@ -86,11 +86,10 @@
[value]="layoutsFormGroup.get('leftWidthPercentage').value"
[displayWith]="formatSliderTooltipLabel">
</mat-slider>
</div>
<div fxLayout="column">
<div fxFlex fxLayout="column" style="width: 100%;">
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px" style="width: 100%;">
<mat-form-field class="mat-block">
<mat-form-field fxFlex class="mat-block">
<mat-label>{{ 'layout.left-width' | translate }}</mat-label>
<input matInput
formControlName="leftWidthPercentage"
@ -99,6 +98,15 @@
step="1"
min="10"
max="90">
<mat-error *ngIf="layoutsFormGroup.get('leftWidthPercentage').hasError('required')">
{{ 'layout.left-width-percentage-required' | translate }}
</mat-error>
<mat-error *ngIf="layoutsFormGroup.get('leftWidthPercentage').hasError('max')">
{{ 'layout.value-max-error' | translate: { max: 90 } }}
</mat-error>
<mat-error *ngIf="layoutsFormGroup.get('leftWidthPercentage').hasError('min')">
{{ 'layout.value-min-error' | translate: { min: 10 } }}
</mat-error>
</mat-form-field>
<mat-form-field fxFlex class="mat-block">
<mat-label>{{ 'layout.right-width' | translate }}</mat-label>
@ -108,6 +116,15 @@
step="1"
min="10"
max="90">
<mat-error *ngIf="layoutsFormGroup.get('rightWidthPercentage').hasError('required')">
{{ 'layout.right-width-percentage-required' | translate }}
</mat-error>
<mat-error *ngIf="layoutsFormGroup.get('rightWidthPercentage').hasError('max')">
{{ 'layout.value-max-error' | translate: { max: 90 } }}
</mat-error>
<mat-error *ngIf="layoutsFormGroup.get('rightWidthPercentage').hasError('min')">
{{ 'layout.value-min-error' | translate: { min: 10 } }}
</mat-error>
</mat-form-field>
</div>
<label class="tb-hint">{{'layout.layout-min-max' | translate: { min: 10, max: 90, units: "%" } }}</label>
@ -115,8 +132,9 @@
</div>
<div [fxShow]="layoutsFormGroup.get('type').value === LayoutWidthType.FIXED"
fxLayout="column"
style="width: 100%;"
fxLayoutAlign="start center">
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px" class="tb-layout-fixed-container">
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px" class="tb-layout-fixed-container" style="width: 100%;">
<label>{{ 'layout.pick-fixed-side' | translate }}</label>
<mat-radio-group aria-label="Select side"
formControlName="fixedLayout"
@ -139,8 +157,16 @@
type="number"
step="1"
min="150"
max="1700"
required>
max="1700">
<mat-error *ngIf="layoutsFormGroup.get('fixedWidth').hasError('required')">
{{ 'layout.layout-fixed-width-required' | translate }}
</mat-error>
<mat-error *ngIf="layoutsFormGroup.get('fixedWidth').hasError('max')">
{{ 'layout.value-max-error' | translate: { max: 1700 } }}
</mat-error>
<mat-error *ngIf="layoutsFormGroup.get('fixedWidth').hasError('min')">
{{ 'layout.value-min-error' | translate: { min: 150 } }}
</mat-error>
</mat-form-field>
<label class="tb-hint">{{ 'layout.layout-min-max' | translate: {min: 150, max: 1700, units: "px" } }}</label>
</div>

View File

@ -14,7 +14,7 @@
/// limitations under the License.
///
import { ChangeDetectorRef, Component, Inject, OnInit, SkipSelf} from '@angular/core';
import { Component, Inject, OnInit, SkipSelf} from '@angular/core';
import { ErrorStateMatcher } from '@angular/material/core';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { Store } from '@ngrx/store';
@ -31,7 +31,8 @@ import {
DashboardSettingsDialogComponent,
DashboardSettingsDialogData
} from '@home/components/dashboard-page/dashboard-settings-dialog.component';
import { LayoutType, LayoutWidthType } from "@home/components/dashboard-page/layout/layout.models";
import { LayoutWidthType } from "@home/components/dashboard-page/layout/layout.models";
import { Subscription } from "rxjs";
export interface ManageDashboardLayoutsDialogData {
layouts: DashboardStateLayouts;
@ -52,7 +53,7 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
LayoutWidthType = LayoutWidthType;
LayoutType = LayoutType;
subscriptions: Array<Subscription>;
submitted = false;
@ -65,19 +66,18 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
private utils: UtilsService,
private dashboardUtils: DashboardUtilsService,
private translate: TranslateService,
private dialog: MatDialog,
private cd: ChangeDetectorRef) {
private dialog: MatDialog) {
super(store, router, dialogRef);
this.layouts = this.data.layouts;
this.layoutsFormGroup = this.fb.group({
main: [{value: isDefined(this.layouts.main), disabled: true}, []],
right: [isDefined(this.layouts.right), []],
leftWidthPercentage: [50, [Validators.min(10), Validators.max(90)]],
rightWidthPercentage: [50, [Validators.min(10), Validators.max(90)]],
leftWidthPercentage: [50, [Validators.min(10), Validators.max(90), Validators.required]],
rightWidthPercentage: [50, [Validators.min(10), Validators.max(90), Validators.required]],
type: [LayoutWidthType.PERCENTAGE, []],
fixedWidth: [150, [Validators.min(150), Validators.max(1700)]],
fixedLayout: [LayoutType.MAIN, []]
fixedWidth: [150, [Validators.min(150), Validators.max(1700), Validators.required]],
fixedLayout: ['main', []]
}
);
@ -99,20 +99,29 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
}
}
if (!this.layouts[LayoutType.MAIN]) {
this.layouts[LayoutType.MAIN] = this.dashboardUtils.createDefaultLayoutData();
if (!this.layouts['main']) {
this.layouts['main'] = this.dashboardUtils.createDefaultLayoutData();
}
if (!this.layouts[LayoutType.RIGHT]) {
this.layouts[LayoutType.RIGHT] = this.dashboardUtils.createDefaultLayoutData();
if (!this.layouts['right']) {
this.layouts['right'] = this.dashboardUtils.createDefaultLayoutData();
}
this.layoutsFormGroup.get('leftWidthPercentage').valueChanges.subscribe((value) => this.layoutControlChange('rightWidthPercentage', value));
this.layoutsFormGroup.get('rightWidthPercentage').valueChanges.subscribe((value) => this.layoutControlChange('leftWidthPercentage', value));
const leftWidthPercentageSub = this.layoutsFormGroup.get('leftWidthPercentage').valueChanges
.subscribe((value) => this.layoutControlChange('rightWidthPercentage', value));
const rightWidthPercentageSub = this.layoutsFormGroup.get('rightWidthPercentage').valueChanges
.subscribe((value) => this.layoutControlChange('leftWidthPercentage', value));
this.subscriptions = [leftWidthPercentageSub, rightWidthPercentageSub];
}
ngOnInit(): void {
}
ngOnDestroy(): void {
for (let subscription of this.subscriptions) {
subscription.unsubscribe();
}
}
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
const originalErrorState = this.errorStateMatcher.isErrorState(control, form);
const customErrorState = !!(control && control.invalid && this.submitted);
@ -143,7 +152,8 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
save(): void {
this.submitted = true;
for (const l of Object.keys(this.layoutsFormGroup.controls)) {
const layouts = ['main', 'right'];
for (const l of layouts) {
const control = this.layoutsFormGroup.controls[l];
if (!control.value) {
if (this.layouts[l]) {
@ -165,7 +175,7 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
} else {
layoutDimension.fixedWidth = formValues.fixedWidth;
layoutDimension.fixedLayout = formValues.fixedLayout;
if (formValues.fixedLayout === LayoutType.MAIN) {
if (formValues.fixedLayout === 'main') {
this.layouts.main.gridSettings.layoutDimension = layoutDimension;
} else {
this.layouts.right.gridSettings.layoutDimension = layoutDimension;
@ -177,7 +187,7 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
buttonFlexValue(): number {
if (this.layoutsFormGroup.get('right').value && this.layoutsFormGroup.value.type !== LayoutWidthType.FIXED) {
return this.layoutsFormGroup.get('leftWidthPercentage').value;
return this.layoutsFormGroup.get('leftWidthPercentage').value - 1;
}
}

View File

@ -59,7 +59,9 @@
"read-more": "Read more",
"hide": "Hide",
"done": "Done",
"print": "Print"
"print": "Print",
"restore": "Restore",
"confirm": "Confirm"
},
"aggregation": {
"aggregation": "Aggregation",
@ -322,6 +324,30 @@
"queue-submit-strategy": "Submit strategy",
"queue-processing-strategy": "Processing strategy",
"queue-configuration": "Queue configuration",
"repository-settings": "Repository settings",
"repository-url": "Repository URL",
"repository-url-required": "Repository URL is required.",
"default-branch": "Default branch name",
"authentication-settings": "Authentication settings",
"auth-method": "Authentication method",
"auth-method-username-password": "Password / access token",
"auth-method-private-key": "Private key",
"password-access-token": "Password / access token",
"change-password-access-token": "Change password / access token",
"private-key": "Private key",
"drop-private-key-file-or": "Drag and drop a private key file or",
"passphrase": "Passphrase",
"enter-passphrase": "Enter passphrase",
"change-passphrase": "Change passphrase",
"check-access": "Check access",
"check-repository-access-success": "Repository access successfully verified!",
"delete-repository-settings-title": "Are you sure you want to delete repository settings?",
"delete-repository-settings-text": "Be careful, after the confirmation the repository settings will be removed and version control feature will be unavailable.",
"auto-commit-settings": "Auto-commit settings",
"auto-commit-entities": "Auto-commit entities",
"no-auto-commit-entities-prompt": "No entities configured for auto-commit",
"delete-auto-commit-settings-title": "Are you sure you want to delete auto-commit settings?",
"delete-auto-commit-settings-text": "Be careful, after the confirmation the auto-commit settings will be removed and auto-commit will be disabled for all entities.",
"2fa": {
"2fa": "Two-factor authentication",
"available-providers": "Available providers",
@ -1819,6 +1845,9 @@
"type-current-tenant": "Current Tenant",
"type-current-user": "Current User",
"type-current-user-owner": "Current User Owner",
"type-widgets-bundle": "Widgets bundle",
"type-widgets-bundles": "Widgets bundles",
"list-of-widgets-bundles": "{ count, plural, 1 {One widgets bundle} other {List of # widget bundles} }",
"search": "Search entities",
"selected-entities": "{ count, plural, 1 {1 entity} other {# entities} } selected",
"entity-name": "Entity name",
@ -2470,7 +2499,12 @@
"right-width": "Right column (%)",
"pick-fixed-side": "Fixed side: ",
"layout-fixed-width": "Fixed width (px)",
"layout-min-max": "Minimum width: {{min}}{{units}}, maximum width: {{max}}{{units}}"
"layout-min-max": "Minimum width: {{min}}{{units}}, maximum width: {{max}}{{units}}",
"value-min-error": "Value must be more then {{min}}",
"value-max-error": "Value must be less then {{max}}",
"layout-fixed-width-required": "Fixed width is required",
"right-width-percentage-required": "Right percentage is required",
"left-width-percentage-required": "Left percentage is required"
},
"legend": {
"direction": "Legend direction",
@ -2480,11 +2514,13 @@
"show-min": "Show min value",
"show-avg": "Show average value",
"show-total": "Show total value",
"show-latest": "Show latest value",
"settings": "Legend settings",
"min": "min",
"max": "max",
"avg": "avg",
"total": "total",
"latest": "latest",
"comparison-time-ago": {
"previousInterval": "(previous interval)",
"customInterval": "(custom interval)",
@ -2900,11 +2936,13 @@
},
"queue": {
"queue-name": "Queue",
"no-queues-found": "No queues found.",
"no-queues-matching": "No queues matching '{{queue}}' were found.",
"select-name": "Select queue name",
"name": "Name",
"name-required": "Queue name is required!",
"name-unique": "Queue name is not unique!",
"name-pattern": "Queue name contains a character other than ASCII alphanumerics, '.', '_' and '-'!",
"queue-required": "Queue is required!",
"topic-required": "Queue topic is required!",
"poll-interval-required": "Poll interval is required!",
@ -2936,18 +2974,25 @@
"add" : "Add queue",
"details": "Queue details",
"topic": "Topic",
"submit-strategy": "Submit Strategy",
"processing-strategy": "Processing Strategy",
"submit-settings": "Submit settings",
"submit-strategy": "Strategy type *",
"grouping-parameter": "Grouping parameter",
"processing-settings": "Retries processing settings",
"processing-strategy": "Processing type *",
"retries-settings": "Retries settings",
"polling-settings": "Polling settings",
"batch-processing": "Batch processing",
"poll-interval": "Poll interval",
"partitions": "Partitions",
"consumer-per-partition": "Consumer per partition",
"immediate-processing": "Immediate processing",
"consumer-per-partition": "Send message poll for each consumer",
"consumer-per-partition-hint": "Enable separate consumer(s) per each partition",
"processing-timeout": "Processing timeout, ms",
"processing-timeout": "Processing within, ms",
"batch-size": "Batch size",
"retries": "Retries (0 - unlimited)",
"failure-percentage": "Failure Percentage",
"pause-between-retries": "Pause between retries",
"max-pause-between-retries": "Maximal pause between retries",
"retries": "Number of retries (0 unlimited)",
"failure-percentage": "Percentage of failure messages for skipping retries",
"pause-between-retries": "Retry within, sec",
"max-pause-between-retries": "Additional retry within, sec",
"delete": "Delete queue",
"copyId": "Copy queue Id",
"idCopiedMessage": "Queue Id has been copied to clipboard",
@ -2979,6 +3024,19 @@
"retry-failed-and-timeout-hint": "Retry all failed and timed-out messages from processing pack"
}
},
"server-error": {
"general": "General server error",
"authentication": "Authentication error",
"jwt-token-expired": "JWT token expired",
"tenant-trial-expired": "Tenant trial expired",
"credentials-expired": "Credentials expired",
"permission-denied": "Permission denied",
"invalid-arguments": "Invalid arguments",
"bad-request-params": "Bad request params",
"item-not-found": "Item not found",
"too-many-requests": "Too many requests",
"too-many-updates": "Too many updates"
},
"tenant": {
"tenant": "Tenant",
"tenants": "Tenants",
@ -3008,9 +3066,7 @@
"tenant-required": "Tenant is required",
"search": "Search tenants",
"selected-tenants": "{ count, plural, 1 {1 tenant} other {# tenants} } selected",
"isolated-tb-core": "Processing in isolated ThingsBoard Core container",
"isolated-tb-rule-engine": "Processing in isolated ThingsBoard Rule Engine container",
"isolated-tb-core-details": "Requires separate microservice(s) per isolated Tenant",
"isolated-tb-rule-engine-details": "Requires separate microservice(s) per isolated Tenant"
},
"tenant-profile": {
@ -3049,75 +3105,101 @@
"export-failed-error": "Unable to export tenant profile: {{error}}",
"tenant-profile-file": "Tenant profile file",
"invalid-tenant-profile-file-error": "Unable to import tenant profile: Invalid tenant profile data structure.",
"maximum-devices": "Maximum number of devices (0 - unlimited)",
"maximum-devices-required": "Maximum number of devices is required.",
"maximum-devices-range": "Minimum number of devices can't be negative",
"maximum-assets": "Maximum number of assets (0 - unlimited)",
"maximum-assets-required": "Maximum number of assets is required.",
"maximum-assets-range": "Maximum number of assets can't be negative",
"maximum-customers": "Maximum number of customers (0 - unlimited)",
"maximum-customers-required": "Maximum number of customers is required.",
"maximum-customers-range": "Maximum number of customers can't be negative",
"maximum-users": "Maximum number of users (0 - unlimited)",
"maximum-users-required": "Maximum number of users is required.",
"maximum-users-range": "Maximum number of users can't be negative",
"maximum-dashboards": "Maximum number of dashboards (0 - unlimited)",
"maximum-dashboards-required": "Maximum number of dashboards is required.",
"maximum-dashboards-range": "Maximum number of dashboards can't be negative",
"maximum-rule-chains": "Maximum number of rule chains (0 - unlimited)",
"maximum-rule-chains-required": "Maximum number of rule chains is required.",
"maximum-rule-chains-range": "Maximum number of rule chains can't be negative",
"maximum-resources-sum-data-size": "Maximum sum of resource files size in bytes (0 - unlimited)",
"maximum-resources-sum-data-size-required": "Maximum sum of resource files size is required.",
"maximum-resources-sum-data-size-range": "Maximum sum of resource files size can`t be negative",
"maximum-ota-packages-sum-data-size": "Maximum sum of ota package files size in bytes (0 - unlimited)",
"maximum-ota-package-sum-data-size-required": "Maximum sum of ota package files size is required.",
"maximum-ota-package-sum-data-size-range": "Maximum sum of ota package files size can`t be negative",
"transport-tenant-msg-rate-limit": "Transport tenant messages rate limit.",
"transport-tenant-telemetry-msg-rate-limit": "Transport tenant telemetry messages rate limit.",
"transport-tenant-telemetry-data-points-rate-limit": "Transport tenant telemetry data points rate limit.",
"transport-device-msg-rate-limit": "Transport device messages rate limit.",
"transport-device-telemetry-msg-rate-limit": "Transport device telemetry messages rate limit.",
"transport-device-telemetry-data-points-rate-limit": "Transport device telemetry data points rate limit.",
"max-transport-messages": "Maximum number of transport messages (0 - unlimited)",
"max-transport-messages-required": "Maximum number of transport messages is required.",
"max-transport-messages-range": "Maximum number of transport messages can't be negative",
"max-transport-data-points": "Maximum number of transport data points (0 - unlimited)",
"max-transport-data-points-required": "Maximum number of transport data points is required.",
"max-transport-data-points-range": "Maximum number of transport data points can't be negative",
"max-r-e-executions": "Maximum number of Rule Engine executions (0 - unlimited)",
"max-r-e-executions-required": "Maximum number of Rule Engine executions is required.",
"max-r-e-executions-range": "Maximum number of Rule Engine executions can't be negative",
"max-j-s-executions": "Maximum number of JavaScript executions (0 - unlimited)",
"max-j-s-executions-required": "Maximum number of JavaScript executions is required.",
"max-j-s-executions-range": "Maximum number of JavaScript executions can't be negative",
"max-d-p-storage-days": "Maximum number of data points storage days (0 - unlimited)",
"max-d-p-storage-days-required": "Maximum number of data points storage days is required.",
"max-d-p-storage-days-range": "Maximum number of data points storage days can't be negative",
"default-storage-ttl-days": "Default storage TTL days (0 - unlimited)",
"default-storage-ttl-days-required": "Default storage TTL days is required.",
"default-storage-ttl-days-range": "Default storage TTL days can't be negative",
"alarms-ttl-days": "Alarms TTL days (0 - unlimited)",
"advanced-settings": "Advanced settings",
"entities": "Entities",
"rule-engine": "Rule Engine",
"time-to-live": "Time-to-live",
"alarms-and-notifications": "Alarms and notifications",
"ota-files-in-bytes": "OTA files in bytes",
"ws-title": "WS",
"unlimited": "(0 - unlimited)",
"maximum-devices": "Devices maximum number",
"maximum-devices-required": "Devices maximum number is required.",
"maximum-devices-range": "Devices maximum number can't be negative",
"maximum-assets": "Assets maximum number",
"maximum-assets-required": "Assets maximum number is required.",
"maximum-assets-range": "Assets maximum number can't be negative",
"maximum-customers": "Customers maximum number",
"maximum-customers-required": "Customers maximum number is required.",
"maximum-customers-range": "Customers maximum number can't be negative",
"maximum-users": "Users maximum number",
"maximum-users-required": "Users maximum number is required.",
"maximum-users-range": "Users maximum number can't be negative",
"maximum-dashboards": "Dashboards maximum number",
"maximum-dashboards-required": "Dashboards maximum number is required.",
"maximum-dashboards-range": "Dashboards maximum number can't be negative",
"maximum-rule-chains": "Rule chains maximum number",
"maximum-rule-chains-required": "Rule chains maximum number is required.",
"maximum-rule-chains-range": "Rule chains maximum number can't be negative",
"maximum-resources-sum-data-size": "Resource files sum size",
"maximum-resources-sum-data-size-required": "Resource files sum size is required.",
"maximum-resources-sum-data-size-range": "Resource files sum size can`t be negative",
"maximum-ota-packages-sum-data-size": "OTA package files sum size",
"maximum-ota-package-sum-data-size-required": "OTA package files sum size is required.",
"maximum-ota-package-sum-data-size-range": "OTA package files sum size can`t be negative",
"transport-tenant-msg-rate-limit": "Transport tenant messages",
"transport-tenant-telemetry-msg-rate-limit": "Transport tenant telemetry messages",
"transport-tenant-telemetry-data-points-rate-limit": "Transport tenant telemetry data points",
"transport-device-msg-rate-limit": "Transport device messages",
"transport-device-telemetry-msg-rate-limit": "Transport device telemetry messages",
"transport-device-telemetry-data-points-rate-limit": "Transport device telemetry data points",
"tenant-entity-export-rate-limit": "Entity version creation",
"tenant-entity-import-rate-limit": "Entity version load",
"max-transport-messages": "Transport messages maximum number",
"max-transport-messages-required": "Transport messages maximum number is required.",
"max-transport-messages-range": "Transport messages maximum number can't be negative",
"max-transport-data-points": "Transport data points maximum number ",
"max-transport-data-points-required": "Transport data points maximum number is required.",
"max-transport-data-points-range": "Transport data points maximum number can't be negative",
"max-r-e-executions": "Rule Engine executions maximum number",
"max-r-e-executions-required": "Rule Engine executions maximum number is required.",
"max-r-e-executions-range": "Rule Engine executions maximum number can't be negative",
"max-j-s-executions": "JavaScript executions maximum number ",
"max-j-s-executions-required": "JavaScript executions maximum number is required.",
"max-j-s-executions-range": "JavaScript executions maximum number can't be negative",
"max-d-p-storage-days": "Data points storage days maximum number",
"max-d-p-storage-days-required": "Data points storage days maximum number is required.",
"max-d-p-storage-days-range": "Data points storage days maximum number can't be negative",
"default-storage-ttl-days": "Storage TTL days by default",
"default-storage-ttl-days-required": "Storage TTL days by default is required.",
"default-storage-ttl-days-range": "Storage TTL days by default can't be negative",
"alarms-ttl-days": "Alarms TTL days",
"alarms-ttl-days-required": "Alarms TTL days required",
"alarms-ttl-days-days-range": "Alarms TTL days can't be negative",
"rpc-ttl-days": "RPC TTL days (0 - unlimited)",
"rpc-ttl-days": "RPC TTL days",
"rpc-ttl-days-required": "RPC TTL days required",
"rpc-ttl-days-days-range": "RPC TTL days can't be negative",
"max-rule-node-executions-per-message": "Maximum number of rule node executions per message (0 - unlimited)",
"max-rule-node-executions-per-message-required": "Maximum number of rule node executions per message is required.",
"max-rule-node-executions-per-message-range": "Maximum number of rule node executions per message can't be negative",
"max-emails": "Maximum number of emails sent (0 - unlimited)",
"max-emails-required": "Maximum number of emails sent is required.",
"max-emails-range": "Maximum number of emails sent can't be negative",
"max-sms": "Maximum number of SMS sent (0 - unlimited)",
"max-sms-required": "Maximum number of SMS sent is required.",
"max-sms-range": "Maximum number of SMS sent can't be negative",
"max-created-alarms": "Maximum number of alarms created (0 - unlimited)",
"max-created-alarms-required": "Maximum number of alarms created is required.",
"max-created-alarms-range": "Maximum number of alarms created can't be negative",
"max-rule-node-executions-per-message": "Rule node per message executions maximum number",
"max-rule-node-executions-per-message-required": "MRule node per message executions maximum number is required.",
"max-rule-node-executions-per-message-range": "Rule node per message executions maximum number can't be negative",
"max-emails": "Emails sent maximum number",
"max-emails-required": "Emails sent maximum number is required.",
"max-emails-range": "Emails sent maximum number can't be negative",
"max-sms": "SMS sent maximum number",
"max-sms-required": "SMS sent maximum number is required.",
"max-sms-range": "SMS sent maximum number can't be negative",
"max-created-alarms": "Alarms created maximum number",
"max-created-alarms-required": "Alarms created maximum number is required.",
"max-created-alarms-range": "Alarms created maximum number be negative",
"no-queue": "No Queue configured",
"add-queue": "Add Queue",
"queues-with-count": "Queues ({{count}})"
"queues-with-count": "Queues ({{count}})",
"tenant-rest-limits": "REST requests for tenant",
"customer-rest-limits": "REST requests for customer",
"incorrect-pattern-for-rate-limits": "The format is comma separated pairs of capacity and period (in seconds) with a colon between, e.g. 100:1,2000:60",
"too-small-value-zero": "The value must be bigger than 0",
"too-small-value-one": "The value must be bigger than 1",
"cassandra-tenant-limits-configuration": "Cassandra query for tenant",
"ws-limit-max-sessions-per-tenant": "Sessions per tenant maximum number",
"ws-limit-max-sessions-per-customer": "Sessions per customer maximum number",
"ws-limit-max-sessions-per-regular-user": "Sessions per regular user maximum number",
"ws-limit-max-sessions-per-public-user": "Sessions per public user maximum number",
"ws-limit-queue-per-session": "Message queue per session maximum size",
"ws-limit-max-subscriptions-per-tenant": "Subscriptions per tenant maximum number",
"ws-limit-max-subscriptions-per-customer": "Subscriptions per customer maximum number",
"ws-limit-max-subscriptions-per-regular-user": "Subscriptions per regular user maximum number",
"ws-limit-max-subscriptions-per-public-user": "Subscriptions per public user maximum number",
"ws-limit-updates-per-session": "WS updates per session"
},
"timeinterval": {
"seconds-interval": "{ seconds, plural, 1 {1 second} other {# seconds} }",
@ -3246,6 +3328,73 @@
"json-value-invalid": "JSON value has an invalid format",
"json-value-required": "JSON value is required."
},
"version-control": {
"version-control": "Version control",
"management": "Version control management",
"search": "Search versions",
"branch": "Branch",
"default": "Default",
"select-branch": "Select branch",
"branch-required": "Branch is required",
"create-entity-version": "Create entity version",
"version-name": "Version name",
"version-name-required": "Version name is required",
"author": "Author",
"export-relations": "Export relations",
"export-attributes": "Export attributes",
"export-credentials": "Export credentials",
"entity-versions": "Entity versions",
"versions": "Versions",
"created-time": "Created time",
"version-id": "Version ID",
"no-entity-versions-text": "No entity versions found",
"no-versions-text": "No versions found",
"copy-full-version-id": "Copy full version id",
"create-version": "Create version",
"creating-version": "Creating version... Please wait",
"nothing-to-commit": "No changes to commit",
"restore-version": "Restore version",
"restore-entity-from-version": "Restore entity from version '{{versionName}}'",
"restoring-entity-version": "Restoring entity version... Please wait",
"load-relations": "Load relations",
"load-attributes": "Load attributes",
"load-credentials": "Load credentials",
"compare-with-current": "Compare with current",
"diff-entity-with-version": "Diff with entity version '{{versionName}}'",
"previous-difference": "Previous Difference",
"next-difference": "Next Difference",
"current": "Current",
"differences": "{ count, plural, 1 {1 difference} other {# differences} }",
"create-entities-version": "Create entities version",
"default-sync-strategy": "Default sync strategy",
"sync-strategy-merge": "Merge",
"sync-strategy-overwrite": "Overwrite",
"entities-to-export": "Entities to export",
"entities-to-restore": "Entities to restore",
"sync-strategy": "Sync strategy",
"all-entities": "All entities",
"no-entities-to-export-prompt": "Please specify entities to export",
"no-entities-to-restore-prompt": "Please specify entities to restore",
"add-entity-type": "Add entity type",
"remove-all": "Remove all",
"version-create-result": "{ added, plural, 0 {No entities} 1 {1 entity} other {# entities} } added.<br/>{ modified, plural, 0 {No entities} 1 {1 entity} other {# entities} } modified.<br/>{ removed, plural, 0 {No entities} 1 {1 entity} other {# entities} } removed.",
"remove-other-entities": "Remove other entities",
"find-existing-entity-by-name": "Find existing entity by name",
"restore-entities-from-version": "Restore entities from version '{{versionName}}'",
"restoring-entities-from-version": "Restoring entities... Please wait",
"no-entities-restored": "No entities restored",
"created": "{{created}} created",
"updated": "{{updated}} updated",
"deleted": "{{deleted}} deleted",
"remove-other-entities-confirm-text": "Be careful! This will permanently <b>delete</b> <b>all</b> current entities<br/>not present in the version you want to restore.<br/><br/>Please type <b>remove other entities</b> to confirm.",
"auto-commit-to-branch": "auto-commit to <b>{{ branch }}</b> branch",
"default-create-entity-version-name": "{{entityName}} update",
"sync-strategy-merge-hint": "Creates or updates selected entities in the repository. All other repository entities are <b>not modified</b>.",
"sync-strategy-overwrite-hint": "Creates or updates selected entities in the repository. All other repository entities are <b>deleted</b>.",
"device-credentials-conflict": "Failed to load the device with external id <b>{{entityId}}</b><br/>due to the same credentials are already present in the database for another device.<br/>Please consider disabling the <b>load credentials</b> setting in the restore form.",
"missing-referenced-entity": "Failed to load the <b>{{sourceEntityTypeName}}</b> with external id <b>{{sourceEntityId}}</b><br/>because it references missing <b>{{targetEntityTypeName}}</b> with id <b>{{targetEntityId}}</b>.",
"runtime-failed": "<b>Failed:</b> {{message}}"
},
"widget": {
"widget-library": "Widgets Library",
"widget-bundle": "Widgets Bundle",
@ -4235,6 +4384,7 @@
"default-map-zoom-level": "Default map zoom level (0 - 20)",
"default-map-center-position": "Default map center position (0,0)",
"disable-scroll-zooming": "Disable scroll zooming",
"disable-double-click-zooming": "Disable double click zooming",
"disable-zoom-control-buttons": "Disable zoom control buttons",
"fit-map-bounds": "Fit map bounds to cover all markers",
"use-default-map-center-position": "Use default map center position",