Browse Source

Merge remote-tracking branch 'origin/master' into develop/3.7.1

pull/11043/head
ViacheslavKlimov 2 years ago
parent
commit
a0be4f6016
  1. 8
      application/src/main/data/json/tenant/dashboards/gateways.json
  2. 2
      rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js
  3. 1
      ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-bootstrap-config-servers.component.html
  4. 8
      ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-config-server.component.html
  5. 17
      ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-config-server.component.ts
  6. 6
      ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/battery-level-basic-config.component.html
  7. 6
      ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-service-rpc-connector.component.ts
  8. 10
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-range-list.component.ts
  9. 6
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings-panel.component.ts
  10. 8
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings.component.ts
  11. 32
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/gradient.component.html
  12. 6
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/gradient.component.scss
  13. 38
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/gradient.component.ts
  14. 6
      ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/battery-level-widget-settings.component.html
  15. 2
      ui-ngx/src/assets/locale/locale.constant-ar_AE.json
  16. 2
      ui-ngx/src/assets/locale/locale.constant-ca_ES.json
  17. 2
      ui-ngx/src/assets/locale/locale.constant-cs_CZ.json
  18. 4
      ui-ngx/src/assets/locale/locale.constant-en_US.json
  19. 2
      ui-ngx/src/assets/locale/locale.constant-es_ES.json
  20. 2
      ui-ngx/src/assets/locale/locale.constant-lt_LT.json
  21. 2
      ui-ngx/src/assets/locale/locale.constant-nl_BE.json
  22. 2
      ui-ngx/src/assets/locale/locale.constant-pl_PL.json
  23. 2
      ui-ngx/src/assets/locale/locale.constant-tr_TR.json
  24. 2
      ui-ngx/src/assets/locale/locale.constant-zh_CN.json
  25. 2
      ui-ngx/src/assets/locale/locale.constant-zh_TW.json

8
application/src/main/data/json/tenant/dashboards/gateways.json

