-
-
-
+
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-range-list.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-range-list.component.scss
index 63265f6dbc..21cbd8e287 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-range-list.component.scss
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-range-list.component.scss
@@ -13,24 +13,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+@import '../../../../../../../../scss/constants';
-:host {
- .range {
- display: flex;
- flex: 1;
- align-items: center;
- flex-direction: row;
-
- &-container {
- display: flex;
- flex: 1;
- flex-direction: row;
- align-items: center;
- gap: 12px;
- padding: 8px;
- margin-right: 12px;
- border: 1px solid rgba(0, 0, 0, 0.12);
- border-radius: 6px;
- }
+.range-container {
+ display: flex;
+ flex: 1;
+ flex-direction: row;
+ align-items: center;
+ gap: 12px;
+ padding: 8px;
+ margin-right: 12px;
+ border: 1px solid rgba(0, 0, 0, 0.12);
+ border-radius: 6px;
+}
+.tb-add-color-range {
+ button {
+ width: 100%;
+ }
+}
+.tb-value-range-text {
+ width: 64px;
+ font-size: 14px;
+ color: rgba(0, 0, 0, 0.38);
+ @media #{$mat-xs} {
+ width: auto;
+ }
+ &.tb-value-range-text-to {
+ text-align: center;
}
}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-range-list.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-range-list.component.ts
index cbc258caa7..c12ba38718 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-range-list.component.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-range-list.component.ts
@@ -14,7 +14,7 @@
/// limitations under the License.
///
-import { Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core';
+import { Component, forwardRef, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import {
AbstractControl,
ControlValueAccessor,
@@ -62,7 +62,8 @@ export function advancedRangeValidator(control: AbstractControl): ValidationErro
useExisting: forwardRef(() => ColorRangeListComponent),
multi: true
}
- ]
+ ],
+ encapsulation: ViewEncapsulation.None
})
export class ColorRangeListComponent implements OnInit, ControlValueAccessor, OnDestroy {
@@ -108,6 +109,9 @@ export class ColorRangeListComponent implements OnInit, ControlValueAccessor, On
this.colorRangeListFormGroup.valueChanges.pipe(
takeUntil(this.destroy$)
).subscribe(() => this.updateModel());
+ this.colorRangeListFormGroup.get('advancedMode').valueChanges.pipe(
+ takeUntil(this.destroy$)
+ ).subscribe(() => Promise.resolve().then(() => this.popover?.updatePosition()));
}
ngOnDestroy() {
@@ -171,6 +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());
}
get advancedRangeFormArray(): UntypedFormArray {
@@ -184,7 +189,7 @@ export class ColorRangeListComponent implements OnInit, ControlValueAccessor, On
removeRange(index: number) {
this.rangeListFormArray.removeAt(index);
this.colorRangeListFormGroup.markAsDirty();
- setTimeout(() => {this.popover?.updatePosition();}, 0);
+ Promise.resolve().then(() => this.popover?.updatePosition());
}
rangeDrop(event: CdkDragDrop
, range: string) {
@@ -207,6 +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());
}
addRange() {
@@ -218,7 +224,7 @@ export class ColorRangeListComponent implements OnInit, ControlValueAccessor, On
};
this.rangeListFormArray.push(this.colorRangeControl(newRange));
this.colorRangeListFormGroup.markAsDirty();
- setTimeout(() => {this.popover?.updatePosition();}, 0);
+ Promise.resolve().then(() => this.popover?.updatePosition());
}
}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings-panel.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings-panel.component.scss
index 1b0fda35b3..31b5f3745c 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings-panel.component.scss
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings-panel.component.scss
@@ -55,17 +55,6 @@
}
.tb-form-row {
height: auto;
- .tb-value-range-text {
- width: 64px;
- font-size: 14px;
- color: rgba(0, 0, 0, 0.38);
- @media #{$mat-xs} {
- width: auto;
- }
- &.tb-value-range-text-to {
- text-align: center;
- }
- }
}
button.mat-mdc-button-base.tb-add-color-range {
&:not(:disabled) {
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings-panel.component.ts
index 94cb084512..89edf5323a 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings-panel.component.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings-panel.component.ts
@@ -20,7 +20,8 @@ import {
ColorSettings,
ColorType,
colorTypeTranslations,
- defaultGradient
+ defaultGradient,
+ defaultRange
} from '@shared/models/widget-settings.models';
import { TbPopoverComponent } from '@shared/components/popover.component';
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
@@ -102,12 +103,12 @@ export class ColorSettingsPanelComponent extends PageComponent implements OnInit
type: [this.colorSettings?.type || ColorType.constant, []],
color: [this.colorSettings?.color, []],
gradient: [this.colorSettings?.gradient || defaultGradient(this.minValue, this.maxValue), []],
- rangeList: [this.colorSettings?.rangeList, []],
+ rangeList: [this.colorSettings?.rangeList || defaultRange(), []],
colorFunction: [this.colorSettings?.colorFunction, []]
}
);
this.colorSettingsFormGroup.get('type').valueChanges.subscribe(() => {
- setTimeout(() => {this.popover?.updatePosition();}, 0);
+ Promise.resolve().then(() => this.popover?.updatePosition());
});
}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings.component.ts
index 11837804df..0c879f52e2 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings.component.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings.component.ts
@@ -103,11 +103,11 @@ export class ColorSettingsComponent implements OnInit, ControlValueAccessor, OnD
@Input()
@coerceNumber()
- minValue: number;
+ minValue = 0;
@Input()
@coerceNumber()
- maxValue: number;
+ maxValue = 100;
colorType = ColorType;
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/gradient.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/gradient.component.scss
index 38f320b940..25e14cb0d5 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/gradient.component.scss
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/gradient.component.scss
@@ -16,11 +16,36 @@
@import "../../../../../../../../scss/constants";
-
:host {
overflow: auto;
height: 100%;
max-height: 420px;
+
+ .gradient-preview {
+ width: 100%;
+ padding: 40px 12px 0;
+ .gradient-background {
+ position: relative;
+ height: 56px;
+ border-radius: 8px;
+ }
+ }
+
+ .gradient-settings {
+ flex: 1;
+ gap: 16px;
+ display: flex;
+ flex-direction: column;
+ }
+
+ .tb-add-gradient {
+ margin-right: 92px;
+ @media #{$mat-lt-lg} {
+ margin-right: 52px;
+ }
+ }
+}
+::ng-deep {
.gradient {
display: flex;
flex: 1;
@@ -67,32 +92,6 @@
}
}
}
-
- .gradient-preview {
- width: 100%;
- padding: 40px 12px 0;
- .gradient-background {
- position: relative;
- height: 56px;
- border-radius: 8px;
- }
- }
-
- .gradient-settings {
- flex: 1;
- gap: 16px;
- display: flex;
- flex-direction: column;
- }
-
- .tb-add-gradient {
- margin-right: 92px;
- @media #{$mat-lt-lg} {
- margin-right: 52px;
- }
- }
-}
-::ng-deep {
.gradient-background {
.pointer {
position: absolute;
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/gradient.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/gradient.component.ts
index e326cff0d4..8b78190f5a 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/gradient.component.ts
+++ b/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 } from '@shared/decorators/coercion';
+import { coerceBoolean, coerceNumber } 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,10 +71,12 @@ export class GradientComponent implements OnInit, ControlValueAccessor, OnDestro
datasource: Datasource;
@Input()
- minValue: string;
+ @coerceNumber()
+ minValue: number;
@Input()
- maxValue: string;
+ @coerceNumber()
+ maxValue: number;
@Input()
@coerceBoolean()
@@ -115,6 +117,9 @@ export class GradientComponent implements OnInit, ControlValueAccessor, OnDestro
this.gradientFormGroup.valueChanges.pipe(
takeUntil(this.destroy$)
).subscribe(() => this.updateModel());
+ this.gradientFormGroup.get('advancedMode').valueChanges.pipe(
+ takeUntil(this.destroy$)
+ ).subscribe(() => Promise.resolve().then(() => this.popover?.updatePosition()));
}
ngOnDestroy() {
@@ -228,7 +233,7 @@ export class GradientComponent implements OnInit, ControlValueAccessor, OnDestro
this.gradientListFormArray.removeAt(index);
}
this.gradientFormGroup.markAsDirty();
- setTimeout(() => {this.popover?.updatePosition();}, 0);
+ Promise.resolve().then(() => this.popover?.updatePosition());
}
gradientDrop(event: CdkDragDrop, advanced = false) {
@@ -247,7 +252,7 @@ export class GradientComponent implements OnInit, ControlValueAccessor, OnDestro
this.gradientListFormArray.push(this.colorGradientControl('rgba(0,0,0,0.87)'));
}
this.gradientFormGroup.markAsDirty();
- setTimeout(() => {this.popover?.updatePosition();}, 0);
+ Promise.resolve().then(() => this.popover?.updatePosition());
}
updateModel() {
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.html
index 86cd0ff825..62cacf0730 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.html
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.html
@@ -41,17 +41,9 @@
+
+
{{ 'widgets.gauge.value' | translate }}
@@ -160,14 +166,6 @@
-
-
-
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.ts
index 9f55ad90a1..5a4289a8d2 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.ts
@@ -138,7 +138,7 @@ export class DigitalGaugeWidgetSettingsComponent extends WidgetSettingsComponent
protected onSettingsSet(settings: WidgetSettings) {
if (!settings.barColor) {
- settings.barColor = constantColor(settings.gaugeColor);
+ settings.barColor = constantColor(settings.defaultColor || '#2196f3');
if (settings.fixedLevelColors.length) {
settings.barColor.rangeList = {
@@ -192,7 +192,6 @@ export class DigitalGaugeWidgetSettingsComponent extends WidgetSettingsComponent
dashThickness: [settings.dashThickness, [Validators.min(0)]],
roundedLineCap: [settings.roundedLineCap, []],
- defaultColor: [settings.defaultColor, []],
gaugeColor: [settings.gaugeColor, []],
barColor: [settings.barColor],
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/battery-level-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/battery-level-widget-settings.component.html
index 2f83df7efa..c34b51a36b 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/battery-level-widget-settings.component.html
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/battery-level-widget-settings.component.html
@@ -63,8 +63,6 @@
+
+
diff --git a/ui-ngx/src/app/modules/home/pages/admin/mobile-app-settings.component.ts b/ui-ngx/src/app/modules/home/pages/admin/mobile-app-settings.component.ts
index edba183919..0f2527d833 100644
--- a/ui-ngx/src/app/modules/home/pages/admin/mobile-app-settings.component.ts
+++ b/ui-ngx/src/app/modules/home/pages/admin/mobile-app-settings.component.ts
@@ -57,14 +57,18 @@ export class MobileAppSettingsComponent extends PageComponent implements HasConf
if (value) {
this.mobileAppSettingsForm.get('androidConfig.appPackage').disable({emitEvent: false});
this.mobileAppSettingsForm.get('androidConfig.sha256CertFingerprints').disable({emitEvent: false});
+ this.mobileAppSettingsForm.get('androidConfig.storeLink').disable({emitEvent: false});
this.mobileAppSettingsForm.get('iosConfig.appId').disable({emitEvent: false});
+ this.mobileAppSettingsForm.get('iosConfig.storeLink').disable({emitEvent: false});
} else {
if (this.mobileAppSettingsForm.get('androidConfig.enabled').value) {
this.mobileAppSettingsForm.get('androidConfig.appPackage').enable({emitEvent: false});
this.mobileAppSettingsForm.get('androidConfig.sha256CertFingerprints').enable({emitEvent: false});
+ this.mobileAppSettingsForm.get('androidConfig.storeLink').enable({emitEvent: false});
}
if (this.mobileAppSettingsForm.get('iosConfig.enabled').value) {
this.mobileAppSettingsForm.get('iosConfig.appId').enable({emitEvent: false});
+ this.mobileAppSettingsForm.get('iosConfig.storeLink').enable({emitEvent: false});
}
}
});
@@ -128,11 +132,13 @@ export class MobileAppSettingsComponent extends PageComponent implements HasConf
androidConfig: this.fb.group({
enabled: [true],
appPackage: [{value: '', disabled: true}, [Validators.required]],
- sha256CertFingerprints: [{value: '', disabled: true}, [Validators.required]]
+ sha256CertFingerprints: [{value: '', disabled: true}, [Validators.required]],
+ storeLink: ['', [Validators.required]]
}),
iosConfig: this.fb.group({
enabled: [true],
- appId: [{value: '', disabled: true}, [Validators.required]]
+ appId: [{value: '', disabled: true}, [Validators.required]],
+ storeLink: ['', [Validators.required]]
}),
qrCodeConfig: this.fb.group({
showOnHomePage: [true],
@@ -154,10 +160,12 @@ export class MobileAppSettingsComponent extends PageComponent implements HasConf
if (!this.mobileAppSettingsForm.get('useDefaultApp').value) {
this.mobileAppSettingsForm.get('androidConfig.appPackage').enable({emitEvent: false});
this.mobileAppSettingsForm.get('androidConfig.sha256CertFingerprints').enable({emitEvent: false});
+ this.mobileAppSettingsForm.get('androidConfig.storeLink').enable({emitEvent: false});
}
} else {
this.mobileAppSettingsForm.get('androidConfig.appPackage').disable({emitEvent: false});
this.mobileAppSettingsForm.get('androidConfig.sha256CertFingerprints').disable({emitEvent: false});
+ this.mobileAppSettingsForm.get('androidConfig.storeLink').disable({emitEvent: false});
}
this.mobileAppSettingsForm.get('qrCodeConfig.badgeEnabled').updateValueAndValidity({onlySelf: true});
}
@@ -166,9 +174,11 @@ export class MobileAppSettingsComponent extends PageComponent implements HasConf
if (value) {
if (!this.mobileAppSettingsForm.get('useDefaultApp').value) {
this.mobileAppSettingsForm.get('iosConfig.appId').enable({emitEvent: false});
+ this.mobileAppSettingsForm.get('iosConfig.storeLink').enable({emitEvent: false});
}
} else {
this.mobileAppSettingsForm.get('iosConfig.appId').disable({emitEvent: false});
+ this.mobileAppSettingsForm.get('iosConfig.storeLink').disable({emitEvent: false});
}
this.mobileAppSettingsForm.get('qrCodeConfig.badgeEnabled').updateValueAndValidity({onlySelf: true});
}
diff --git a/ui-ngx/src/app/shared/components/entity/entity-autocomplete.component.ts b/ui-ngx/src/app/shared/components/entity/entity-autocomplete.component.ts
index 9792d9f1e9..8703e0a10b 100644
--- a/ui-ngx/src/app/shared/components/entity/entity-autocomplete.component.ts
+++ b/ui-ngx/src/app/shared/components/entity/entity-autocomplete.component.ts
@@ -249,6 +249,11 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
this.noEntitiesMatchingText = 'alarm.no-alarms-matching';
this.entityRequiredText = 'alarm.alarm-required';
break;
+ case EntityType.QUEUE_STATS:
+ this.entityText = 'queue-statistics.queue-statistics';
+ this.noEntitiesMatchingText = 'queue-statistics.no-queue-statistics-matching';
+ this.entityRequiredText = 'queue-statistics.queue-statistics-required';
+ break;
case AliasEntityType.CURRENT_CUSTOMER:
this.entityText = 'customer.default-customer';
this.noEntitiesMatchingText = 'customer.no-customers-matching';
diff --git a/ui-ngx/src/app/shared/components/entity/entity-type-select.component.ts b/ui-ngx/src/app/shared/components/entity/entity-type-select.component.ts
index 1bd2861b70..04754e4a20 100644
--- a/ui-ngx/src/app/shared/components/entity/entity-type-select.component.ts
+++ b/ui-ngx/src/app/shared/components/entity/entity-type-select.component.ts
@@ -90,8 +90,9 @@ export class EntityTypeSelectComponent implements ControlValueAccessor, OnInit,
}
ngOnInit() {
- this.entityTypes = this.filterAllowedEntityTypes ?
- this.entityService.prepareAllowedEntityTypesList(this.allowedEntityTypes, this.useAliasEntityTypes) : this.allowedEntityTypes;
+ this.entityTypes = this.filterAllowedEntityTypes
+ ? this.entityService.prepareAllowedEntityTypesList(this.allowedEntityTypes, this.useAliasEntityTypes)
+ : this.allowedEntityTypes;
this.entityTypeFormGroup.get('entityType').valueChanges.subscribe(
(value) => {
let modelValue;
diff --git a/ui-ngx/src/app/shared/models/entity-type.models.ts b/ui-ngx/src/app/shared/models/entity-type.models.ts
index 885ea90929..045e95983c 100644
--- a/ui-ngx/src/app/shared/models/entity-type.models.ts
+++ b/ui-ngx/src/app/shared/models/entity-type.models.ts
@@ -367,7 +367,11 @@ export const entityTypeTranslations = new Map(
[LimitedApi.CASSANDRA_QUERIES, 'api-limit.cassandra-queries'],
[LimitedApi.TRANSPORT_MESSAGES_PER_TENANT, 'api-limit.transport-messages'],
[LimitedApi.TRANSPORT_MESSAGES_PER_DEVICE, 'api-limit.transport-messages-per-device'],
+ [LimitedApi.TRANSPORT_MESSAGES_PER_GATEWAY, 'api-limit.transport-messages-per-gateway'],
+ [LimitedApi.TRANSPORT_MESSAGES_PER_GATEWAY_DEVICE, 'api-limit.transport-messages-per-gateway_device'],
[LimitedApi.EDGE_EVENTS, 'api-limit.edge-events'],
[LimitedApi.EDGE_EVENTS_PER_EDGE, 'api-limit.edge-events-per-edge'],
[LimitedApi.EDGE_UPLINK_MESSAGES, 'api-limit.edge-uplink-messages'],
diff --git a/ui-ngx/src/app/shared/models/mobile-app.models.ts b/ui-ngx/src/app/shared/models/mobile-app.models.ts
index 7b98da0744..b879a9eb45 100644
--- a/ui-ngx/src/app/shared/models/mobile-app.models.ts
+++ b/ui-ngx/src/app/shared/models/mobile-app.models.ts
@@ -21,17 +21,21 @@ export interface MobileAppSettings extends HasTenantId {
androidConfig: AndroidConfig;
iosConfig: IosConfig;
qrCodeConfig: QRCodeConfig;
+ defaultGooglePlayLink: string;
+ defaultAppStoreLink: string;
}
export interface AndroidConfig {
enabled: boolean;
appPackage: string;
- sha256CertFingerprints: string
+ sha256CertFingerprints: string;
+ storeLink: string;
}
export interface IosConfig {
enabled: boolean;
appId: string;
+ storeLink: string;
}
export interface QRCodeConfig {
diff --git a/ui-ngx/src/app/shared/models/queue.models.ts b/ui-ngx/src/app/shared/models/queue.models.ts
index eb23cc1269..5e1559cda9 100644
--- a/ui-ngx/src/app/shared/models/queue.models.ts
+++ b/ui-ngx/src/app/shared/models/queue.models.ts
@@ -126,3 +126,8 @@ export interface QueueInfo extends BaseData, HasTenantId {
duplicateMsgToAllPartitions?: boolean;
};
}
+
+export interface QueueStatisticsInfo extends Omit, 'label'>, HasTenantId {
+ queueName: string;
+ serviceId: string;
+}
diff --git a/ui-ngx/src/app/shared/models/widget-settings.models.ts b/ui-ngx/src/app/shared/models/widget-settings.models.ts
index 681913c24c..5124458ff0 100644
--- a/ui-ngx/src/app/shared/models/widget-settings.models.ts
+++ b/ui-ngx/src/app/shared/models/widget-settings.models.ts
@@ -297,6 +297,12 @@ export const defaultGradient = (minValue?: number, maxValue?: number): ColorGrad
maxValue: isDefinedAndNotNull(maxValue) ? maxValue : 100
});
+export const defaultRange = (): ColorRangeSettings => ({
+ advancedMode: false,
+ range: [],
+ rangeAdvanced: []
+});
+
const updateGradientMinMaxValues = (colorSettings: ColorSettings, minValue?: number, maxValue?: number): void => {
if (isDefinedAndNotNull(colorSettings.gradient)) {
if (isDefinedAndNotNull(minValue)) {
@@ -431,7 +437,7 @@ export abstract class AdvancedModeColorProcessor extends ColorProcessor {
protected constructor(protected settings: ColorSettings,
protected ctx: WidgetContext) {
super(settings);
- this.advancedMode = this.getCurrentConfig().advancedMode;
+ this.advancedMode = this.getCurrentConfig()?.advancedMode;
if (this.advancedMode) {
createValueSubscription(
this.ctx,
@@ -529,7 +535,7 @@ class RangeColorProcessor extends AdvancedModeColorProcessor {
this.settings.rangeList.range as Array;
}
- if (rangeList.length && isDefinedAndNotNull(value) && isNumeric(value)) {
+ if (rangeList?.length && isDefinedAndNotNull(value) && isNumeric(value)) {
const num = Number(value);
for (const range of rangeList) {
if (advancedMode ?
@@ -571,7 +577,8 @@ class GradientColorProcessor extends AdvancedModeColorProcessor {
update(value: any): void {
const progress = this.calculateProgress(+value, this.minValue, this.maxValue);
super.update(progress);
- this.color = this.getGradientColor(progress, this.settings.gradient.gradient);
+ this.color = this.getGradientColor(progress,
+ this.advancedMode ? this.settings.gradient.gradientAdvanced : this.settings.gradient.gradient);
}
updatedAdvancedData(data: Array) {
diff --git a/ui-ngx/src/app/shared/models/widget.models.ts b/ui-ngx/src/app/shared/models/widget.models.ts
index 88d537220e..01a7e98215 100644
--- a/ui-ngx/src/app/shared/models/widget.models.ts
+++ b/ui-ngx/src/app/shared/models/widget.models.ts
@@ -73,7 +73,7 @@ export const widgetTypesData = new Map(
icon: 'timeline',
configHelpLinkId: 'widgetsConfigTimeseries',
template: {
- fullFqn: 'system.charts.basic_timeseries'
+ fullFqn: 'system.time_series_chart'
}
}
],
diff --git a/ui-ngx/src/assets/dashboard/sys_admin_home_page.json b/ui-ngx/src/assets/dashboard/sys_admin_home_page.json
index bb38c53b6f..20e3b0b48a 100644
--- a/ui-ngx/src/assets/dashboard/sys_admin_home_page.json
+++ b/ui-ngx/src/assets/dashboard/sys_admin_home_page.json
@@ -2665,7 +2665,7 @@
"dropShadow": false,
"enableFullscreen": false,
"widgetStyle": {},
- "widgetCss": " .tb-widget-container > .tb-widget > .tb-widget-content .tb-widget-title > .title-row > .title {\n padding: 0;\n}\n\n .tb-widget-container > .tb-widget > .tb-widget-content .tb-widget-title > .title-row > .title {\n padding-bottom: 8px;\n font-weight: 600;\n font-size: 20px;\n line-height: 24px;\n letter-spacing: 0.1px;\n color: rgba(0, 0, 0, 0.76);\n}\n\n.tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel {\n padding: 0;\n}\n\n@media screen and (min-width: 960px) and (max-height: 900px) {\n .tb-widget-container > .tb-widget > .tb-widget-content .tb-widget-title {\n display: none;\n }\n}\n\n@media screen and (min-width: 960px) and (max-width: 1819px) {\n .tb-widget-container > .tb-widget > .tb-widget-content .tb-widget-title > .title-row > .title {\n padding-bottom: 0;\n font-weight: 500;\n font-size: 14px;\n line-height: 20px;\n letter-spacing: 0.25px;\n }\n}\n\n@media screen and (min-width: 960px) and (max-width: 1279px) {\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-qrcode-label {\n display: none;\n }\n}\n\n@media screen and (min-width: 960px) and (max-width: 1190px) {\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel {\n gap: 0;\n }\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-qrcode {\n min-width: 150px;\n }\n}\n\n@media screen and (max-width: 960px) {\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-qrcode {\n max-width: 110px;\n }\n \n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-badges {\n max-width: 140px;\n }\n}\n\n@media screen and (min-width: 1819px) {\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-qrcode {\n max-width: 125px;\n }\n \n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-badges {\n max-width: 160px;\n }\n}",
+ "widgetCss": " .tb-widget-container > .tb-widget > .tb-widget-content .tb-widget-title > .title-row > .title {\n padding: 0;\n}\n\n .tb-widget-container > .tb-widget > .tb-widget-content .tb-widget-title > .title-row > .title {\n padding-bottom: 8px;\n font-weight: 600;\n font-size: 20px;\n line-height: 24px;\n letter-spacing: 0.1px;\n color: rgba(0, 0, 0, 0.76);\n}\n\n.tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel {\n padding: 0;\n}\n\n@media screen and (min-width: 960px) and (max-width: 1819px) {\n .tb-widget-container > .tb-widget > .tb-widget-content .tb-widget-title > .title-row > .title {\n padding-bottom: 0;\n font-weight: 500;\n font-size: 14px;\n line-height: 20px;\n letter-spacing: 0.25px;\n }\n}\n\n@media screen and (min-width: 960px) and (max-width: 1190px) {\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel {\n gap: 0;\n }\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-qrcode {\n min-width: 150px;\n }\n}\n\n@media screen and (max-width: 960px) {\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-qrcode {\n max-width: 110px;\n }\n \n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-badges {\n max-width: 140px;\n }\n}\n\n@media screen and (min-width: 1819px) {\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-qrcode {\n max-width: 125px;\n }\n \n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-badges {\n max-width: 160px;\n }\n}\n\n@media screen and (min-width: 960px) and (max-height: 960px) {\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-qrcode-label {\n display: none;\n }\n}",
"showTitleIcon": false,
"titleTooltip": "",
"titleStyle": null,
diff --git a/ui-ngx/src/assets/dashboard/tenant_admin_home_page.json b/ui-ngx/src/assets/dashboard/tenant_admin_home_page.json
index bdc90f529f..e3277ac88a 100644
--- a/ui-ngx/src/assets/dashboard/tenant_admin_home_page.json
+++ b/ui-ngx/src/assets/dashboard/tenant_admin_home_page.json
@@ -1208,7 +1208,7 @@
"dropShadow": false,
"enableFullscreen": false,
"widgetStyle": {},
- "widgetCss": " .tb-widget-container > .tb-widget > .tb-widget-content .tb-widget-title > .title-row > .title {\n padding: 0;\n}\n\n .tb-widget-container > .tb-widget > .tb-widget-content .tb-widget-title > .title-row > .title {\n padding-bottom: 8px;\n font-weight: 600;\n font-size: 20px;\n line-height: 24px;\n letter-spacing: 0.1px;\n color: rgba(0, 0, 0, 0.76);\n}\n\n.tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel {\n padding: 0;\n}\n\n@media screen and (min-width: 960px) and (max-height: 900px) {\n .tb-widget-container > .tb-widget > .tb-widget-content .tb-widget-title {\n display: none;\n }\n}\n\n@media screen and (min-width: 960px) and (max-width: 1819px) {\n .tb-widget-container > .tb-widget > .tb-widget-content .tb-widget-title > .title-row > .title {\n padding-bottom: 0;\n font-weight: 500;\n font-size: 14px;\n line-height: 20px;\n letter-spacing: 0.25px;\n }\n}\n\n@media screen and (min-width: 960px) and (max-width: 1279px) {\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-qrcode-label {\n display: none;\n }\n}\n\n@media screen and (min-width: 960px) and (max-width: 1182px) {\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel {\n gap: 0;\n }\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-qrcode {\n min-width: 150px;\n }\n}\n\n@media screen and (max-width: 960px) {\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-qrcode {\n max-width: 120px;\n }\n \n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-badges {\n max-width: 160px;\n }\n}\n\n@media screen and (min-width: 1819px) {\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-qrcode {\n max-width: 125px;\n }\n \n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-badges {\n max-width: 160px;\n }\n}",
+ "widgetCss": " .tb-widget-container > .tb-widget > .tb-widget-content .tb-widget-title > .title-row > .title {\n padding: 0;\n}\n\n .tb-widget-container > .tb-widget > .tb-widget-content .tb-widget-title > .title-row > .title {\n padding-bottom: 8px;\n font-weight: 600;\n font-size: 20px;\n line-height: 24px;\n letter-spacing: 0.1px;\n color: rgba(0, 0, 0, 0.76);\n}\n\n.tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel {\n padding: 0;\n}\n\n@media screen and (min-width: 960px) and (max-width: 1819px) {\n .tb-widget-container > .tb-widget > .tb-widget-content .tb-widget-title > .title-row > .title {\n padding-bottom: 0;\n font-weight: 500;\n font-size: 14px;\n line-height: 20px;\n letter-spacing: 0.25px;\n }\n}\n\n@media screen and (min-width: 960px) and (max-width: 1182px) {\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel {\n gap: 0;\n }\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-qrcode {\n min-width: 150px;\n }\n}\n\n@media screen and (max-width: 960px) {\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-qrcode {\n max-width: 120px;\n }\n \n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-badges {\n max-width: 160px;\n }\n}\n\n@media screen and (min-width: 1819px) {\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-qrcode {\n max-width: 125px;\n }\n \n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-badges {\n max-width: 160px;\n }\n}\n\n@media screen and (min-width: 960px) and (max-height: 960px) {\n .tb-widget-container > .tb-widget > .tb-widget-content > .tb-widget .tb-mobile-app-qrcode-panel .tb-qrcode-label {\n display: none;\n }\n}",
"showTitleIcon": false,
"titleTooltip": "",
"titleStyle": null,
diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json
index c9cf8ef663..b922ff1b10 100644
--- a/ui-ngx/src/assets/locale/locale.constant-en_US.json
+++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json
@@ -437,6 +437,10 @@
"ios": "iOS",
"app-id": "App ID",
"app-id-required": "App ID is required",
+ "google-play-link": "Google Play link",
+ "google-play-link-required": "Google Play link is required",
+ "app-store-link": "App Store link",
+ "app-store-link-required": "App Store link is required",
"appearance": "Appearance",
"appearance-on-home-page": "Appearance on Home page",
"enabled": "Enabled",
@@ -894,6 +898,8 @@
"rest-api-requests-per-customer": "REST API requests per customer",
"transport-messages": "Transport messages",
"transport-messages-per-device": "Transport messages per device",
+ "transport-messages-per-gateway": "Transport messages per gateway",
+ "transport-messages-per-gateway-device": "Transport messages per gateway device",
"ws-updates-per-session": "WS updates per session",
"edge-events": "Edge events",
"edge-events-per-edge": "Edge events per edge",
@@ -4421,6 +4427,15 @@
"retry-failed-and-timeout-hint": "Retry all failed and timed-out messages from processing pack"
}
},
+ "queue-statistics": {
+ "queue-statistics": "Queue statistics",
+ "no-queue-statistics-matching": "No queue statistics matching '{{entity}}' were found.",
+ "queue-statistics-required": "Queue statistics is required.",
+ "list-of-queue-statistics": "{ count, plural, =1 {One queue statistic} other {List of # queue statistics} }",
+ "selected-queue-statistics": "{ count, plural, =1 {1 queue statistic} other {# queue statistics} } selected",
+ "no-queue-statistics-text": "No queue statistics found",
+ "queue-statistics-starts-with": "Queue statistics whose names start with '{{prefix}}'"
+ },
"server-error": {
"general": "General server error",
"authentication": "Authentication error",
@@ -4547,6 +4562,9 @@
"transport-gateway-msg-rate-limit": "Transport gateway messages",
"transport-gateway-telemetry-msg-rate-limit": "Transport gateway telemetry messages",
"transport-gateway-telemetry-data-points-rate-limit": "Transport gateway telemetry data points",
+ "transport-gateway-device-msg-rate-limit": "Transport gateway device messages",
+ "transport-gateway-device-telemetry-msg-rate-limit": "Transport gateway device telemetry messages",
+ "transport-gateway-device-telemetry-data-points-rate-limit": "Transport gateway device telemetry data points",
"tenant-entity-export-rate-limit": "Entity version creation",
"tenant-entity-import-rate-limit": "Entity version load",
"tenant-notification-request-rate-limit": "Notification requests",
@@ -4631,6 +4649,9 @@
"edit-transport-gateway-msg-title": "Edit transport gateway messages rate limits",
"edit-transport-gateway-telemetry-msg-title": "Edit transport gateway telemetry messages rate limits",
"edit-transport-gateway-telemetry-data-points-title": "Edit transport gateway telemetry data points rate limits",
+ "edit-transport-gateway-device-msg-title": "Edit transport gateway device messages rate limits",
+ "edit-transport-gateway-device-telemetry-msg-title": "Edit transport gateway device telemetry messages rate limits",
+ "edit-transport-gateway-device-telemetry-data-points-title": "Edit transport gateway device telemetry data points rate limits",
"edit-tenant-rest-limits-title": "Edit REST requests for tenant rate limits",
"edit-customer-rest-limits-title": "Edit REST requests for customer rate limits",
"edit-ws-limit-updates-per-session-title": "Edit WS updates per session rate limits",
@@ -4667,6 +4688,9 @@
"transport-gateway-msg": "Transport gateway messages",
"transport-gateway-telemetry-msg": "Transport gateway telemetry messages",
"transport-gateway-telemetry-data-points": "Transport gateway telemetry data points",
+ "transport-gateway-device-msg": "Transport gateway device messages",
+ "transport-gateway-device-telemetry-msg": "Transport gateway device telemetry messages",
+ "transport-gateway-device-telemetry-data-points": "Transport gateway device telemetry data points",
"sec": "sec"
}
},
@@ -5664,7 +5688,9 @@
},
"widgets": {
"mobile-app-qr-code": {
- "configuration-hint": "The configuration depends on the Mobile app QR code widget in platform main settings"
+ "configuration-hint": "The configuration depends on the Mobile app QR code widget in platform main settings",
+ "get-it-on-google-play": "Get it on Google Play",
+ "download-on-the-app-store": "Download on the App Store"
},
"action-button": {
"behavior": "Behavior",
@@ -6305,6 +6331,7 @@
"gauge-bar-background": "Gauge bar background",
"bar-color": "Bar color",
"min-and-max-value": "Min and max value",
+ "min-and-max-label": "Min and max label",
"font": "Font",
"tick-width-and-color": "Tick width and color"
},