@ -181,12 +181,12 @@
"actions": {
"actionCellButton": [
{
"name": "Docker commands",
"name": "Launch command",
"icon": "terminal",
"useShowWidgetActionFunction": null,
"showWidgetActionFunction": "return true;",
"type": "customPretty",
"customHtml": "<div class=\"container\">\n <mat-toolbar fxLayout=\"row\" color=\"primary\">\n <h2>Docker commands</h2>\n <span fxFlex></span>\n <div [tb-help]=\"'gatewayInstall'\"></div>\n <button mat-icon-button (click)=\"cancel()\" type=\"button\">\n <mat-icon class=\"material-icons\">close</mat-icon>\n </button>\n </mat-toolbar>\n <tb-gateway-command [deviceId]=\"entityId\"></tb-gateway-command>\n <div mat-dialog-actions fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button mat-button color=\"primary\"\n type=\"button\"\n (click)=\"cancel()\" cdkFocusInitial>\n {{ 'action.close' | translate }}\n </button>\n </div>\n</div>\n",
"customHtml": "<div class=\"container\">\n <mat-toolbar fxLayout=\"row\" color=\"primary\">\n <h2>{{ 'gateway.launch-command' | translate }}</h2>\n <span fxFlex></span>\n <div [tb-help]=\"'gatewayInstall'\"></div>\n <button mat-icon-button (click)=\"cancel()\" type=\"button\">\n <mat-icon class=\"material-icons\">close</mat-icon>\n </button>\n </mat-toolbar>\n <tb-gateway-command [deviceId]=\"entityId\"></tb-gateway-command>\n <div mat-dialog-actions fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button mat-button color=\"primary\"\n type=\"button\"\n (click)=\"cancel()\" cdkFocusInitial>\n {{ 'action.close' | translate }}\n </button>\n </div>\n</div>\n",
"customCss": ".container {\n display: grid;\n grid-template-rows: min-content minmax(auto, 1fr) min-content;\n height: 100%;\n max-height: 100vh;\n width: 600px;\n max-width: 100%;\n}",
"customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\n\nopenCommands();\n\nfunction openCommands() {\n customDialog.customDialog(htmlTemplate, CommandsDialogController, {panelClass: \"test\"}).subscribe();\n}\n\nfunction CommandsDialogController(instance) {\n let vm = instance;\n \n vm.entityId = entityId.id;\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n}\n",
"customResources": [],
@ -1861,7 +1861,7 @@
"padding": "8px",
"settings": {
"useMarkdownTextFunction": false,
"markdownTextPattern": "<div class=\"action-buttons-container\">\r\n <button mat-raised-button color=\"primary\"\r\n (click)=\"ctx.actionsApi.handleWidgetAction($event, ctx.actionsApi.getActionDescriptors('elementClick')[0], ctx.datasources[0].entity.id)\"\r\n >Launch command\r\n </button>\r\n</div>",
"markdownTextPattern": "<div class=\"action-buttons-container\">\r\n <button mat-raised-button color=\"primary\"\r\n (click)=\"ctx.actionsApi.handleWidgetAction($event, ctx.actionsApi.getActionDescriptors('elementClick')[0], ctx.datasources[0].entity.id)\"\r\n >{{ 'gateway.launch-command' | translate }}\r\n </button>\r\n</div>",
"applyDefaultMarkdownStyle": false,
"markdownCss": ".action-buttons-container {\r\n display: flex;\r\n flex-wrap: wrap;\r\n flex-direction: row;\r\n height: 100%;\r\n width: 100%;\r\n align-content: center;\r\n}\r\n\r\nbutton {\r\n flex-grow: 1;\r\n margin: 10px;\r\n min-width: 150px;\r\n height: auto;\r\n}"
},
@ -1887,7 +1887,7 @@
"useShowWidgetActionFunction": null,
"showWidgetActionFunction": "return true;",
"type": "customPretty",
"customHtml": "<div class=\"container\">\n <mat-toolbar fxLayout=\"row\" color=\"primary\">\n <h2>Launch command</h2>\n <span fxFlex></span>\n <div [tb-help]=\"'gatewayInstall'\"></div>\n <button mat-icon-button (click)=\"cancel()\" type=\"button\">\n <mat-icon class=\"material-icons\">close</mat-icon>\n </button>\n </mat-toolbar>\n <tb-gateway-command [deviceId]=\"entityId\"></tb-gateway-command>\n <div mat-dialog-actions fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button mat-button color=\"primary\"\n type=\"button\"\n (click)=\"cancel()\" cdkFocusInitial>\n {{ 'action.close' | translate }}\n </button>\n </div>\n</div>\n",
"customHtml": "<div class=\"container\">\n <mat-toolbar fxLayout=\"row\" color=\"primary\">\n <h2>{{ 'gateway.launch-command' | translate }}</h2>\n <span fxFlex></span>\n <div [tb-help]=\"'gatewayInstall'\"></div>\n <button mat-icon-button (click)=\"cancel()\" type=\"button\">\n <mat-icon class=\"material-icons\">close</mat-icon>\n </button>\n </mat-toolbar>\n <tb-gateway-command [deviceId]=\"entityId\"></tb-gateway-command>\n <div mat-dialog-actions fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button mat-button color=\"primary\"\n type=\"button\"\n (click)=\"cancel()\" cdkFocusInitial>\n {{ 'action.close' | translate }}\n </button>\n </div>\n</div>\n",
"customCss": ".container {\n display: grid;\n grid-template-rows: min-content minmax(auto, 1fr) min-content;\n height: 100%;\n max-height: 100vh;\n width: 600px;\n max-width: 100%;\n}",
"customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\n\nopenCommands();\n\nfunction openCommands() {\n customDialog.customDialog(htmlTemplate, CommandsDialogController, {panelClass: \"test\"}).subscribe();\n}\n\nfunction CommandsDialogController(instance) {\n let vm = instance;\n \n vm.entityId = entityId.id;\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n}\n",
"customResources": [],

2
rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js

File diff suppressed because one or more lines are too long

1
ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-bootstrap-config-servers.component.html

@ -20,6 +20,7 @@
<div *ngFor="let serverConfig of serverConfigsFromArray.controls; trackBy: trackByParams; let $index = index;">
<tb-profile-lwm2m-device-config-server
[formControl]="serverConfig"
[isBootstrap]="serverConfig.value.bootstrapServerIs"
(removeServer)="removeServerConfig($event, $index)"
(isTransportWasRunWithBootstrapChange)="updateIsTransportWasRunWithBootstrap($event)">
</tb-profile-lwm2m-device-config-server>

8
ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-config-server.component.html

@ -32,7 +32,7 @@
</div>
</div>
</mat-panel-title>
<span fxFlex></span>
<span fxFlex="100"></span>
<button *ngIf="!disabled" mat-icon-button style="min-width: 40px;"
type="button"
(click)="removeServer.emit($event)"
@ -57,8 +57,8 @@
<mat-form-field fxFlex>
<mat-label>{{ 'device-profile.lwm2m.short-id' | translate }}</mat-label>
<mat-icon *ngIf="!disabled" class="mat-primary" aria-hidden="false" aria-label="help-icon" matSuffix style="cursor:pointer;"
matTooltip="{{'device-profile.lwm2m.short-id-tooltip' | translate }}">help</mat-icon>
<input matInput type="number" min="1" max="65534" formControlName="shortServerId" required>
matTooltip="{{ (isBootstrap ? 'device-profile.lwm2m.short-id-tooltip-bootstrap': 'device-profile.lwm2m.short-id-tooltip') | translate }}">help</mat-icon>
<input matInput type="number" [min]="shortServerIdMin" [max]="shortServerIdMax" formControlName="shortServerId" required>
<mat-error *ngIf="serverFormGroup.get('shortServerId').hasError('required')">
{{ 'device-profile.lwm2m.short-id-required' | translate }}
</mat-error>
@ -67,7 +67,7 @@
</mat-error>
<mat-error *ngIf="serverFormGroup.get('shortServerId').hasError('min') ||
serverFormGroup.get('shortServerId').hasError('max')">
{{ 'device-profile.lwm2m.short-id-range' | translate }}
{{ 'device-profile.lwm2m.short-id-range' | translate : {min: shortServerIdMin, max: shortServerIdMax} }}
</mat-error>
</mat-form-field>
</div>

17
ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-config-server.component.ts

@ -38,6 +38,7 @@ import {
Lwm2mSecurityType,
Lwm2mSecurityTypeTranslationMap
} from '@shared/models/lwm2m-security-config.models';
import { coerceBoolean } from '@shared/decorators/coercion';
@Component({
selector: 'tb-profile-lwm2m-device-config-server',
@ -73,6 +74,13 @@ export class Lwm2mDeviceConfigServerComponent implements OnInit, ControlValueAcc
currentSecurityMode = null;
bootstrapDisabled = false;
shortServerIdMin = 1;
shortServerIdMax = 65534;
@Input()
@coerceBoolean()
isBootstrap = false;
@Output()
removeServer = new EventEmitter();
@ -86,13 +94,18 @@ export class Lwm2mDeviceConfigServerComponent implements OnInit, ControlValueAcc
}
ngOnInit(): void {
if (this.isBootstrap) {
this.shortServerIdMin = 0;
this.shortServerIdMax = 65535;
}
this.serverFormGroup = this.fb.group({
host: ['', Validators.required],
port: ['', [Validators.required, Validators.min(1), Validators.max(65535), Validators.pattern('[0-9]*')]],
securityMode: [Lwm2mSecurityType.NO_SEC],
serverPublicKey: [''],
clientHoldOffTime: ['', [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]],
shortServerId: ['', [Validators.required, Validators.min(1), Validators.max(65534), Validators.pattern('[0-9]*')]],
shortServerId: ['',
[Validators.required, Validators.min(this.shortServerIdMin), Validators.max(this.shortServerIdMax), Validators.pattern('[0-9]*')]],
bootstrapServerAccountTimeout: ['', [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]],
binding: [''],
lifetime: [null, [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]],
@ -199,7 +212,7 @@ export class Lwm2mDeviceConfigServerComponent implements OnInit, ControlValueAcc
if (value !== undefined) {
this.propagateChange(value);
}
}
};
private getLwm2mBootstrapSecurityInfo(securityMode = Lwm2mSecurityType.NO_SEC): Observable<ServerSecurityConfig> {
return this.deviceProfileService.getLwm2mBootstrapSecurityInfoBySecurityType(

6
ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/battery-level-basic-config.component.html

@ -102,6 +102,8 @@
<tb-color-settings formControlName="valueColor"
rangeAdvancedMode
gradientAdvancedMode
minValue="0"
maxValue="100"
[aliasController]="aliasController"
[dataKeyCallbacks]="callbacks"
[datasource]="datasource"
@ -114,6 +116,8 @@
<tb-color-settings formControlName="batteryLevelColor"
rangeAdvancedMode
gradientAdvancedMode
minValue="0"
maxValue="100"
[aliasController]="aliasController"
[dataKeyCallbacks]="callbacks"
[datasource]="datasource"
@ -125,6 +129,8 @@
<tb-color-settings formControlName="batteryShapeColor"
rangeAdvancedMode
gradientAdvancedMode
minValue="0"
maxValue="100"
[aliasController]="aliasController"
[dataKeyCallbacks]="callbacks"
[datasource]="datasource"

6
ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-service-rpc-connector.component.ts

@ -387,11 +387,11 @@ export class GatewayServiceRPCConnectorComponent implements OnInit, ControlValue
value = deepClone(value);
switch (this.connectorType) {
case ConnectorType.SNMP:
this.clearFromArrayByName("oids");
value.oids.forEach(value => {
this.clearFromArrayByName("oid");
value.oid.forEach(value => {
this.addSNMPoid(value)
})
delete value.oids;
delete value.oid;
break;
case ConnectorType.REQUEST:
this.clearFromArrayByName("httpHeaders");

10
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-range-list.component.ts

@ -111,7 +111,7 @@ export class ColorRangeListComponent implements OnInit, ControlValueAccessor, On
).subscribe(() => this.updateModel());
this.colorRangeListFormGroup.get('advancedMode').valueChanges.pipe(
takeUntil(this.destroy$)
).subscribe(() => Promise.resolve().then(() => this.popover?.updatePosition()));
).subscribe(() => setTimeout(() => {this.popover?.updatePosition();}, 0));
}
ngOnDestroy() {
@ -175,7 +175,7 @@ export class ColorRangeListComponent implements OnInit, ControlValueAccessor, On
public removeAdvancedRange(index: number) {
(this.colorRangeListFormGroup.get('rangeAdvanced') as UntypedFormArray).removeAt(index);
Promise.resolve().then(() => this.popover?.updatePosition());
setTimeout(() => {this.popover?.updatePosition();}, 0);
}
get advancedRangeFormArray(): UntypedFormArray {
@ -189,7 +189,7 @@ export class ColorRangeListComponent implements OnInit, ControlValueAccessor, On
removeRange(index: number) {
this.rangeListFormArray.removeAt(index);
this.colorRangeListFormGroup.markAsDirty();
Promise.resolve().then(() => this.popover?.updatePosition());
setTimeout(() => {this.popover?.updatePosition();}, 0);
}
rangeDrop(event: CdkDragDrop<string[]>, range: string) {
@ -212,7 +212,7 @@ export class ColorRangeListComponent implements OnInit, ControlValueAccessor, On
const advancedRangeColorsArray = this.colorRangeListFormGroup.get('rangeAdvanced') as UntypedFormArray;
const advancedRangeColorControl = this.fb.control(advancedRange, [advancedRangeValidator]);
advancedRangeColorsArray.push(advancedRangeColorControl);
Promise.resolve().then(() => this.popover?.updatePosition());
setTimeout(() => {this.popover?.updatePosition();}, 0);
}
addRange() {
@ -224,7 +224,7 @@ export class ColorRangeListComponent implements OnInit, ControlValueAccessor, On
};
this.rangeListFormArray.push(this.colorRangeControl(newRange));
this.colorRangeListFormGroup.markAsDirty();
Promise.resolve().then(() => this.popover?.updatePosition());
setTimeout(() => {this.popover?.updatePosition();}, 0);
}
}

6
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings-panel.component.ts

@ -31,7 +31,7 @@ import { deepClone } from '@core/utils';
import { WidgetService } from '@core/http/widget.service';
import { ColorSettingsComponent } from '@home/components/widget/lib/settings/common/color-settings.component';
import { IAliasController } from '@core/api/widget-api.models';
import { coerceBoolean, coerceNumber } from '@shared/decorators/coercion';
import { coerceBoolean } from '@shared/decorators/coercion';
import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.component.models';
import { Datasource } from '@shared/models/widget.models';
@ -74,11 +74,9 @@ export class ColorSettingsPanelComponent extends PageComponent implements OnInit
gradientAdvancedMode = false;
@Input()
@coerceNumber()
minValue: number;
@Input()
@coerceNumber()
maxValue: number;
colorType = ColorType;
@ -108,7 +106,7 @@ export class ColorSettingsPanelComponent extends PageComponent implements OnInit
}
);
this.colorSettingsFormGroup.get('type').valueChanges.subscribe(() => {
Promise.resolve().then(() => this.popover?.updatePosition());
setTimeout(() => {this.popover?.updatePosition();}, 0);
});
}

8
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings.component.ts

@ -33,7 +33,7 @@ import {
} from '@home/components/widget/lib/settings/common/color-settings-panel.component';
import { IAliasController } from '@core/api/widget-api.models';
import { deepClone, isDefinedAndNotNull } from '@core/utils';
import { coerceBoolean, coerceNumber } from '@shared/decorators/coercion';
import { coerceBoolean } from '@shared/decorators/coercion';
import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.component.models';
import { Datasource } from '@shared/models/widget.models';
@ -102,12 +102,10 @@ export class ColorSettingsComponent implements OnInit, ControlValueAccessor, OnD
gradientAdvancedMode = false;
@Input()
@coerceNumber()
minValue = 0;
minValue: number;
@Input()
@coerceNumber()
maxValue = 100;
maxValue: number;
colorType = ColorType;

32
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/gradient.component.html

@ -36,19 +36,21 @@
<div class="gradient-settings" [ngSwitch]="gradientFormGroup.get('advancedMode').value">
<ng-template [ngSwitchCase]="false">
<div class="gradient" formGroupName="gradient">
<div class="gradient">
<div class="gradient-container gradient-container-start">
<div translate>widgets.color.gradient-start</div>
<div class="start-gradient-container">
<div class="tb-form-row no-border no-padding" fxHide.xs [fxHide]="!minValue?.toString()?.length">
<div class="gradient-text" translate>widgets.color.start-value</div>
<div class="tb-form-row no-border no-padding">
<div class="gradient-text" fxHide.xs translate>widgets.color.start-value</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput type="number" min="0" disabled [(ngModel)]="minValue" [ngModelOptions]="{standalone: true}" placeholder="{{ 'widget-config.set' | translate }}">
<input matInput type="number" formControlName="minValue" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
</div>
<tb-color-input asBoxInput
formControlName="start">
</tb-color-input>
<ng-container formGroupName="gradient">
<tb-color-input asBoxInput
formControlName="start">
</tb-color-input>
</ng-container>
</div>
</div>
</div>
@ -94,19 +96,21 @@
<mat-icon>add</mat-icon>
</button>
<div class="gradient" formGroupName="gradient">
<div class="gradient">
<div class="gradient-container gradient-container-end">
<div translate>widgets.color.gradient-end</div>
<div class="end-gradient-container">
<div class="tb-form-row no-border no-padding" fxHide.xs [fxHide]="!maxValue?.toString()?.length">
<div class="gradient-text" translate>widgets.color.end-value</div>
<div class="tb-form-row no-border no-padding">
<div class="gradient-text" fxHide.xs translate>widgets.color.end-value</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput type="number" min="0" disabled [(ngModel)]="maxValue" [ngModelOptions]="{standalone: true}" placeholder="{{ 'widget-config.set' | translate }}">
<input matInput type="number" formControlName="maxValue" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
</div>
<tb-color-input asBoxInput
formControlName="end">
</tb-color-input>
<ng-container formGroupName="gradient">
<tb-color-input asBoxInput
formControlName="end">
</tb-color-input>
</ng-container>
</div>
</div>
</div>

6
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/gradient.component.scss

@ -23,7 +23,7 @@
.gradient-preview {
width: 100%;
padding: 40px 12px 0;
padding: 40px 15px 0;
.gradient-background {
position: relative;
height: 56px;
@ -120,11 +120,13 @@
display: flex;
align-items: center;
justify-content: center;
width: 33px;
width: 38px;
height: 24px;
border-radius: 4px;
background-color: rgba(0, 0, 0, 0.06);
&-text {
text-overflow: ellipsis;
overflow: hidden;
font-size: 14px;
font-weight: 500;
}

38
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/gradient.component.ts

@ -31,7 +31,7 @@ import { takeUntil } from 'rxjs/operators';
import { CdkDragDrop } from '@angular/cdk/drag-drop';
import { IAliasController } from '@core/api/widget-api.models';
import { DomSanitizer } from '@angular/platform-browser';
import { coerceBoolean, coerceNumber } from '@shared/decorators/coercion';
import { coerceBoolean } from '@shared/decorators/coercion';
import { isDefinedAndNotNull } from '@core/utils';
import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.component.models';
import { Datasource } from '@shared/models/widget.models';
@ -71,11 +71,9 @@ export class GradientComponent implements OnInit, ControlValueAccessor, OnDestro
datasource: Datasource;
@Input()
@coerceNumber()
minValue: number;
@Input()
@coerceNumber()
maxValue: number;
@Input()
@ -111,7 +109,9 @@ export class GradientComponent implements OnInit, ControlValueAccessor, OnDestro
source: [{type: ValueSourceType.constant}],
color: ['rgba(255, 0, 0, 1)']
})
})
}),
minValue: {value: 0, disabled: isFinite(this.minValue)},
maxValue: {value: 100, disabled: isFinite(this.maxValue)}
});
this.gradientFormGroup.valueChanges.pipe(
@ -119,7 +119,7 @@ export class GradientComponent implements OnInit, ControlValueAccessor, OnDestro
).subscribe(() => this.updateModel());
this.gradientFormGroup.get('advancedMode').valueChanges.pipe(
takeUntil(this.destroy$)
).subscribe(() => Promise.resolve().then(() => this.popover?.updatePosition()));
).subscribe(() => setTimeout(() => {this.popover?.updatePosition();}, 0));
}
ngOnDestroy() {
@ -141,6 +141,8 @@ export class GradientComponent implements OnInit, ControlValueAccessor, OnDestro
writeValue(value: ColorGradientSettings): void {
if (isDefinedAndNotNull(value)) {
this.gradientFormGroup.get('advancedMode').patchValue(value.advancedMode, {emitEvent: false});
this.gradientFormGroup.get('minValue').patchValue(isFinite(value.minValue) ? value.minValue : this.minValue, {emitEvent: false});
this.gradientFormGroup.get('maxValue').patchValue(isFinite(value.maxValue) ? value.maxValue : this.maxValue, {emitEvent: false});
if (value?.gradient?.length) {
this.gradientFormGroup.get('gradient').get('start').patchValue(value.gradient[0], {emitEvent: false});
this.gradientFormGroup.get('gradient').get('end').patchValue(value.gradient[value.gradient.length - 1], {emitEvent: false});
@ -165,10 +167,10 @@ export class GradientComponent implements OnInit, ControlValueAccessor, OnDestro
this.advancedGradientListFormArray.value.map((v, i) => this.pointer(shift * (i + 1), i+1, null, true)).join('') +
`<div class="pointer end"></div>`;
} else {
const point = (+this.maxValue - +this.minValue) / (this.gradientListFormArray.value.length + 1);
const min = this.gradientFormGroup.get('minValue').value || 0;
const max = this.gradientFormGroup.get('maxValue').value || 100;
const point = (+max - +min) / (this.gradientListFormArray.value.length + 1);
const shift = 100 / (this.gradientListFormArray.value.length + 1);
const min = isDefinedAndNotNull(this.minValue) ? this.minValue : 0;
const max = isDefinedAndNotNull(this.maxValue) ? this.maxValue : 100;
return `<div class="pointer start"><div class="pointer-value"><span class="pointer-value-text">${min}</span></div></div>` +
this.gradientListFormArray.value.map((v, i) => this.pointer(shift * (i + 1), i+1, point)).join('') +
`<div class="pointer end"><div class="pointer-value"><span class="pointer-value-text">${max}</span></div></div>`;
@ -180,7 +182,8 @@ export class GradientComponent implements OnInit, ControlValueAccessor, OnDestro
return `<div class="pointer" style="left: ${shift}%"></div>`;
} else {
return `<div class="pointer" style="left: ${shift}%">` +
`<div class="pointer-value"><span class="pointer-value-text">${Math.floor(+this.minValue + (value * index))}</span></div></div>`;
`<div class="pointer-value"><span class="pointer-value-text">` +
`${Math.floor(+this.gradientFormGroup.get('minValue').value + (value * index))}</span></div></div>`;
}
}
@ -233,7 +236,7 @@ export class GradientComponent implements OnInit, ControlValueAccessor, OnDestro
this.gradientListFormArray.removeAt(index);
}
this.gradientFormGroup.markAsDirty();
Promise.resolve().then(() => this.popover?.updatePosition());
setTimeout(() => {this.popover?.updatePosition();}, 0);
}
gradientDrop(event: CdkDragDrop<string[]>, advanced = false) {
@ -252,19 +255,18 @@ export class GradientComponent implements OnInit, ControlValueAccessor, OnDestro
this.gradientListFormArray.push(this.colorGradientControl('rgba(0,0,0,0.87)'));
}
this.gradientFormGroup.markAsDirty();
Promise.resolve().then(() => this.popover?.updatePosition());
setTimeout(() => {this.popover?.updatePosition();}, 0);
}
updateModel() {
const gradient = this.gradientFormGroup.getRawValue();
this.propagateChange(
{
advancedMode: this.gradientFormGroup.value.advancedMode,
gradient: [this.gradientFormGroup.value.gradient.start,
...this.gradientFormGroup.value.gradient.gradientList.map(item => item.color),
this.gradientFormGroup.value.gradient.end],
gradientAdvanced: [this.gradientFormGroup.value.gradientAdvanced.start,
...this.gradientFormGroup.value.gradientAdvanced.gradientList,
this.gradientFormGroup.value.gradientAdvanced.end]
advancedMode: gradient.advancedMode,
gradient: [gradient.gradient.start, ...gradient.gradient.gradientList.map(item => item.color), gradient.gradient.end],
gradientAdvanced: [gradient.gradientAdvanced.start, ...gradient.gradientAdvanced.gradientList, gradient.gradientAdvanced.end],
minValue: gradient.minValue,
maxValue: gradient.maxValue
}
);
}

6
ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/battery-level-widget-settings.component.html

@ -51,6 +51,8 @@
<tb-color-settings formControlName="valueColor"
rangeAdvancedMode
gradientAdvancedMode
minValue="0"
maxValue="100"
[aliasController]="aliasController"
[dataKeyCallbacks]="dataKeyCallbacks"
[datasource]="datasource"
@ -63,6 +65,8 @@
<tb-color-settings formControlName="batteryLevelColor"
rangeAdvancedMode
gradientAdvancedMode
minValue="0"
maxValue="100"
[aliasController]="aliasController"
[dataKeyCallbacks]="dataKeyCallbacks"
[datasource]="datasource"
@ -74,6 +78,8 @@
<tb-color-settings formControlName="batteryShapeColor"
rangeAdvancedMode
gradientAdvancedMode
minValue="0"
maxValue="100"
[aliasController]="aliasController"
[dataKeyCallbacks]="dataKeyCallbacks"
[datasource]="datasource"

2
ui-ngx/src/assets/locale/locale.constant-ar_AE.json

@ -2000,7 +2000,7 @@
"short-id": "معرف الخادم القصير",
"short-id-tooltip": "معرف الخادم القصير. يُستخدم كرابط لربط نموذج كائن الخادم.\nهذا المعرف يُميز بشكل فريد كل خادم LwM2M المُعد للعميل LwM2M.\nيجب ضبط المورد عندما يكون مورد الخادم التمهيدي بقيمة 'false'.\nلا يجب استخدام قيم المعرف ID:0 و ID:65535 لتحديد خادم LwM2M.",
"short-id-required": "معرف الخادم القصير مطلوب.",
"short-id-range": "يجب أن يكون معرف الخادم القصير ضمن نطاق من 1 إلى 65534.",
"short-id-range": "يجب أن يكون معرف الخادم القصير ضمن نطاق من {{ min }} إلى {{ max }}.",
"short-id-pattern": "يجب أن يكون معرف الخادم القصير عددًا صحيحًا موجبًا.",
"lifetime": "مدة تسجيل العميل",
"lifetime-required": "مدة تسجيل العميل مطلوبة.",

2
ui-ngx/src/assets/locale/locale.constant-ca_ES.json

@ -1632,7 +1632,7 @@
"short-id": "Identificador curt del servidor",
"short-id-tooltip": "Identificador curt del servidor. S'utilitza com a enllaç a la instància d'objecte del servidor associada.\nAquest identificador identifica de manera única cada servidor LwM2M configurat per al client LwM2M.\nEl recurs S'HA d'establir quan el recurs del servidor Bootstrap té un valor 'fals'.\nEls valors ID:0 i ID :65535 NO S'HAN d'utilitzar per identificar el servidor LwM2M.",
"short-id-required": "Cal identificador curt del servidor.",
"short-id-range": "L'identificador de servidor curt hauria d'estar entre 1 i 65534.",
"short-id-range": "L'identificador de servidor curt hauria d'estar entre {{ min }} i {{ max }}.",
"short-id-pattern": "L'identificador de servidor curt ha de ser un nombre enter positiu.",
"lifetime": "Vida útil del registre del client",
"lifetime-required": "Cal vida útil del registre del client.",

2
ui-ngx/src/assets/locale/locale.constant-cs_CZ.json

@ -1247,7 +1247,7 @@
"mode": "Režim konfigurace bezpečnosti",
"short-id": "Krátké ID",
"short-id-required": "Krátké ID je povinné.",
"short-id-range": "Krátké ID by mělo být v rozsahu od 1 do 65534.",
"short-id-range": "Krátké ID by mělo být v rozsahu od {{ min }} do {{ max }}.",
"short-id-pattern": "Krátké ID musí být kladné celé číslo.",
"lifetime": "Doba platnosti registrace klienta",
"lifetime-required": "Doba platnosti registrace klienta je povinná.",

4
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -1860,8 +1860,9 @@
"server": "Server",
"short-id": "Short server ID",
"short-id-tooltip": "Server short Id. Used as link to associate server Object Instance.\nThis identifier uniquely identifies each LwM2M Server configured for the LwM2M Client.\nResource MUST be set when the Bootstrap-Server Resource has a value of 'false'.\nThe values ID:0 and ID:65535 values MUST NOT be used for identifying the LwM2M Server.",
"short-id-tooltip-bootstrap": "Server short Id. Used as link to associate server Object Instance.\nThis identifier uniquely identifies each LwM2M Server configured for the LwM2M Client.\nResource MUST be set when the Bootstrap-Server Resource has a value of 'false'.",
"short-id-required": "Short server ID is required.",
"short-id-range": "Short server ID should be in a range from 1 to 65534.",
"short-id-range": "Short server ID should be in a range from {{ min }} to {{ max }}.",
"short-id-pattern": "Short server ID must be a positive integer.",
"lifetime": "Client registration lifetime",
"lifetime-required": "Client registration lifetime is required.",
@ -2835,6 +2836,7 @@
"enable-remote-logging": "Enable remote logging",
"ellipsis-chips-text": "+ {{count}} more",
"launch-gateway": "Launch gateway",
"launch-command": "Launch command",
"launch-docker-compose": "Start the gateway using the following command in the terminal from folder with docker-compose.yml file",
"logs-configuration": "Logs configuration",
"create-new-gateway": "Create a new gateway",

2
ui-ngx/src/assets/locale/locale.constant-es_ES.json

@ -1757,7 +1757,7 @@
"short-id": "Short server ID",
"short-id-tooltip": "Id corto del servidor. Usado como enlace para asociar las instancias de objetos del servidor.\nEste identificador sirve para identificar únicamente cada servidor LwM2M configurado para el cliente LwM2M.\nLos recursos DEBEN ser ajustados cuando el servidor Bootstrap tenga un valor de 'false'.\nLos valores ID:0 and ID:65535 NO DEBEN ser usados para identificar al servidor LwM2M.",
"short-id-required": "Se requiere Short server ID.",
"short-id-range": "Short server ID debe estar en un rango de 1 a 65534.",
"short-id-range": "Short server ID debe estar en un rango de {{ min }} a {{ max }}.",
"short-id-pattern": "Short server ID debe ser un número entero positivo.",
"lifetime": "Ciclo de vida registro de cliente (Registration Lifetime)",
"lifetime-required": "Se requiere ciclo de vida.",

2
ui-ngx/src/assets/locale/locale.constant-lt_LT.json

@ -1970,7 +1970,7 @@
"short-id": "Short server ID",
"short-id-tooltip": "Server short Id. Used as link to associate server Object Instance.\nThis identifier uniquely identifies each LwM2M Server configured for the LwM2M Client.\nResource MUST be set when the Bootstrap-Server Resource has a value of 'false'.\nThe values ID:0 and ID:65535 values MUST NOT be used for identifying the LwM2M Server.",
"short-id-required": "Short server ID is required.",
"short-id-range": "Short server ID should be in a range from 1 to 65534.",
"short-id-range": "Short server ID should be in a range from {{ min }} to {{ max }}.",
"short-id-pattern": "Short server ID must be a positive integer.",
"lifetime": "Client registration lifetime",
"lifetime-required": "Client registration lifetime is required.",

2
ui-ngx/src/assets/locale/locale.constant-nl_BE.json

@ -1857,7 +1857,7 @@
"short-id": "Korte server-ID",
"short-id-tooltip": "Server-id kort Id. Wordt gebruikt als koppeling naar het Object-exemplaar van de koppeling.\nDeze id identificeert elke LwM2M-server die is geconfigureerd voor de LwM2M-client op unieke wijze.\nResource MOET worden ingesteld wanneer de Bootstrap-Server Resource een waarde van 'false' heeft.\nDe waarden ID:0 en ID:65535 mogen NIET worden gebruikt voor het identificeren van de LwM2M-server.",
"short-id-required": "Een korte server-ID is vereist.",
"short-id-range": "Korte server-ID moet tussen 1 en 65534 liggen.",
"short-id-range": "Korte server-ID moet tussen {{ min }} en {{ max }} liggen.",
"short-id-pattern": "Korte server-ID moet een positief geheel getal zijn.",
"lifetime": "Levensduur klantregistratie",
"lifetime-required": "Levenslange registratie van klanten is vereist.",

2
ui-ngx/src/assets/locale/locale.constant-pl_PL.json

@ -1976,7 +1976,7 @@
"short-id": "Krótki identyfikator serwera",
"short-id-tooltip": "Krótki identyfikator serwera. ",
"short-id-required": "Krótki identyfikator serwera jest wymagany.",
"short-id-range": "Krótki identyfikator serwera powinien mieścić się w zakresie od 1 do 65534.",
"short-id-range": "Krótki identyfikator serwera powinien mieścić się w zakresie od {{ min }} do {{ max }}.",
"short-id-pattern": "Krótki identyfikator serwera musi być dodatnią liczbą całkowitą.",
"lifetime": "Okres rejestracji klienta",
"lifetime-required": "Okres rejestracji klienta jest wymagany.",

2
ui-ngx/src/assets/locale/locale.constant-tr_TR.json

@ -1260,7 +1260,7 @@
"mode": "Güvenlik yapılandırma modu",
"short-id": "Kısa ID",
"short-id-required": "Kısa ID gerekli.",
"short-id-range": "Kısa ID 1 ile 65534 aralığında olmalıdır.",
"short-id-range": "Kısa ID {{ min }} ile {{ max }} aralığında olmalıdır.",
"short-id-pattern": "Kısa ID pozitif bir tam sayı olmalıdır.",
"lifetime": "İstemci kayıt ömrü",
"lifetime-required": "İstemci kayıt ömrü gerekli.",

2
ui-ngx/src/assets/locale/locale.constant-zh_CN.json

@ -1794,7 +1794,7 @@
"short-id": "服务器ID",
"short-id-tooltip": "服务器ID用作关联服务器对象实例的链接。",
"short-id-required": "服务器ID必填。",
"short-id-range": "服务器ID应在1到65534范围内。",
"short-id-range": "服务器ID应在{{ min }}到{{ max }}范围内。",
"short-id-pattern": "服务器ID必须是一个正整数。",
"lifetime": "客户端注册生命周期",
"lifetime-required": "客户端注册生命周期必填。",

2
ui-ngx/src/assets/locale/locale.constant-zh_TW.json

@ -1432,7 +1432,7 @@
"short-id": "短伺服器ID",
"short-id-tooltip": "短伺服器ID。用作關聯伺服器物件實例的鏈接。 \n此標識符唯一標識為LwM2M伺服器客戶端配置的每個LwM2M 伺服器。\n當引導伺服器資源的值為'false'時,必須設置資源。\nID:0值和ID:65535值不得用於識別LwM2M伺服器。.",
"short-id-required": "短伺服器ID必填",
"short-id-range": "短伺服器ID長度需介於1到65534。",
"short-id-range": "短伺服器ID長度需介於{{ min }}到{{ max }}。",
"short-id-pattern": "短伺服器ID需為正整數",
"lifetime": "客戶登記使用期限",
"lifetime-required": "客戶登記使用期限必填",

Loading…
Cancel
Save